From c120a357cd0ea7db938cb6672673594c7deed120 Mon Sep 17 00:00:00 2001 From: Oleksii Kriuchykhin Date: Mon, 23 May 2022 13:32:15 +0200 Subject: [PATCH] Add permissions for Report model [SCI-6834] --- app/controllers/reports_controller.rb | 38 +++++++++---------- app/models/report.rb | 3 ++ app/permissions/team.rb | 23 +++++++---- app/views/reports/_index_toolbar.html.erb | 2 +- .../extends/permission_extends.rb | 14 +++++++ ...220516111152_add_team_level_permissions.rb | 16 ++++++-- 6 files changed, 66 insertions(+), 30 deletions(-) diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index a82efe5c8..160101e80 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -4,25 +4,18 @@ class ReportsController < ApplicationController include ReportsHelper include StringUtility - BEFORE_ACTION_METHODS = %i( - create - edit - update - generate_pdf - generate_docx - new_template_values - project_contents - ).freeze - before_action :load_vars, only: %i(edit update document_preview generate_pdf generate_docx status save_pdf_to_inventory_modal save_pdf_to_inventory_item) - before_action :load_vars_nested, only: BEFORE_ACTION_METHODS + before_action :load_vars_nested, only: %i(create edit update generate_pdf + generate_docx new_template_values project_contents) before_action :load_wizard_vars, only: %i(new edit) before_action :load_available_repositories, only: %i(index save_pdf_to_inventory_modal available_repositories) - - before_action :check_manage_permissions, only: BEFORE_ACTION_METHODS + before_action :check_read_permissions, except: %i(index datatable new create edit update generate_pdf + generate_docx new_template_values project_contents) + before_action :check_create_permissions, only: %i(new create) + before_action :check_manage_permissions, only: %i(edit update generate_pdf + generate_docx new_template_values project_contents) before_action :switch_team_with_param, only: :index - after_action :generate_pdf_report, only: %i(create update generate_pdf) # Index showing all reports of a single project @@ -147,8 +140,8 @@ class ReportsController < ApplicationController end report_ids.each do |report_id| - report = Report.find_by_id(report_id) - next unless report.present? && can_manage_reports?(report.project.team) + report = current_team.reports.find_by(id: report_id) + next unless report.present? && can_manage_report?(report) # record an activity log_activity(:delete_report, report) @@ -311,7 +304,7 @@ class ReportsController < ApplicationController render json: { html: render_to_string( partial: 'reports/wizard/project_contents.html.erb', - locals: { project: @project, report: nil} + locals: { project: @project, report: nil } ) } end @@ -337,7 +330,6 @@ class ReportsController < ApplicationController def load_vars @report = current_team.reports.find_by(id: params[:id]) render_404 unless @report - render_403 unless can_read_project?(@report.project) end def load_vars_nested @@ -364,8 +356,16 @@ class ReportsController < ApplicationController .select(:id, :name) end + def check_read_permissions + render_403 unless can_read_report?(@report) + end + + def check_create_permissions + render_403 unless can_create_reports?(@project.team) + end + def check_manage_permissions - render_403 unless can_manage_reports?(@project.team) + render_403 unless can_manage_report?(@report) end def load_available_repositories diff --git a/app/models/report.rb b/app/models/report.rb index 6c412a481..cd59c4118 100644 --- a/app/models/report.rb +++ b/app/models/report.rb @@ -2,6 +2,8 @@ class Report < ApplicationRecord include SettingsModel + include Assignable + include PermissionCheckableModel include SearchableModel include SearchableByNameModel @@ -28,6 +30,7 @@ class Report < ApplicationRecord foreign_key: 'last_modified_by_id', class_name: 'User', optional: true + has_many :users, through: :user_assignments has_many :report_template_values, dependent: :destroy # Report either has many report elements (if grouped by timestamp), diff --git a/app/permissions/team.rb b/app/permissions/team.rb index ac306bec3..9461f73ad 100644 --- a/app/permissions/team.rb +++ b/app/permissions/team.rb @@ -47,13 +47,8 @@ Canaid::Permissions.register_for(Team) do within_limits && team.permission_granted?(user, TeamPermissions::INVENTORIES_CREATE) end - # this permission is scattered around the application - # if you want to make changes here keep in mind to check/change the - # SQL view that lists reports in index page: - # - check the model app/models/views/datatables/datatables_report.rb - # - check visible_by method in Project model - can :manage_reports do |user, team| - can_manage_team?(user, team) + can :create_reports do |user, team| + team.permission_granted?(user, TeamPermissions::REPORTS_CREATE) end end @@ -90,3 +85,17 @@ Canaid::Permissions.register_for(Protocol) do can_read_protocol_in_repository?(user, protocol) && can_create_protocols_in_repository?(user, protocol.team) end end + +Canaid::Permissions.register_for(Report) do + can :read_report do |user, report| + report.permission_granted?(user, ReportPermissions::READ) + end + + can :manage_report do |user, report| + report.permission_granted?(user, ReportPermissions::MANAGE) + end + + can :manage_report_users do |user, report| + report.permission_granted?(user, ReportPermissions::USERS_MANAGE) + end +end diff --git a/app/views/reports/_index_toolbar.html.erb b/app/views/reports/_index_toolbar.html.erb index a47bbc8c8..3dd2fd6f0 100644 --- a/app/views/reports/_index_toolbar.html.erb +++ b/app/views/reports/_index_toolbar.html.erb @@ -1,4 +1,4 @@ -<% if can_manage_reports?(current_team) %> +<% if can_create_reports?(current_team) %>
<%= link_to new_report_path, class: 'btn btn-primary', id: 'new-report-btn' do %> diff --git a/config/initializers/extends/permission_extends.rb b/config/initializers/extends/permission_extends.rb index 71d1eb416..d1cfaa36f 100644 --- a/config/initializers/extends/permission_extends.rb +++ b/config/initializers/extends/permission_extends.rb @@ -9,6 +9,7 @@ module PermissionExtends PROJECTS_CREATE INVENTORIES_CREATE PROTOCOLS_CREATE + REPORTS_CREATE ).each { |permission| const_set(permission, "team_#{permission.underscore}") } end @@ -20,6 +21,14 @@ module PermissionExtends ).each { |permission| const_set(permission, "protocol_#{permission.underscore}") } end + module ReportPermissions + %w( + READ + MANAGE + USERS_MANAGE + ).each { |permission| const_set(permission, "report_#{permission.underscore}") } + end + module ProjectPermissions %w( READ @@ -112,6 +121,7 @@ module PermissionExtends OWNER_PERMISSIONS = ( TeamPermissions.constants.map { |const| TeamPermissions.const_get(const) } + ProtocolPermissions.constants.map { |const| ProtocolPermissions.const_get(const) } + + ReportPermissions.constants.map { |const| ReportPermissions.const_get(const) } + ProjectPermissions.constants.map { |const| ProjectPermissions.const_get(const) } + ExperimentPermissions.constants.map { |const| ExperimentPermissions.const_get(const) } + MyModulePermissions.constants.map { |const| MyModulePermissions.const_get(const) } + @@ -121,8 +131,11 @@ module PermissionExtends NORMAL_USER_PERMISSIONS = [ TeamPermissions::PROJECTS_CREATE, TeamPermissions::PROTOCOLS_CREATE, + TeamPermissions::REPORTS_CREATE, ProtocolPermissions::READ, ProtocolPermissions::MANAGE, + ReportPermissions::READ, + ReportPermissions::MANAGE, ProjectPermissions::READ, ProjectPermissions::READ_ARCHIVED, ProjectPermissions::ACTIVITIES_READ, @@ -210,6 +223,7 @@ module PermissionExtends VIEWER_PERMISSIONS = [ ProtocolPermissions::READ, + ReportPermissions::READ, ProjectPermissions::READ, ProjectPermissions::READ_ARCHIVED, ProjectPermissions::ACTIVITIES_READ, diff --git a/db/migrate/20220516111152_add_team_level_permissions.rb b/db/migrate/20220516111152_add_team_level_permissions.rb index 591404838..e72930649 100644 --- a/db/migrate/20220516111152_add_team_level_permissions.rb +++ b/db/migrate/20220516111152_add_team_level_permissions.rb @@ -8,9 +8,13 @@ class AddTeamLevelPermissions < ActiveRecord::Migration[6.1] TeamPermissions::PROJECTS_CREATE, TeamPermissions::INVENTORIES_CREATE, TeamPermissions::PROTOCOLS_CREATE, + TeamPermissions::REPORTS_CREATE, ProtocolPermissions::READ, ProtocolPermissions::MANAGE, ProtocolPermissions::USERS_MANAGE, + ReportPermissions::READ, + ReportPermissions::MANAGE, + ReportPermissions::USERS_MANAGE, RepositoryPermissions::READ, RepositoryPermissions::READ_ARCHIVED, RepositoryPermissions::MANAGE, @@ -28,8 +32,11 @@ class AddTeamLevelPermissions < ActiveRecord::Migration[6.1] NORMAL_USER_PERMISSIONS = [ TeamPermissions::PROJECTS_CREATE, TeamPermissions::PROTOCOLS_CREATE, + TeamPermissions::REPORTS_CREATE, ProtocolPermissions::READ, ProtocolPermissions::MANAGE, + ReportPermissions::READ, + ReportPermissions::MANAGE, RepositoryPermissions::READ, RepositoryPermissions::COLUMNS_CREATE, RepositoryPermissions::ROWS_CREATE, @@ -37,7 +44,7 @@ class AddTeamLevelPermissions < ActiveRecord::Migration[6.1] RepositoryPermissions::ROWS_DELETE ].freeze - VIEWER_PERMISSIONS = [ProtocolPermissions::READ].freeze + VIEWER_PERMISSIONS = [ProtocolPermissions::READ, ReportPermissions::READ].freeze def change reversible do |dir| @@ -70,7 +77,7 @@ class AddTeamLevelPermissions < ActiveRecord::Migration[6.1] @viewer_role.permissions = @viewer_role.permissions - VIEWER_PERMISSIONS @viewer_role.save(validate: false) - UserAssignment.where(assignable_type: %w(Team Protocol Repository)).delete_all + UserAssignment.where(assignable_type: %w(Team Protocol Report Repository)).delete_all end end end @@ -87,7 +94,7 @@ class AddTeamLevelPermissions < ActiveRecord::Migration[6.1] end def create_user_assignments(user_teams, user_role) - user_teams.includes(:user, team: %i(repositories repository_protocols)) + user_teams.includes(:user, team: %i(reports repositories repository_protocols)) .find_in_batches(batch_size: 100) do |user_team_batch| user_assignments = [] user_team_batch.each do |user_team| @@ -108,6 +115,9 @@ class AddTeamLevelPermissions < ActiveRecord::Migration[6.1] user_assignments << new_user_assignment(user_team.user, protocol, @viewer_role, :automatically) end end + user_team.team.reports.each do |report| + user_assignments << new_user_assignment(user_team.user, report, user_role, :automatically) + end end UserAssignment.import(user_assignments) end