mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-20 03:54:34 +08:00
113 lines
3.4 KiB
Ruby
113 lines
3.4 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 :viewable_by_user, lambda { |user, teams = user.current_team|
|
|
teams = Team.where(id: teams.id) if teams.is_a?(Team) # handle single team
|
|
readable_ids = if permission_class == StorageLocation
|
|
readable_by_user(user).where(team: teams).pluck(:id)
|
|
else
|
|
with_granted_permissions(user, "#{permission_class.name}Permissions::READ".constantize, teams).or(
|
|
where(team: teams.with_granted_permissions(user, TeamPermissions::MANAGE))
|
|
).pluck(:id)
|
|
end
|
|
shared_with_team_ids = joins(:team_shared_objects, :team).where(team_shared_objects: { team: teams }).pluck(:id)
|
|
globally_shared_ids =
|
|
if column_names.include?('permission_level')
|
|
joins(:team).where(
|
|
{
|
|
permission_level: [
|
|
Extends::SHARED_OBJECTS_PERMISSION_LEVELS[:shared_read],
|
|
Extends::SHARED_OBJECTS_PERMISSION_LEVELS[:shared_write]
|
|
]
|
|
}
|
|
).pluck(:id)
|
|
else
|
|
none.pluck(:id)
|
|
end
|
|
|
|
where(id: (readable_ids + shared_with_team_ids + globally_shared_ids).uniq)
|
|
}
|
|
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.where(team: team, permission_level: :shared_read).any?
|
|
end
|
|
end
|