From 79baa2bb1110823354895215986e7a4285df9859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com> Date: Wed, 12 Jan 2022 17:30:21 +0100 Subject: [PATCH] fix #131 --- .../server/universities_controller.rb | 1 + app/jobs/sync_server_admin_users_job.rb | 10 ++++ app/models/university/with_users.rb | 7 +-- .../user/with_sync_between_universities.rb | 48 +++++++++++-------- 4 files changed, 43 insertions(+), 23 deletions(-) create mode 100644 app/jobs/sync_server_admin_users_job.rb diff --git a/app/controllers/server/universities_controller.rb b/app/controllers/server/universities_controller.rb index 95f23cae6..5dd42f655 100644 --- a/app/controllers/server/universities_controller.rb +++ b/app/controllers/server/universities_controller.rb @@ -19,6 +19,7 @@ class Server::UniversitiesController < Server::ApplicationController end def create + @university.source_university_id = current_university.id if @university.save redirect_to [:server, @university], notice: t('admin.successfully_created_html', model: @university.to_s) else diff --git a/app/jobs/sync_server_admin_users_job.rb b/app/jobs/sync_server_admin_users_job.rb new file mode 100644 index 000000000..74934788c --- /dev/null +++ b/app/jobs/sync_server_admin_users_job.rb @@ -0,0 +1,10 @@ +class SyncServerAdminUsersJob < ApplicationJob + queue_as :default + + def perform(source_university_id, target_university_id) + source_university = University.find_by(id: source_university_id) + target_university = University.find_by(id: target_university_id) + return unless source_university.present? && target_university.present? + User.synchronize_server_admin_users(source_university, target_university) + end +end diff --git a/app/models/university/with_users.rb b/app/models/university/with_users.rb index ccc0ea64e..dacbaf54c 100644 --- a/app/models/university/with_users.rb +++ b/app/models/university/with_users.rb @@ -2,6 +2,8 @@ module University::WithUsers extend ActiveSupport::Concern included do + attr_accessor :source_university_id + has_many :users, dependent: :destroy after_commit :synchronize_server_admin_users, on: :create @@ -9,9 +11,8 @@ module University::WithUsers private def synchronize_server_admin_users - User.synchronize_server_admin_users(id) + return unless source_university_id.present? + SyncServerAdminUsersJob.perform_later(source_university_id, id) end - handle_asynchronously :synchronize_server_admin_users, queue: 'default' - end end diff --git a/app/models/user/with_sync_between_universities.rb b/app/models/user/with_sync_between_universities.rb index 341601120..f1a1eed41 100644 --- a/app/models/user/with_sync_between_universities.rb +++ b/app/models/user/with_sync_between_universities.rb @@ -2,41 +2,49 @@ module User::WithSyncBetweenUniversities extend ActiveSupport::Concern included do - after_save :sync_from_current_university, if: Proc.new { |user| user.server_admin? } + attr_accessor :skip_server_admin_sync - def self.synchronize_server_admin_users(university_id) - university = University.where.not(id: university_id).first - university.users.server_admin.each(&:sync_from_current_university) if university + after_save :sync_between_universities, if: Proc.new { |user| user.server_admin? && !user.skip_server_admin_sync } + + def self.synchronize_server_admin_users(source_university, target_university) + source_university.users.server_admin.each do |user| + user.sync_in_university(target_university) + end end end - def sync_from_current_university - University.where.not(id: university_id).each do |university| - unless User.where(email: email, university_id: university.id).any? - duplicate_user_for_university(university) - else - User.where(email: email, university_id: university.id).first&.update_columns( - encrypted_password: self.encrypted_password, - first_name: self.first_name, - last_name: self.last_name, - mobile_phone: self.mobile_phone, - role: :server_admin - ) - end + def sync_between_universities + University.where.not(id: university_id).each do |target_university| + sync_in_university(target_university) + end + end + + def sync_in_university(target_university) + unless User.where(email: email, university_id: target_university.id).any? + duplicate_user_for_university(target_university) + else + User.find_by(email: email, university_id: target_university.id)&.update_columns( + encrypted_password: self.encrypted_password, + first_name: self.first_name, + last_name: self.last_name, + mobile_phone: self.mobile_phone, + role: :server_admin + ) end end private - def duplicate_user_for_university(university) + def duplicate_user_for_university(target_university) # Create user for this university user = self.dup - user.assign_attributes(university_id: university.id, picture_infos: nil, + user.assign_attributes(university_id: target_university.id, picture_infos: nil, password: "MyNewPasswordIs2Strong!", password_confirmation: "MyNewPasswordIs2Strong!", reset_password_token: nil, unlock_token: nil, encrypted_otp_secret_key: nil, confirmation_token: Devise.friendly_token, confirmed_at: Time.now, - role: :server_admin) + role: :server_admin, skip_server_admin_sync: true) # as a new user must have a password and we can't access previous user password + byebug user.save user.update_column(:encrypted_password, self.encrypted_password) if user.valid? end -- GitLab