scinote-web/app/models/concerns/shareable.rb
Martin Artnik ff99f1df65
Merge pull request #8807 from artoscinote/ma_SCI_12271
Fix logic parenthesis in .can_manage_shared? [SCI-12271]
2025-08-18 09:46:09 +02:00

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