-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Get users from sso and run it as a rake task (#430)
Co-authored-by: Letiste <leo.sale72@gmail.com>
- Loading branch information
Showing
15 changed files
with
195 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
3hBkelrJkRosY8dMQ7mCuMYvOmv0joqEot1iGbs/jSd+krvIwDkjd/7/lnOUBFxAhrkTFfO5e05L2W3zC9Z4G+mDq5wf8GJQbxah2dTLf9HkgrLqnobuFCF7HPeaIsi3I9dKWJMgSNAiUvxYz0pj9dMUaoHEOml0tUiHgFa2q44+rPs7OHo7atYW1B7QwnvVFiBuiEw5lLij/4fTH2AMXPK65YxPNL0ljap5d+chkdw47ukryOInPtqN/rBgRlfWt7EHctvKdLca7SoJ9f0s3HGayMdI3Z1p0m6xPzaVy/wJrw1x0dLZz0hUm76Vop1K19DvZggVczIQQOoHquNtu97w8g9ybUW5mciH696LjcktZlGVLo0vVjm6ZK4H9vxFj/NAH3Om7NIF0wKy0BfPsIOt71FJ6FpbyPV58kkLuISoaVusewIYY++QwOa+woG8jqGPlCOl1L3LkSaOpKpQ5YMnxmcHSXS7eVRuIFOVvrPv4isAjefQl8ZgwbF59dQO5IU=--+K1TdG/RdN6c2gha--9rlzCCSz/Aq0gJawQhEBFA== | ||
VfC7hNP55EjMyi4vt8jK8lAaRmOkql+wsyAFxSVsQdVT8tbZk1l0dgyELsvoVfHwU9kqzI+wMIFyuH6MoXBhcghZfa6m5g683FM06BDkYPwwDflEVeox0DvWmgGji4qzk3oFe57T9qQT736mz3dWfeQTzvjHnaUpq27gYQTpQHOuELjYwKsMXbFRFiNNMmG5phiG2k0Asc7dqZ8CRPwmhJYPm5aJBc9Bzrz3ebBnhxmZ+JzZ8AsZnnvnAFnylm2jRwgN91kJE9l3fkWVTlF6rm0EoCJ9r3neibTeDu2PtNnkYISp3O7chrBJKo6FS9GFAcOxgkxB8QPiX2TV2s3jPiNyxffxLqUe+jziPP4dDiHdZvKrONIltblTJV2WTzur7/82fCEhQUf2oM7uwavq/yvQNOlay4nUD9TyBGZrs1fyFuulT4Ik2/w4T7usUC6am1xIzB2ITF8IuAgolkT/5EPsIs45gJEpJy9Fqlg1PAv01NN9hhViEl+A--tARvrsUmwyVJ9/XI--ytpULZnEcYeOSqfUYhHAnA== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
QF2+HIDkGNTPjx81hqlGjQAZyIzZVAp9c7J+dWPqlggPt9u/LWhxWWi6vY7KXGYe3opGafwsWlOgrO0BXtzbOg+RK+Bq9a8rUgsKchqHi44B487Y9/rTvS5bcCTJj5c78AJFdZCsEdOXqUv6khBGHB2i8fGQ5LZyh/SFJhmyt3QqGuL6Ig4MsuD/275o2M94CjrlXT2nNGe6BPl94GurtQv7s67bbgrSy3N2f0Kc+VR4VfrIhTwgkpXxEBv7vk/ok/1WvYpqRbFNuyPhiqkZ6Rj+0oK7JCxtFDL15tBtrIRbdpNuBeWO8BQwf/CfvcgBsJnOGg//LU/AJe+ndMCdUzdfVpuB1QKG4A62lmrLNOEwlw/K3JdPsWqPEh6rSVIr5nAzl4oaxMo0NZs7VK7ZhNpGxkvdNVQEZDxchZkaanQOIFU02240w3nMHYx5aed1MEj2ZpuR26Jg+W85m3K0BvsCDcXAouLTvMCB8kGZ8H6SOWExIdbIhmM3--x6H3t+K9w244qMLp--x+vXvS3cObYjuhqsAb4HYA== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Sync Accounts | ||
|
||
We use an SSO system to [authenticate our users](./authentication.md). That implies that our users' data are not stored only | ||
on lea5 database. To ensure the consistency of the data, we use a task to synchronize the data from the SSO | ||
to lea5. | ||
|
||
The task is defined in [`sync_accounts.rake`](../../lib/tasks/sync_accounts.rake), and runs every 3 hours. | ||
The timer is done with service/timer of systemd, the configuration can be found in [systemd folder](../../lib/support/systemd). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
[Unit] | ||
Description=Lea5 - Sync users between Keycloak and Lea5 | ||
|
||
[Service] | ||
# Command runs once then exists, it is not a background service | ||
Type=oneshot | ||
|
||
ExecStart=/opt/lea5/bin/rails lea5:sync_accounts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# See https://leethax.org/2017/11/17/systemd-timers.html | ||
# and https://wiki.archlinux.org/title/Systemd/Timers | ||
[Timer] | ||
# Run the service every 3 hours | ||
OnActiveSec=3h | ||
OnUnitActiveSec=3h | ||
|
||
[Install] | ||
WantedBy=timer.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'net/http' | ||
require 'json' | ||
|
||
namespace :lea5 do | ||
desc 'sync accounts from SSO' | ||
task sync_accounts: [:environment] do | ||
sso_users = retrieve_users_from_sso | ||
|
||
User.all.each do |user| | ||
user_from_sso = sso_users[user.keycloak_id] | ||
if user_from_sso | ||
update_user(user, user_from_sso) | ||
else | ||
destroy_user(user) | ||
end | ||
end | ||
end | ||
end | ||
|
||
# @return [Hash<String, Hash<String, Object>>] | ||
def retrieve_users_from_sso | ||
uri = URI('https://auth.rezoleo.fr/realms/rezoleo/protocol/openid-connect/token') | ||
params = { | ||
client_id: Rails.application.credentials.sso_id!, | ||
client_secret: Rails.application.credentials.sso_secret!, | ||
grant_type: 'client_credentials' | ||
} | ||
res = Net::HTTP.post_form(uri, params) | ||
# Needs "view-users" service account role in Keycloak | ||
access_token = JSON.parse(res.body)['access_token'] | ||
|
||
uri = URI('https://auth.rezoleo.fr/admin/realms/rezoleo/users?max=9999') # because pagination is a no no for keycloak | ||
res = Net::HTTP.get_response(uri, { 'Authorization' => "Bearer #{access_token}" }) | ||
JSON.parse(res.body).index_by { |user| user['id'] } | ||
end | ||
|
||
def update_user(user, user_from_sso) | ||
user.update_from_sso( | ||
firstname: user_from_sso['firstName'], | ||
lastname: user_from_sso['lastName'], | ||
email: user_from_sso['email'], | ||
room: user_from_sso['attributes']['room'].first | ||
) | ||
if user.save | ||
puts "Updated #{user.email}" | ||
else | ||
puts "Error updating user #{user.email}" | ||
end | ||
end | ||
|
||
def destroy_user(user) | ||
if user.destroy | ||
puts "Destroyed #{user.email}" | ||
else | ||
# :nocov: | ||
puts "Error destroying user #{user.email}" | ||
# :nocov: | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'json' | ||
require 'rake' | ||
require 'webmock' | ||
|
||
class SyncAccountsTest < ActiveSupport::TestCase | ||
# https://blog.10pines.com/2019/01/14/testing-rake-tasks/ | ||
# https://thoughtbot.com/blog/test-rake-tasks-like-a-boss | ||
def setup | ||
Rake.application.rake_require 'tasks/sync_accounts' | ||
Rake::Task.define_task(:environment) | ||
Rails.application.credentials.sso_id = '123456' | ||
Rails.application.credentials.sso_secret = 'super-secret' | ||
end | ||
|
||
test 'sync_accounts rake task' do | ||
KeycloakStub.stub_access_token | ||
KeycloakStub.stub_list_users | ||
|
||
assert_not_equal 'A113', User.find_by(email: 'tony@avengers.com').room | ||
|
||
assert_difference 'User.count', -1 do | ||
Rake::Task['lea5:sync_accounts'].invoke | ||
end | ||
assert_equal 'A113', User.find_by(email: 'tony@avengers.com').room | ||
end | ||
end | ||
|
||
class KeycloakStub | ||
MOCK_KEYCLOAK_USER_OK = { | ||
id: '12345678-1234-1234-1234-123456789abc', | ||
username: 'user1', | ||
firstName: 'Tony', | ||
lastName: 'Stark', | ||
email: 'tony@avengers.com', | ||
attributes: { locale: ['en'], room: ['A113'] } | ||
}.freeze | ||
MOCK_KEYCLOAK_USER_BAD_ROOM = { | ||
id: '12345678-1234-1234-1234-123456789ghi', | ||
username: 'user2', | ||
firstName: 'Peter', | ||
lastName: 'Parker', | ||
email: 'peterp@univ.edu', | ||
attributes: { room: ['BAD-ROOM'] } | ||
}.freeze | ||
|
||
def self.stub_access_token | ||
WebMock.stub_request(:post, 'https://auth.rezoleo.fr/realms/rezoleo/protocol/openid-connect/token') | ||
.with( | ||
body: WebMock.hash_including({ | ||
client_id: '123456', | ||
client_secret: 'super-secret', | ||
grant_type: 'client_credentials' | ||
}) | ||
) | ||
.to_return(status: 200, | ||
body: JSON.dump({ access_token: 'my_access_token' }), | ||
headers: { content_type: 'application/json' }) | ||
end | ||
|
||
def self.stub_list_users | ||
WebMock.stub_request(:get, 'https://auth.rezoleo.fr/admin/realms/rezoleo/users?max=9999') | ||
.with(headers: { Authorization: 'Bearer my_access_token' }) | ||
.to_return(status: 200, | ||
body: JSON.dump([MOCK_KEYCLOAK_USER_OK, MOCK_KEYCLOAK_USER_BAD_ROOM]), | ||
headers: {}) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters