scinote-web/app/models/concerns/permission_checkable_model.rb

61 lines
3.1 KiB
Ruby

# frozen_string_literal: true
module PermissionCheckableModel
extend ActiveSupport::Concern
included do
include PermissionExtends
scope :with_granted_permissions, lambda { |user, permissions, teams = user.permission_team|
with_user_assignments = joins(user_assignments: :user_role)
.where(user_assignments: { user: user, team: teams })
# direct user assignments take precedence over group assignments, thus skipping objects that already have user assignments.
with_group_assignments = left_outer_joins(user_group_assignments: [:user_role, { user_group: :users }], team_assignments: :user_role)
.where.not(id: with_user_assignments)
with_granted_user_permissions = with_user_assignments.where('user_roles.permissions @> ARRAY[?]::varchar[]', permissions)
with_granted_group_permissions = with_group_assignments
.where(user_group_assignments: { assignable: self, user_groups: { users: user }, team: teams })
.where('user_roles.permissions @> ARRAY[?]::varchar[]', permissions)
.or(
with_group_assignments
.where(team_assignments: { assignable: self, team: teams })
.where('user_roles_team_assignments.permissions @> ARRAY[?]::varchar[]', permissions)
)
.distinct
where(id: with_granted_user_permissions.reselect(:id))
.or(where(id: with_granted_group_permissions.reselect(:id)))
}
scope :readable_by_user, lambda { |user, teams = user.permission_team|
read_permission = "::#{self.class.to_s.split('::').first}Permissions".constantize::READ
with_granted_permissions(user, read_permission, teams)
}
scope :managable_by_user, lambda { |user, teams = user.permission_team|
manage_permission = "::#{self.class.to_s.split('::').first}Permissions".constantize::MANAGE
with_granted_permissions(user, manage_permission, teams)
}
def self.permission_class
self
end
end
def permission_granted?(user, permission, permission_team = user.permission_team)
if user_assignments.exists?(user: user, team: permission_team)
return user_assignments.joins(:user_role)
.where(user: user, team: permission_team)
.exists?(['user_roles.permissions @> ARRAY[?]::varchar[]', [permission]])
end
user_roles = UserRole.left_outer_joins(:team_assignments, user_group_assignments: { user_group: :users })
user_roles.where(user_group_assignments: { assignable: self, user_groups: { users: user }, team: permission_team })
.or(user_roles.where(team_assignments: { assignable: self, team: permission_team }))
.exists?(['user_roles.permissions @> ARRAY[?]::varchar[]', [permission]])
end
def readable_by_user?(user)
permission_granted?(user, "::#{self.class.to_s.split('::').first}Permissions".constantize::READ)
end
end