2021-06-06 15:54:47 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Assignable
|
|
|
|
extend ActiveSupport::Concern
|
|
|
|
|
|
|
|
included do
|
2021-09-30 17:32:11 +08:00
|
|
|
include Canaid::Helpers::PermissionsHelper
|
|
|
|
|
2021-11-22 18:17:39 +08:00
|
|
|
attr_accessor :skip_user_assignments
|
|
|
|
|
2021-06-06 15:54:47 +08:00
|
|
|
has_many :user_assignments, as: :assignable, dependent: :destroy
|
2022-10-10 21:27:42 +08:00
|
|
|
has_many :automatic_user_assignments, -> { automatically_assigned },
|
|
|
|
as: :assignable,
|
|
|
|
class_name: 'UserAssignment',
|
|
|
|
inverse_of: :assignable
|
2021-06-06 15:54:47 +08:00
|
|
|
|
2021-09-30 17:32:11 +08:00
|
|
|
scope :readable_by_user, lambda { |user|
|
|
|
|
joins(user_assignments: :user_role)
|
|
|
|
.where(user_assignments: { user: user })
|
|
|
|
.where('? = ANY(user_roles.permissions)', "::#{self.class.to_s.split('::').first}Permissions".constantize::READ)
|
|
|
|
}
|
|
|
|
|
2021-10-01 18:20:24 +08:00
|
|
|
scope :managable_by_user, lambda { |user|
|
|
|
|
joins(user_assignments: :user_role)
|
|
|
|
.where(user_assignments: { user: user })
|
|
|
|
.where('? = ANY(user_roles.permissions)', "::#{self.class.to_s.split('::').first}Permissions".constantize::MANAGE)
|
|
|
|
}
|
|
|
|
|
2021-10-27 19:48:52 +08:00
|
|
|
scope :with_user_permission, lambda { |user, permission|
|
|
|
|
joins(user_assignments: :user_role)
|
|
|
|
.where(user_assignments: { user: user })
|
|
|
|
.where('? = ANY(user_roles.permissions)', permission)
|
|
|
|
}
|
|
|
|
|
2021-11-22 18:17:39 +08:00
|
|
|
after_create :create_users_assignments
|
|
|
|
|
|
|
|
def role_for_user(user)
|
|
|
|
user_assignments.find_by(user: user)&.user_role
|
|
|
|
end
|
|
|
|
|
2021-12-01 23:23:24 +08:00
|
|
|
def manually_assigned_users
|
|
|
|
User.joins(:user_assignments).where(user_assignments: { assigned: :manually, assignable: self })
|
|
|
|
end
|
|
|
|
|
2023-01-03 21:43:03 +08:00
|
|
|
def assigned_users
|
|
|
|
User.joins(:user_assignments).where(user_assignments: { assignable: self })
|
|
|
|
end
|
|
|
|
|
2023-02-18 16:09:33 +08:00
|
|
|
def deep_clone_user_assginments(object)
|
|
|
|
user_assignments.each do |original_assignment|
|
|
|
|
new_assignment = original_assignment.dup
|
|
|
|
new_assignment.assignable = object
|
|
|
|
new_assignment.save!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2023-02-22 22:37:39 +08:00
|
|
|
def top_level_assignable?
|
|
|
|
self.class.name.in?(Extends::TOP_LEVEL_ASSIGNABLES)
|
|
|
|
end
|
|
|
|
|
2023-03-06 23:06:38 +08:00
|
|
|
private
|
|
|
|
|
|
|
|
def after_user_assignment_changed(user_assignment = nil)
|
2023-03-03 20:20:15 +08:00
|
|
|
# Optional, redefine in the assignable model.
|
2023-03-06 23:06:38 +08:00
|
|
|
# Will be called when an assignment is changed (save/destroy) for the assignable model.
|
2023-03-03 20:20:15 +08:00
|
|
|
end
|
|
|
|
|
2021-11-22 18:17:39 +08:00
|
|
|
def create_users_assignments
|
|
|
|
return if skip_user_assignments
|
2022-05-13 21:45:24 +08:00
|
|
|
|
2023-02-22 22:37:39 +08:00
|
|
|
role = if top_level_assignable?
|
2022-10-12 20:27:21 +08:00
|
|
|
UserRole.find_predefined_owner_role
|
2021-11-09 23:10:43 +08:00
|
|
|
else
|
|
|
|
permission_parent.user_assignments.find_by(user: created_by).user_role
|
|
|
|
end
|
|
|
|
|
2021-09-30 17:32:11 +08:00
|
|
|
UserAssignment.create!(
|
2021-06-19 23:17:57 +08:00
|
|
|
user: created_by,
|
|
|
|
assignable: self,
|
2023-02-22 22:37:39 +08:00
|
|
|
assigned: top_level_assignable? ? :manually : :automatically,
|
2021-11-09 23:10:43 +08:00
|
|
|
user_role: role
|
2021-06-19 23:17:57 +08:00
|
|
|
)
|
2022-10-14 16:23:57 +08:00
|
|
|
|
|
|
|
UserAssignments::GenerateUserAssignmentsJob.perform_later(self, created_by)
|
2021-06-06 15:54:47 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|