mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-20 23:16:15 +08:00
Add new permission checking logic [SCI-5436]
This commit is contained in:
parent
1e3e701788
commit
3b90225c5a
29
app/models/concerns/permission_checkable_model.rb
Normal file
29
app/models/concerns/permission_checkable_model.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module PermissionCheckableModel
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def permission_granted?(user, permission)
|
||||
user_role_permissions = load_user_role_permissions(user)
|
||||
return false if user_role_permissions.blank?
|
||||
|
||||
user_role_permissions.include?(permission)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_user_role_permissions(user)
|
||||
user_role_permissions =
|
||||
if user_assignments.loaded?
|
||||
user_assignments.detect { |user_assignment| user_assignment.user == user }&.user_role&.permissions
|
||||
else
|
||||
user_assignments.find_by(user: user)&.user_role&.permissions
|
||||
end
|
||||
|
||||
if user_role_permissions.blank? && permission_parent.present?
|
||||
user_role_permissions = permission_parent.load_user_role_permissions(user)
|
||||
end
|
||||
|
||||
user_role_permissions
|
||||
end
|
||||
end
|
|
@ -2,6 +2,7 @@ class Experiment < ApplicationRecord
|
|||
include ArchivableModel
|
||||
include SearchableModel
|
||||
include SearchableByNameModel
|
||||
include PermissionCheckableModel
|
||||
|
||||
belongs_to :project, inverse_of: :experiments, touch: true
|
||||
belongs_to :created_by,
|
||||
|
@ -24,9 +25,10 @@ class Experiment < ApplicationRecord
|
|||
has_many :activities, inverse_of: :experiment
|
||||
has_many :user_assignments, as: :assignable, dependent: :destroy
|
||||
has_many :users, through: :user_assignments
|
||||
|
||||
has_one_attached :workflowimg
|
||||
|
||||
alias_attribute :project, :permission_parent
|
||||
|
||||
auto_strip_attributes :name, :description, nullify: false
|
||||
validates :name, length: { minimum: Constants::NAME_MIN_LENGTH, maximum: Constants::NAME_MAX_LENGTH }
|
||||
validates :description, length: { maximum: Constants::TEXT_MAX_LENGTH }
|
||||
|
@ -36,6 +38,8 @@ class Experiment < ApplicationRecord
|
|||
validates :uuid, uniqueness: { scope: :project },
|
||||
unless: proc { |e| e.uuid.blank? }
|
||||
|
||||
default_scope { includes(user_assignments: :user_role) }
|
||||
|
||||
scope :is_archived, lambda { |is_archived|
|
||||
if is_archived
|
||||
joins(:project).where('experiments.archived = TRUE OR projects.archived = TRUE')
|
||||
|
|
|
@ -5,6 +5,7 @@ class MyModule < ApplicationRecord
|
|||
include SearchableModel
|
||||
include SearchableByNameModel
|
||||
include TinyMceImages
|
||||
include PermissionCheckableModel
|
||||
|
||||
enum state: Extends::TASKS_STATES
|
||||
|
||||
|
@ -58,6 +59,10 @@ class MyModule < ApplicationRecord
|
|||
# Associations for old activity type
|
||||
has_many :activities, inverse_of: :my_module
|
||||
|
||||
alias_attribute :experiment, :permission_parent
|
||||
|
||||
default_scope { includes(user_assignments: :user_role) }
|
||||
|
||||
scope :overdue, -> { where('my_modules.due_date < ?', Time.current.utc) }
|
||||
scope :without_group, -> { active.where(my_module_group: nil) }
|
||||
scope :one_day_prior, (lambda do
|
||||
|
|
|
@ -3,6 +3,7 @@ class Project < ApplicationRecord
|
|||
include SearchableModel
|
||||
include SearchableByNameModel
|
||||
include ViewableModel
|
||||
include PermissionCheckableModel
|
||||
|
||||
enum visibility: { hidden: 0, visible: 1 }
|
||||
|
||||
|
@ -46,6 +47,8 @@ class Project < ApplicationRecord
|
|||
has_many :reports, inverse_of: :project, dependent: :destroy
|
||||
has_many :report_elements, inverse_of: :project, dependent: :destroy
|
||||
|
||||
default_scope { includes(user_assignments: :user_role) }
|
||||
|
||||
scope :visible_to, (lambda do |user, team|
|
||||
unless user.is_admin_of_team?(team)
|
||||
left_outer_joins(:user_projects)
|
||||
|
@ -152,6 +155,10 @@ class Project < ApplicationRecord
|
|||
.distinct
|
||||
end
|
||||
|
||||
def permission_parent
|
||||
nil
|
||||
end
|
||||
|
||||
def default_view_state
|
||||
{
|
||||
experiments: {
|
||||
|
|
|
@ -16,7 +16,7 @@ Canaid::Permissions.register_for(Experiment) do
|
|||
# module: read (read users, read comments, read archive)
|
||||
# result: read (read comments)
|
||||
can :read_experiment do |user, experiment|
|
||||
can_read_project?(user, experiment.project)
|
||||
experiment.permission_granted?(user, ExperimentPermissions::READ)
|
||||
end
|
||||
|
||||
# experiment: create/update/delete
|
||||
|
@ -24,7 +24,7 @@ Canaid::Permissions.register_for(Experiment) do
|
|||
# module: create, copy, reposition, create/update/delete connection,
|
||||
# assign/reassign/unassign tags
|
||||
can :manage_experiment do |user, experiment|
|
||||
user.is_user_or_higher_of_project?(experiment.project) &&
|
||||
experiment.permission_granted?(user, ExperimentPermissions::MANAGE) &&
|
||||
MyModule.joins(:experiment)
|
||||
.where(experiment: experiment)
|
||||
.preload(my_module_status: :my_module_status_implications)
|
||||
|
@ -39,7 +39,7 @@ Canaid::Permissions.register_for(Experiment) do
|
|||
|
||||
# experiment: archive
|
||||
can :archive_experiment do |user, experiment|
|
||||
can_manage_experiment?(user, experiment)
|
||||
experiment.permission_granted?(user, ExperimentPermissions::ARCHIVE)
|
||||
end
|
||||
|
||||
# NOTE: Must not be dependent on canaid parmision for which we check if it's
|
||||
|
@ -47,15 +47,14 @@ Canaid::Permissions.register_for(Experiment) do
|
|||
# experiment: restore
|
||||
can :restore_experiment do |user, experiment|
|
||||
project = experiment.project
|
||||
user.is_user_or_higher_of_project?(project) &&
|
||||
experiment.permission_granted?(user, ExperimentPermissions::RESTORE) &&
|
||||
experiment.archived? &&
|
||||
project.active?
|
||||
end
|
||||
|
||||
# experiment: copy
|
||||
can :clone_experiment do |user, experiment|
|
||||
user.is_user_or_higher_of_project?(experiment.project) &&
|
||||
user.is_normal_user_or_admin_of_team?(experiment.project.team)
|
||||
experiment.permission_granted?(user, ExperimentPermissions::CLONE)
|
||||
end
|
||||
|
||||
# experiment: move
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Canaid::Permissions.register_for(Project) do
|
||||
include PermissionExtends
|
||||
|
||||
# Project must be active for all the specified permissions
|
||||
%i(manage_project
|
||||
archive_project
|
||||
|
@ -15,9 +19,7 @@ Canaid::Permissions.register_for(Project) do
|
|||
export_project)
|
||||
.each do |perm|
|
||||
can perm do |user, project|
|
||||
user.is_member_of_project?(project) ||
|
||||
user.is_admin_of_team?(project.team) ||
|
||||
(project.visible? && user.is_member_of_team?(project.team))
|
||||
project.permission_granted?(user, ProjectPermissions::READ)
|
||||
end
|
||||
end
|
||||
# project: read, read activities, read comments, read users, read archive,
|
||||
|
@ -36,7 +38,7 @@ Canaid::Permissions.register_for(Project) do
|
|||
|
||||
# project: update/delete, assign/reassign/unassign users
|
||||
can :manage_project do |user, project|
|
||||
user.is_owner_of_project?(project) &&
|
||||
project.permission_granted?(user, ProjectPermissions::MANAGE) &&
|
||||
MyModule.joins(experiment: :project)
|
||||
.where(experiments: { project: project })
|
||||
.preload(my_module_status: :my_module_status_implications)
|
||||
|
@ -51,24 +53,24 @@ Canaid::Permissions.register_for(Project) do
|
|||
|
||||
# project: archive
|
||||
can :archive_project do |user, project|
|
||||
can_manage_project?(user, project)
|
||||
project.permission_granted?(user, ProjectPermissions::ARCHIVE)
|
||||
end
|
||||
|
||||
# NOTE: Must not be dependent on canaid parmision for which we check if it's
|
||||
# active
|
||||
# project: restore
|
||||
can :restore_project do |user, project|
|
||||
user.is_owner_of_project?(project) && project.archived?
|
||||
project.archived? && project.permission_granted?(user, ProjectPermissions::RESTORE)
|
||||
end
|
||||
|
||||
# experiment: create
|
||||
can :create_experiments do |user, project|
|
||||
user.is_user_or_higher_of_project?(project)
|
||||
project.permission_granted?(user, ProjectPermissions::CREATE_EXPERIMENTS)
|
||||
end
|
||||
|
||||
# project: create comment
|
||||
can :create_comments_in_project do |user, project|
|
||||
user.is_technician_or_higher_of_project?(project)
|
||||
project.permission_granted?(user, ProjectPermissions::CREATE_COMMENTS)
|
||||
end
|
||||
|
||||
# project: create/update/delete tag
|
||||
|
@ -90,6 +92,6 @@ Canaid::Permissions.register_for(ProjectComment) do
|
|||
# project: update/delete comment
|
||||
can :manage_comment_in_project do |user, project_comment|
|
||||
project_comment.project.present? && (project_comment.user == user ||
|
||||
user.is_owner_of_project?(project_comment.project))
|
||||
project.permission_granted?(user, ProjectPermissions::EDIT_COMMENTS))
|
||||
end
|
||||
end
|
||||
|
|
62
config/initializers/extends/permission_extends.rb
Normal file
62
config/initializers/extends/permission_extends.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module PermissionExtends
|
||||
module ProjectPermissions
|
||||
%w(
|
||||
READ
|
||||
EXPORT
|
||||
MANAGE
|
||||
ARCHIVE
|
||||
RESTORE
|
||||
CREATE_EXPERIMENTS
|
||||
CREATE_COMMENTS
|
||||
EDIT_COMMENTS
|
||||
DELETE_COMMENTS
|
||||
MANAGE_TAGS
|
||||
).each { |permission| const_set(permission, permission.underscore) }
|
||||
end
|
||||
|
||||
module ExperimentPermissions
|
||||
%w(
|
||||
READ
|
||||
MANAGE
|
||||
ARCHIVE
|
||||
RESTORE
|
||||
CLONE
|
||||
MOVE
|
||||
).each { |permission| const_set(permission, permission.underscore) }
|
||||
end
|
||||
|
||||
module MyModulePermissions
|
||||
%w(
|
||||
MANAGE
|
||||
ARCHIVE
|
||||
RESTORE
|
||||
MOVE
|
||||
MANAGE_USERS
|
||||
ASSIGN_REPOSITORY_ROWS
|
||||
CHANGE_FLOW_STATUS
|
||||
CREATE_COMMENTS
|
||||
CREATE_REPOSITORY_SNAPSHOT
|
||||
MANAGE_REPOSITORY_SNAPSHOT
|
||||
).each { |permission| const_set(permission, permission.underscore) }
|
||||
end
|
||||
|
||||
module RepositoryPermissions
|
||||
%w(
|
||||
READ
|
||||
MANAGE
|
||||
ARCHIVE
|
||||
RESTORE
|
||||
SHARE
|
||||
CREATE_SNAPSHOT
|
||||
DELETE_SNAPSHOT
|
||||
CREATE_ROW
|
||||
UPDATE_ROW
|
||||
DELETE_ROW
|
||||
CREATE_COLUMN
|
||||
UPDATE_COLUMN
|
||||
DELETE_COLUMN
|
||||
).each { |permission| const_set(permission, permission.underscore) }
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue