mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-07 13:44:23 +08:00
124 lines
3.8 KiB
Ruby
124 lines
3.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Shareable
|
|
extend ActiveSupport::Concern
|
|
|
|
included do
|
|
has_many :team_shared_objects, as: :shared_object, dependent: :destroy
|
|
has_many :teams_shared_with, through: :team_shared_objects, source: :team, dependent: :destroy
|
|
|
|
if column_names.include? 'permission_level'
|
|
enum permission_level: Extends::SHARED_OBJECTS_PERMISSION_LEVELS
|
|
define_method :globally_shareable? do
|
|
true
|
|
end
|
|
else
|
|
# If model does not include the permission_level column for global sharing,
|
|
# all related methods should just return false
|
|
Extends::SHARED_OBJECTS_PERMISSION_LEVELS.each do |level|
|
|
define_method "#{level[0]}?" do
|
|
level[0] == :not_shared
|
|
end
|
|
|
|
define_method :globally_shareable? do
|
|
false
|
|
end
|
|
end
|
|
end
|
|
|
|
scope :shared_with_team, lambda { |team|
|
|
directly_shared = joins(:team_shared_objects, :team).where(team_shared_objects: { team: team })
|
|
globally_shared =
|
|
if column_names.include?('permission_level')
|
|
where(
|
|
permission_level: [
|
|
Extends::SHARED_OBJECTS_PERMISSION_LEVELS[:shared_read],
|
|
Extends::SHARED_OBJECTS_PERMISSION_LEVELS[:shared_write]
|
|
]
|
|
)
|
|
else
|
|
none
|
|
end
|
|
where(id: directly_shared.select(:id)).or(where(id: globally_shared.select(:id)))
|
|
}
|
|
rescue ActiveRecord::NoDatabaseError,
|
|
ActiveRecord::ConnectionNotEstablished,
|
|
ActiveRecord::StatementInvalid,
|
|
PG::ConnectionBad
|
|
|
|
Rails.logger.info('Not connected to database, skipping sharable model initialization.')
|
|
end
|
|
|
|
def can_manage_shared?(user)
|
|
(globally_shared? || shared_with?(user.current_team)) &&
|
|
user.current_team.permission_granted?(user, TeamPermissions::MANAGE)
|
|
end
|
|
|
|
def shareable_write?
|
|
true
|
|
end
|
|
|
|
def private_shared_with?(team)
|
|
team_shared_objects.exists?(team: team)
|
|
end
|
|
|
|
def private_shared_with_read?(team)
|
|
team_shared_objects.exists?(team: team, permission_level: :shared_read)
|
|
end
|
|
|
|
def private_shared_with_write?(team)
|
|
team_shared_objects.exists?(team: team, permission_level: :shared_write)
|
|
end
|
|
|
|
def i_shared?(team)
|
|
shared_with_anybody? && self.team == team
|
|
end
|
|
|
|
def globally_shared?
|
|
shared_read? || shared_write?
|
|
end
|
|
|
|
def shared_with_anybody?
|
|
(!not_shared? || team_shared_objects.any?)
|
|
end
|
|
|
|
def shared_with?(team)
|
|
return false if self.team == team
|
|
|
|
!not_shared? || private_shared_with?(team)
|
|
end
|
|
|
|
def shared_with_write?(team)
|
|
return false if self.team == team
|
|
|
|
shared_write? || private_shared_with_write?(team)
|
|
end
|
|
|
|
def shared_with_read?(team)
|
|
return false if self.team == team
|
|
|
|
shared_read? || team_shared_objects.exists?(team: team, permission_level: :shared_read)
|
|
end
|
|
|
|
def demote_all_sharing_assignments_to_viewer!(for_team: nil)
|
|
# take into account special roles with no read permission, and do not upgrade them to viewer
|
|
read_permission = "#{self.class.permission_class}Permissions".constantize::READ
|
|
|
|
teams = for_team ? Team.where(id: for_team.id).where.not(id: team.id) : Team.where.not(id: team.id)
|
|
|
|
[user_assignments, user_group_assignments, team_assignments].each do |assignments|
|
|
assignments.joins(:user_role)
|
|
.where(team_id: teams.select(:id))
|
|
.where(['user_roles.permissions @> ARRAY[?]::varchar[]', [read_permission]])
|
|
.update!(user_role: UserRole.find_predefined_viewer_role)
|
|
end
|
|
end
|
|
|
|
def destroy_all_sharing_assignments!(for_team: nil)
|
|
teams = for_team ? Team.where(id: for_team.id).where.not(id: team.id) : Team.where.not(id: team.id)
|
|
|
|
user_assignments.where(team_id: teams.select(:id)).destroy_all
|
|
user_group_assignments.where(team_id: teams.select(:id)).destroy_all
|
|
team_assignments.where(team_id: teams.select(:id)).destroy_all
|
|
end
|
|
end
|