Add new permission checking logic [SCI-5436]

This commit is contained in:
Oleksii Kriuchykhin 2021-02-09 10:45:12 +01:00
parent 1e3e701788
commit 3b90225c5a
7 changed files with 124 additions and 16 deletions

View 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

View file

@ -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')

View file

@ -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

View file

@ -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: {

View file

@ -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

View file

@ -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

View 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