Class: Users::RefreshAuthorizedProjectsService
- Inherits:
-
Object
- Object
- Users::RefreshAuthorizedProjectsService
- Defined in:
- app/services/users/refresh_authorized_projects_service.rb
Overview
Service for refreshing the authorized projects of a user.
This particular service class can not be used to update data for the same user concurrently. Doing so could lead to an incorrect state. To ensure this doesn’t happen a caller must synchronize access (e.g. using ‘Gitlab::ExclusiveLease`).
Usage:
user = User.find_by(username: 'alice')
service = Users::RefreshAuthorizedProjectsService.new(some_user)
service.execute
Constant Summary collapse
- LEASE_TIMEOUT =
1.minute.to_i
Instance Attribute Summary collapse
-
#source ⇒ Object
readonly
Returns the value of attribute source.
-
#user ⇒ Object
readonly
Returns the value of attribute user.
Instance Method Summary collapse
- #execute ⇒ Object
-
#execute_without_lease ⇒ Object
This method returns the updated User object.
-
#initialize(user, source: nil, incorrect_auth_found_callback: nil, missing_auth_found_callback: nil) ⇒ RefreshAuthorizedProjectsService
constructor
user - The User for which to refresh the authorized projects.
-
#update_authorizations(remove = [], add = []) ⇒ Object
Updates the list of authorizations for the current user.
Constructor Details
#initialize(user, source: nil, incorrect_auth_found_callback: nil, missing_auth_found_callback: nil) ⇒ RefreshAuthorizedProjectsService
user - The User for which to refresh the authorized projects.
22 23 24 25 26 27 |
# File 'app/services/users/refresh_authorized_projects_service.rb', line 22 def initialize(user, source: nil, incorrect_auth_found_callback: nil, missing_auth_found_callback: nil) @user = user @source = source @incorrect_auth_found_callback = incorrect_auth_found_callback @missing_auth_found_callback = missing_auth_found_callback end |
Instance Attribute Details
#source ⇒ Object (readonly)
Returns the value of attribute source.
17 18 19 |
# File 'app/services/users/refresh_authorized_projects_service.rb', line 17 def source @source end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
17 18 19 |
# File 'app/services/users/refresh_authorized_projects_service.rb', line 17 def user @user end |
Instance Method Details
#execute ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'app/services/users/refresh_authorized_projects_service.rb', line 29 def execute lease_key = "refresh_authorized_projects:#{user.id}" lease = Gitlab::ExclusiveLease.new(lease_key, timeout: LEASE_TIMEOUT) until uuid = lease.try_obtain # Keep trying until we obtain the lease. If we don't do so we may end up # not updating the list of authorized projects properly. To prevent # hammering Redis too much we'll wait for a bit between retries. sleep(0.1) end begin # We need an up to date User object that has access to all relations that # may have been created earlier. The only way to ensure this is to reload # the User object. user.reset execute_without_lease ensure Gitlab::ExclusiveLease.cancel(lease_key, uuid) end end |
#execute_without_lease ⇒ Object
This method returns the updated User object.
52 53 54 55 56 57 58 59 60 61 |
# File 'app/services/users/refresh_authorized_projects_service.rb', line 52 def execute_without_lease remove, add = AuthorizedProjectUpdate::FindRecordsDueForRefreshService.new( user, source: source, incorrect_auth_found_callback: incorrect_auth_found_callback, missing_auth_found_callback: missing_auth_found_callback ).execute (remove, add) end |
#update_authorizations(remove = [], add = []) ⇒ Object
Updates the list of authorizations for the current user.
remove - The project IDs of the authorization rows to remove. add - Rows to insert in the form ‘[{ user_id: user_id, project_id: project_id, access_level: access_level}, …]`
67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'app/services/users/refresh_authorized_projects_service.rb', line 67 def (remove = [], add = []) log_refresh_details(remove, add) ProjectAuthorizations::Changes.new do |changes| changes.add(add) changes.remove_projects_for_user(user, remove) end.apply! # Since we batch insert authorization rows, Rails' associations may get # out of sync. As such we force a reload of the User object. user.reset end |