From d18f60aefed325d93c18b11991040859d91a3d55 Mon Sep 17 00:00:00 2001 From: ulferts Date: Wed, 2 Mar 2022 14:59:51 +0100 Subject: [PATCH] replace assignable column on role --- app/contracts/roles/base_contract.rb | 1 - app/models/members/scopes/assignable.rb | 10 ++++++- app/models/role.rb | 2 +- app/views/roles/_member_attributes.html.erb | 3 -- app/views/roles/_permissions.html.erb | 5 +++- config/locales/en.yml | 3 +- ...20220302123642_assignable_to_permission.rb | 30 +++++++++++++++++++ .../src/global_styles/content/_forms.sass | 3 ++ .../spec/features/impediments_spec.rb | 3 +- .../spec/features/tasks_on_taskboard_spec.rb | 3 +- .../impediments/create_services_spec.rb | 2 +- .../bcf/v2_1/project_extensions_api_spec.rb | 4 +-- .../requests/api/bcf/v2_1/topics_api_spec.rb | 2 +- .../action_boards/assignee_board_spec.rb | 2 +- .../spec/features/budgets/add_budget_spec.rb | 2 +- .../features/budgets/update_budget_spec.rb | 8 ++--- .../cost_entries/add_cost_entry_spec.rb | 14 +++++---- .../add_entry_without_rate_permission_spec.rb | 8 +++-- .../spec/features/my/assigned_to_me_spec.rb | 9 +++--- .../spec/features/update_entries_spec.rb | 2 +- .../spec/features/shared_context.rb | 1 + .../team_planner_user_interaction_spec.rb | 2 +- spec/contracts/roles/create_contract_spec.rb | 1 - .../roles/shared_contract_examples.rb | 1 - spec/contracts/roles/update_contract_spec.rb | 4 +-- .../work_packages/bulk_controller_spec.rb | 3 +- .../work_packages/moves_controller_spec.rb | 3 +- spec/factories/role_factory.rb | 8 ++--- .../global_roles/global_role_crud_spec.rb | 2 +- spec/features/projects/copy_spec.rb | 7 +++-- .../invite_user_modal_spec.rb | 10 +++---- .../subproject_invite_spec.rb | 2 +- spec/features/work_packages/copy_spec.rb | 2 +- .../custom_actions/custom_actions_spec.rb | 2 +- .../work_packages/edit_work_package_spec.rb | 3 +- .../new/attributes_from_filter_spec.rb | 2 +- .../new/new_work_package_spec.rb | 2 +- .../table/queries/me_filter_spec.rb | 2 +- spec/models/mail_handler_spec.rb | 4 +-- .../scopes/possible_assignee_spec.rb | 2 +- .../form/work_package_form_resource_spec.rb | 8 ++--- .../v3/work_packages/update_resource_spec.rb | 6 ++-- .../cleanup_service_integration_spec.rb | 5 ++-- .../projects/copy_service_integration_spec.rb | 2 +- .../shared_available_principals_examples.rb | 27 +++++++++++------ spec_legacy/fixtures/role_permissions.yml | 4 +++ spec_legacy/unit/mail_handler_spec.rb | 2 +- 47 files changed, 146 insertions(+), 87 deletions(-) create mode 100644 db/migrate/20220302123642_assignable_to_permission.rb diff --git a/app/contracts/roles/base_contract.rb b/app/contracts/roles/base_contract.rb index 6f109215eb..199272c226 100644 --- a/app/contracts/roles/base_contract.rb +++ b/app/contracts/roles/base_contract.rb @@ -29,7 +29,6 @@ module Roles class BaseContract < ::ModelContract attribute :name - attribute :assignable validate :check_permission_prerequisites diff --git a/app/models/members/scopes/assignable.rb b/app/models/members/scopes/assignable.rb index d3f1d174ef..92eb884976 100644 --- a/app/models/members/scopes/assignable.rb +++ b/app/models/members/scopes/assignable.rb @@ -39,7 +39,15 @@ module Members::Scopes not_locked .includes(:roles) .references(:roles) - .where(roles: { assignable: true }) + .where(assignable_permission_exists) + end + + def assignable_permission_exists + RolePermission + .where('role_permissions.role_id = roles.id') + .where(permission: 'work_package_assigned') + .arel + .exists end end end diff --git a/app/models/role.rb b/app/models/role.rb index accdb3a203..c48c4ea23c 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -50,7 +50,7 @@ class Role < ApplicationRecord has_many :member_roles, dependent: :destroy has_many :members, through: :member_roles - has_many :role_permissions + has_many :role_permissions, dependent: :destroy default_scope -> { includes(:role_permissions) diff --git a/app/views/roles/_member_attributes.html.erb b/app/views/roles/_member_attributes.html.erb index 111a802b24..4c7e84c555 100644 --- a/app/views/roles/_member_attributes.html.erb +++ b/app/views/roles/_member_attributes.html.erb @@ -27,9 +27,6 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -
- <%= f.check_box :assignable %> -
<% if role.new_record? && roles.any? %>
<%= styled_label_tag :copy_workflow_from, t(:label_copy_workflow_from) %> diff --git a/app/views/roles/_permissions.html.erb b/app/views/roles/_permissions.html.erb index a0bc20c92e..bb4c690250 100644 --- a/app/views/roles/_permissions.html.erb +++ b/app/views/roles/_permissions.html.erb @@ -51,9 +51,12 @@ See COPYRIGHT and LICENSE files for more details. <%= styled_check_box_tag 'role[permissions][]', permission.name, (role.permissions && role.permissions.include?(permission.name)) %> - <%= l_or_humanize(permission.name, prefix: 'permission_') %> + <%= t(:"permission_#{permission.name}") %>
+
+ <%= t(:"permission_#{permission.name}_explanation", default: nil) %> +
<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index f5d8c4aa6e..2f29c00ff7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -529,7 +529,6 @@ en: repository: url: "URL" role: - assignable: "Work packages can be assigned to users and groups in possession of this role in the respective project" permissions: "Permissions" time_entry: activity: "Activity" @@ -2287,6 +2286,8 @@ en: permission_view_timelines: "View timelines" permission_view_wiki_edits: "View wiki history" permission_view_wiki_pages: "View wiki" + permission_work_package_assigned: "Become assignee/responsible" + permission_work_package_assigned_explanation: "Work packages can be assigned to users and groups in possession of this role in the respective project" placeholders: default: "-" diff --git a/db/migrate/20220302123642_assignable_to_permission.rb b/db/migrate/20220302123642_assignable_to_permission.rb new file mode 100644 index 0000000000..a9116b178f --- /dev/null +++ b/db/migrate/20220302123642_assignable_to_permission.rb @@ -0,0 +1,30 @@ +class AssignableToPermission < ActiveRecord::Migration[6.1] + def up + # Because of a missing dependent: :destroy, some role_permission + # for removed roles exist. + execute <<~SQL.squish + DELETE FROM role_permissions WHERE role_id IS NULL + SQL + + execute <<~SQL.squish + INSERT INTO role_permissions (role_id, permission, created_at, updated_at) + SELECT id role_id, 'work_package_assigned' permission, NOW() created_at, NOW() updated_at FROM roles + WHERE assignable AND type = 'Role' AND builtin = 0 + SQL + + remove_column :roles, :assignable + end + + def down + add_column :roles, :assignable, :boolean, default: true + + execute <<~SQL.squish + UPDATE roles + SET assignable = EXISTS(SELECT 1 from role_permissions WHERE permission = 'work_package_assigned' and role_id = roles.id) + SQL + + execute <<~SQL.squish + DELETE FROM role_permissions where permission = 'work_package_assigned' + SQL + end +end diff --git a/frontend/src/global_styles/content/_forms.sass b/frontend/src/global_styles/content/_forms.sass index 4756dbe80e..012845101c 100644 --- a/frontend/src/global_styles/content/_forms.sass +++ b/frontend/src/global_styles/content/_forms.sass @@ -484,6 +484,9 @@ fieldset.form--fieldset &.-no-italic font-style: normal + &.-labeled-checkbox + margin-left: 25px + .form--inline-instructions font-style: italic display: inline diff --git a/modules/backlogs/spec/features/impediments_spec.rb b/modules/backlogs/spec/features/impediments_spec.rb index 4207dfa529..acdc071ab7 100644 --- a/modules/backlogs/spec/features/impediments_spec.rb +++ b/modules/backlogs/spec/features/impediments_spec.rb @@ -60,7 +60,8 @@ describe 'Impediments on taskboard', view_work_packages edit_work_packages manage_subtasks - assign_versions)) + assign_versions + work_package_assigned)) end let!(:current_user) do create(:user, diff --git a/modules/backlogs/spec/features/tasks_on_taskboard_spec.rb b/modules/backlogs/spec/features/tasks_on_taskboard_spec.rb index 493ac7bc39..87594a1930 100644 --- a/modules/backlogs/spec/features/tasks_on_taskboard_spec.rb +++ b/modules/backlogs/spec/features/tasks_on_taskboard_spec.rb @@ -57,7 +57,8 @@ describe 'Tasks on taskboard', view_work_packages edit_work_packages manage_subtasks - assign_versions)) + assign_versions + work_package_assigned)) end let!(:current_user) do create(:user, diff --git a/modules/backlogs/spec/services/impediments/create_services_spec.rb b/modules/backlogs/spec/services/impediments/create_services_spec.rb index be2d673de9..de97bba8c5 100644 --- a/modules/backlogs/spec/services/impediments/create_services_spec.rb +++ b/modules/backlogs/spec/services/impediments/create_services_spec.rb @@ -32,7 +32,7 @@ describe Impediments::CreateService do let(:instance) { described_class.new(user: user) } let(:user) { create(:user) } - let(:role) { create(:role, permissions: %i(add_work_packages assign_versions)) } + let(:role) { create(:role, permissions: %i(add_work_packages assign_versions work_package_assigned)) } let(:type_feature) { create(:type_feature) } let(:type_task) { create(:type_task) } let(:priority) { create(:priority, is_default: true) } diff --git a/modules/bim/spec/requests/api/bcf/v2_1/project_extensions_api_spec.rb b/modules/bim/spec/requests/api/bcf/v2_1/project_extensions_api_spec.rb index 442e5a2c9f..99d07be982 100644 --- a/modules/bim/spec/requests/api/bcf/v2_1/project_extensions_api_spec.rb +++ b/modules/bim/spec/requests/api/bcf/v2_1/project_extensions_api_spec.rb @@ -75,13 +75,13 @@ describe 'BCF 2.1 project extensions resource', type: :request, content_type: :j let(:current_user) do create(:user, member_in_project: project, - member_with_permissions: %i[view_project edit_project manage_bcf view_members]) + member_with_permissions: %i[view_project edit_project manage_bcf view_members work_package_assigned]) end let(:other_user) do create(:user, member_in_project: project, - member_with_permissions: [:view_project]) + member_with_permissions: %i[view_project work_package_assigned]) end before do diff --git a/modules/bim/spec/requests/api/bcf/v2_1/topics_api_spec.rb b/modules/bim/spec/requests/api/bcf/v2_1/topics_api_spec.rb index 5ebe12a090..0bf8ea428d 100644 --- a/modules/bim/spec/requests/api/bcf/v2_1/topics_api_spec.rb +++ b/modules/bim/spec/requests/api/bcf/v2_1/topics_api_spec.rb @@ -38,7 +38,7 @@ describe 'BCF 2.1 topics resource', type: :request, content_type: :json, with_ma let(:view_only_user) do create(:user, member_in_project: project, - member_with_permissions: %i[view_linked_issues view_work_packages]) + member_with_permissions: %i[view_linked_issues view_work_packages work_package_assigned]) end let(:only_member_user) do create(:user, diff --git a/modules/boards/spec/features/action_boards/assignee_board_spec.rb b/modules/boards/spec/features/action_boards/assignee_board_spec.rb index dc4d1944c0..144c739c7e 100644 --- a/modules/boards/spec/features/action_boards/assignee_board_spec.rb +++ b/modules/boards/spec/features/action_boards/assignee_board_spec.rb @@ -51,7 +51,7 @@ describe 'Assignee action board', let(:permissions) do %i[show_board_views manage_board_views add_work_packages - edit_work_packages view_work_packages manage_public_queries] + edit_work_packages view_work_packages manage_public_queries work_package_assigned] end let!(:priority) { create :default_priority } diff --git a/modules/budgets/spec/features/budgets/add_budget_spec.rb b/modules/budgets/spec/features/budgets/add_budget_spec.rb index d7bf565461..1cfdda3bc3 100644 --- a/modules/budgets/spec/features/budgets/add_budget_spec.rb +++ b/modules/budgets/spec/features/budgets/add_budget_spec.rb @@ -97,7 +97,7 @@ describe 'adding a new budget', type: :feature, js: true do let(:new_budget_page) { Pages::NewBudget.new project.identifier } let(:budget_page) { Pages::EditBudget.new Budget.last } - let(:project_members) { { user => create(:role) } } + let(:project_members) { { user => create(:role, permissions: %i[work_package_assigned]) } } before do create :cost_rate, cost_type: cost_type, rate: 50.0 diff --git a/modules/budgets/spec/features/budgets/update_budget_spec.rb b/modules/budgets/spec/features/budgets/update_budget_spec.rb index 790c0ee4e4..530066cc93 100644 --- a/modules/budgets/spec/features/budgets/update_budget_spec.rb +++ b/modules/budgets/spec/features/budgets/update_budget_spec.rb @@ -31,15 +31,13 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper.rb') describe 'updating a budget', type: :feature, js: true do let(:project) do create :project_with_types, - enabled_module_names: %i[budgets costs], - members: { user => create(:role) } + enabled_module_names: %i[budgets costs work_package_tracking], + members: { user => create(:role, permissions: %i[work_package_assigned]) } end let(:user) { create :admin } let(:budget) { create :budget, author: user, project: project } - before do - login_as(user) - end + current_user { user } describe 'with new cost items' do let(:cost_type) do diff --git a/modules/costs/spec/features/cost_entries/add_cost_entry_spec.rb b/modules/costs/spec/features/cost_entries/add_cost_entry_spec.rb index ac1745fbfa..9de16f8d06 100644 --- a/modules/costs/spec/features/cost_entries/add_cost_entry_spec.rb +++ b/modules/costs/spec/features/cost_entries/add_cost_entry_spec.rb @@ -36,12 +36,14 @@ describe 'Work Package cost fields', type: :feature, js: true do create(:project, types: [type_task]) end shared_let(:role) do - create :role, permissions: %i[view_work_packages - delete_work_packages - log_costs - view_cost_rates - edit_cost_entries - view_cost_entries] + create :role, + permissions: %i[view_work_packages + delete_work_packages + log_costs + view_cost_rates + edit_cost_entries + view_cost_entries + work_package_assigned] end shared_let(:user) do create :user, diff --git a/modules/costs/spec/features/cost_entries/add_entry_without_rate_permission_spec.rb b/modules/costs/spec/features/cost_entries/add_entry_without_rate_permission_spec.rb index 3fa2e3f81b..5153b681bf 100644 --- a/modules/costs/spec/features/cost_entries/add_entry_without_rate_permission_spec.rb +++ b/modules/costs/spec/features/cost_entries/add_entry_without_rate_permission_spec.rb @@ -36,9 +36,11 @@ describe 'Create cost entry without rate permissions', type: :feature, js: true create(:project, types: [type_task]) end shared_let(:role) do - create :role, permissions: %i[view_work_packages - log_costs - view_cost_entries] + create :role, + permissions: %i[view_work_packages + log_costs + view_cost_entries + work_package_assigned] end shared_let(:user) do create :user, diff --git a/modules/my_page/spec/features/my/assigned_to_me_spec.rb b/modules/my_page/spec/features/my/assigned_to_me_spec.rb index 5133f570e0..000ad7df5d 100644 --- a/modules/my_page/spec/features/my/assigned_to_me_spec.rb +++ b/modules/my_page/spec/features/my/assigned_to_me_spec.rb @@ -63,7 +63,10 @@ describe 'Assigned to me embedded query on my page', type: :feature, js: true do create(:user) end - let(:role) { create(:role, permissions: %i[view_work_packages add_work_packages edit_work_packages save_queries]) } + let(:role) do + create(:role, + permissions: %i[view_work_packages add_work_packages edit_work_packages save_queries work_package_assigned]) + end let(:user) do create(:user, @@ -78,9 +81,7 @@ describe 'Assigned to me embedded query on my page', type: :feature, js: true do let(:embedded_table) { Pages::EmbeddedWorkPackagesTable.new(assigned_area.area) } let(:hierarchies) { ::Components::WorkPackages::Hierarchies.new } - before do - login_as user - end + current_user { user } context 'with parent work package' do let!(:assigned_work_package_child) do diff --git a/modules/reporting/spec/features/update_entries_spec.rb b/modules/reporting/spec/features/update_entries_spec.rb index 3051568e32..180975c516 100644 --- a/modules/reporting/spec/features/update_entries_spec.rb +++ b/modules/reporting/spec/features/update_entries_spec.rb @@ -32,7 +32,7 @@ require_relative 'support/components/cost_reports_base_table' describe 'Updating entries within the cost report', type: :feature, js: true do let(:project) { create :project } - let(:user) { create :admin } + let(:user) { create :admin, member_in_project: project, member_with_permissions: %i[work_package_assigned] } let(:work_package) { create :work_package, project: project } let!(:time_entry_user) do diff --git a/modules/team_planner/spec/features/shared_context.rb b/modules/team_planner/spec/features/shared_context.rb index 9092a1dffe..23eb9c6c7a 100644 --- a/modules/team_planner/spec/features/shared_context.rb +++ b/modules/team_planner/spec/features/shared_context.rb @@ -43,6 +43,7 @@ shared_context 'with team planner full access' do view_work_packages edit_work_packages add_work_packages view_team_planner manage_team_planner save_queries manage_public_queries + work_package_assigned ] end diff --git a/modules/team_planner/spec/features/team_planner_user_interaction_spec.rb b/modules/team_planner/spec/features/team_planner_user_interaction_spec.rb index 55354ed836..f02497d805 100644 --- a/modules/team_planner/spec/features/team_planner_user_interaction_spec.rb +++ b/modules/team_planner/spec/features/team_planner_user_interaction_spec.rb @@ -43,7 +43,7 @@ describe 'Team planner drag&dop and resizing', type: :feature, js: true do firstname: 'Bernd', member_in_project: project, member_with_permissions: %w[ - view_work_packages view_team_planner + view_work_packages view_team_planner work_package_assigned ] end diff --git a/spec/contracts/roles/create_contract_spec.rb b/spec/contracts/roles/create_contract_spec.rb index cd72139e42..0f484c91b4 100644 --- a/spec/contracts/roles/create_contract_spec.rb +++ b/spec/contracts/roles/create_contract_spec.rb @@ -34,7 +34,6 @@ describe Roles::CreateContract do let(:role) do Role.new.tap do |r| r.name = role_name - r.assignable = role_assignable r.permissions = role_permissions end end diff --git a/spec/contracts/roles/shared_contract_examples.rb b/spec/contracts/roles/shared_contract_examples.rb index b60f8839f9..565127aca3 100644 --- a/spec/contracts/roles/shared_contract_examples.rb +++ b/spec/contracts/roles/shared_contract_examples.rb @@ -34,7 +34,6 @@ shared_examples_for 'roles contract' do end let(:role_instance) { Role.new } let(:role_name) { 'A role name' } - let(:role_assignable) { true } let(:role_permissions) { [:view_work_packages] } def expect_valid(valid, symbols = {}) diff --git a/spec/contracts/roles/update_contract_spec.rb b/spec/contracts/roles/update_contract_spec.rb index 80a710539e..1b06845b3d 100644 --- a/spec/contracts/roles/update_contract_spec.rb +++ b/spec/contracts/roles/update_contract_spec.rb @@ -33,10 +33,8 @@ describe Roles::UpdateContract do it_behaves_like 'roles contract' do let(:role) do build_stubbed(:role, - name: 'Some name', - assignable: !role_assignable).tap do |r| + name: 'Some name').tap do |r| r.name = role_name - r.assignable = role_assignable r.permissions = role_permissions end end diff --git a/spec/controllers/work_packages/bulk_controller_spec.rb b/spec/controllers/work_packages/bulk_controller_spec.rb index 5174aeec9b..a96faf32d0 100644 --- a/spec/controllers/work_packages/bulk_controller_spec.rb +++ b/spec/controllers/work_packages/bulk_controller_spec.rb @@ -58,7 +58,8 @@ describe WorkPackages::BulkController, type: :controller, with_settings: { journ permissions: %i[edit_work_packages view_work_packages manage_subtasks - assign_versions]) + assign_versions + work_package_assigned]) end let(:member1_p1) do create(:member, diff --git a/spec/controllers/work_packages/moves_controller_spec.rb b/spec/controllers/work_packages/moves_controller_spec.rb index a47afee858..231db99cd0 100644 --- a/spec/controllers/work_packages/moves_controller_spec.rb +++ b/spec/controllers/work_packages/moves_controller_spec.rb @@ -37,7 +37,8 @@ describe WorkPackages::MovesController, type: :controller, with_settings: { jour add_work_packages edit_work_packages assign_versions - manage_subtasks) + manage_subtasks + work_package_assigned) end let(:type) { create :type } let(:type_2) { create :type } diff --git a/spec/factories/role_factory.rb b/spec/factories/role_factory.rb index ddb053fb66..3f8549106e 100644 --- a/spec/factories/role_factory.rb +++ b/spec/factories/role_factory.rb @@ -32,25 +32,21 @@ FactoryBot.define do factory :role do permissions { [] } sequence(:name) { |n| "role_#{n}" } - assignable { true } factory :non_member do name { 'Non member' } builtin { Role::BUILTIN_NON_MEMBER } - assignable { false } initialize_with { Role.where(name: name).first_or_initialize } end factory :anonymous_role do name { 'Anonymous' } builtin { Role::BUILTIN_ANONYMOUS } - assignable { false } initialize_with { Role.where(name: name).first_or_initialize } end factory :existing_role do - name { 'Role ' + Digest::MD5.hexdigest(permissions.map(&:to_s).join('/'))[0..4] } - assignable { true } + name { "Role #{Digest::MD5.hexdigest(permissions.map(&:to_s).join('/'))[0..4]}" } permissions { [] } initialize_with do @@ -58,7 +54,7 @@ FactoryBot.define do if Role.where(name: name).exists? Role.find_by(name: name) else - Role.create name: name, assignable: assignable + Role.create name: name end role.add_permission!(*permissions.reject { |p| role.permissions.include?(p) }) diff --git a/spec/features/global_roles/global_role_crud_spec.rb b/spec/features/global_roles/global_role_crud_spec.rb index 019c1e3e6b..024ecbd023 100644 --- a/spec/features/global_roles/global_role_crud_spec.rb +++ b/spec/features/global_roles/global_role_crud_spec.rb @@ -52,7 +52,7 @@ describe 'Global role: Global role CRUD', type: :feature, js: true do # And I should see "Global group" expect(page).to have_text 'GLOBAL GROUP' # And I should see "Glob test" - expect(page).to have_text 'Glob test' + expect(page).to have_text 'Permission Glob Test' # And I should not see "Issues can be assigned to this role" expect(page).to have_no_text 'Issues can be assigned to this role' # When I fill in "Name" with "Manager" diff --git a/spec/features/projects/copy_spec.rb b/spec/features/projects/copy_spec.rb index f9cfdb1662..d0f3c472d2 100644 --- a/spec/features/projects/copy_spec.rb +++ b/spec/features/projects/copy_spec.rb @@ -76,7 +76,9 @@ describe 'Projects copy', create(:role, permissions: permissions) end - let(:permissions) { %i(copy_projects edit_project add_subprojects manage_types view_work_packages select_custom_fields) } + let(:permissions) do + %i(copy_projects edit_project add_subprojects manage_types view_work_packages select_custom_fields work_package_assigned) + end let(:wp_user) do user = create(:user) @@ -151,7 +153,8 @@ describe 'Projects copy', expect(page).to have_text 'The job has been queued and will be processed shortly.' # ensure all jobs are run especially emails which might be sent later on - while perform_enqueued_jobs > 0 do end + while perform_enqueued_jobs > 0 + end copied_project = Project.find_by(name: 'Copied project') diff --git a/spec/features/users/invite_user_modal/invite_user_modal_spec.rb b/spec/features/users/invite_user_modal/invite_user_modal_spec.rb index e41411d786..d72ab6466a 100644 --- a/spec/features/users/invite_user_modal/invite_user_modal_spec.rb +++ b/spec/features/users/invite_user_modal/invite_user_modal_spec.rb @@ -32,7 +32,7 @@ describe 'Invite user modal', type: :feature, js: true do shared_let(:project) { create :project } shared_let(:work_package) { create :work_package, project: project } - let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } + let(:permissions) { %i[view_work_packages edit_work_packages manage_members work_package_assigned] } let(:global_permissions) { %i[] } let(:modal) do ::Components::Users::InviteUserModal.new project: project, @@ -127,7 +127,7 @@ describe 'Invite user modal', type: :feature, js: true do let(:principal) { build :invited_user } context 'when the current user has permissions to create a user' do - let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } + let(:permissions) { %i[view_work_packages edit_work_packages manage_members work_package_assigned] } let(:global_permissions) { %i[manage_user] } it_behaves_like 'invites the principal to the project' do @@ -139,6 +139,7 @@ describe 'Invite user modal', type: :feature, js: true do context 'when the current user does not have permissions to invite a user to the instance by email' do let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } + it 'does not show the invite user option' do modal.project_step ngselect = modal.open_select_in_step principal.mail @@ -186,9 +187,10 @@ describe 'Invite user modal', type: :feature, js: true do let(:principal) { build :placeholder_user, name: 'MY NEW PLACEHOLDER' } context 'an enterprise system', with_ee: %i[placeholder_users] do + let(:permissions) { %i[view_work_packages edit_work_packages manage_members work_package_assigned] } + describe 'create a new placeholder' do context 'with permissions to manage placeholders' do - let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } let(:global_permissions) { %i[manage_placeholder_user] } it_behaves_like 'invites the principal to the project' do @@ -199,7 +201,6 @@ describe 'Invite user modal', type: :feature, js: true do end context 'without permissions to manage placeholders' do - let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } it 'does not allow to invite a new placeholder' do modal.project_step @@ -213,7 +214,6 @@ describe 'Invite user modal', type: :feature, js: true do context 'with an existing placeholder' do let(:principal) { create :placeholder_user, name: 'EXISTING PLACEHOLDER' } - let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } let(:global_permissions) { %i[] } it_behaves_like 'invites the principal to the project' do diff --git a/spec/features/users/invite_user_modal/subproject_invite_spec.rb b/spec/features/users/invite_user_modal/subproject_invite_spec.rb index 6ebfcc9e5d..8533ae37ff 100644 --- a/spec/features/users/invite_user_modal/subproject_invite_spec.rb +++ b/spec/features/users/invite_user_modal/subproject_invite_spec.rb @@ -34,7 +34,7 @@ describe 'Invite user modal subprojects', type: :feature, js: true do shared_let(:work_package) { create :work_package, project: subproject } shared_let(:invitable_user) { create :user, firstname: 'Invitable', lastname: 'User' } - let(:permissions) { %i[view_work_packages edit_work_packages manage_members] } + let(:permissions) { %i[view_work_packages edit_work_packages manage_members work_package_assigned] } let(:global_permissions) { %i[] } let(:modal) do ::Components::Users::InviteUserModal.new project: subproject, diff --git a/spec/features/work_packages/copy_spec.rb b/spec/features/work_packages/copy_spec.rb index 66922464a2..6129705ba6 100644 --- a/spec/features/work_packages/copy_spec.rb +++ b/spec/features/work_packages/copy_spec.rb @@ -61,7 +61,7 @@ RSpec.feature 'Work package copy', js: true, selenium: true do type: type, author: author) end - let(:role) { build(:role, permissions: [:view_work_packages]) } + let(:role) { build(:role, permissions: %i[view_work_packages work_package_assigned]) } let(:assignee) do create(:user, firstname: 'An', diff --git a/spec/features/work_packages/custom_actions/custom_actions_spec.rb b/spec/features/work_packages/custom_actions/custom_actions_spec.rb index 371df91c7a..113cea7487 100644 --- a/spec/features/work_packages/custom_actions/custom_actions_spec.rb +++ b/spec/features/work_packages/custom_actions/custom_actions_spec.rb @@ -31,7 +31,7 @@ require 'spec_helper' describe 'Custom actions', type: :feature, js: true do shared_let(:admin) { create :admin } - let(:permissions) { %i(view_work_packages edit_work_packages move_work_packages) } + let(:permissions) { %i(view_work_packages edit_work_packages move_work_packages work_package_assigned) } let(:role) { create(:role, permissions: permissions) } let!(:other_role) { create(:role, permissions: permissions) } let(:user) do diff --git a/spec/features/work_packages/edit_work_package_spec.rb b/spec/features/work_packages/edit_work_package_spec.rb index 11df522674..9388b56834 100644 --- a/spec/features/work_packages/edit_work_package_spec.rb +++ b/spec/features/work_packages/edit_work_package_spec.rb @@ -17,7 +17,8 @@ describe 'edit work package', js: true do let(:manager_role) do create :role, permissions: %i[view_work_packages - edit_work_packages] + edit_work_packages + work_package_assigned] end let(:manager) do create :admin, diff --git a/spec/features/work_packages/new/attributes_from_filter_spec.rb b/spec/features/work_packages/new/attributes_from_filter_spec.rb index 3268346406..02a378397d 100644 --- a/spec/features/work_packages/new/attributes_from_filter_spec.rb +++ b/spec/features/work_packages/new/attributes_from_filter_spec.rb @@ -41,7 +41,7 @@ RSpec.feature 'Work package create uses attributes from filters', js: true, sele let(:wp_table) { ::Pages::WorkPackagesTable.new(project) } let(:split_view_create) { ::Pages::SplitWorkPackageCreate.new(project: project) } - let(:role) { create :existing_role, permissions: [:view_work_packages] } + let(:role) { create :existing_role, permissions: %i[view_work_packages work_package_assigned] } let!(:query) do build(:query, project: project, user: user).tap do |query| diff --git a/spec/features/work_packages/new/new_work_package_spec.rb b/spec/features/work_packages/new/new_work_package_spec.rb index 07d55c3311..6bf5b02a4e 100644 --- a/spec/features/work_packages/new/new_work_package_spec.rb +++ b/spec/features/work_packages/new/new_work_package_spec.rb @@ -13,7 +13,7 @@ describe 'new work package', js: true do create(:project, types: types) end - let(:permissions) { %i[view_work_packages add_work_packages edit_work_packages] } + let(:permissions) { %i[view_work_packages add_work_packages edit_work_packages work_package_assigned] } let(:user) do create(:user, member_in_project: project, diff --git a/spec/features/work_packages/table/queries/me_filter_spec.rb b/spec/features/work_packages/table/queries/me_filter_spec.rb index 06048687b0..09d1ea51db 100644 --- a/spec/features/work_packages/table/queries/me_filter_spec.rb +++ b/spec/features/work_packages/table/queries/me_filter_spec.rb @@ -36,7 +36,7 @@ describe 'filter me value', js: true do public: true, members: project_members end - let(:role) { create :existing_role, permissions: [:view_work_packages] } + let(:role) { create :existing_role, permissions: %i[view_work_packages work_package_assigned] } let(:admin) { create :admin } let(:user) { create :user } let(:wp_table) { ::Pages::WorkPackagesTable.new(project) } diff --git a/spec/models/mail_handler_spec.rb b/spec/models/mail_handler_spec.rb index 18f90855d3..6671e33c4f 100644 --- a/spec/models/mail_handler_spec.rb +++ b/spec/models/mail_handler_spec.rb @@ -47,7 +47,7 @@ describe MailHandler, type: :model do end shared_context 'wp_on_given_project' do - let(:permissions) { %i[add_work_packages assign_versions] } + let(:permissions) { %i[add_work_packages assign_versions work_package_assigned] } let!(:user) do create(:user, mail: 'JSmith@somenet.foo', @@ -151,7 +151,7 @@ describe MailHandler, type: :model do end shared_context 'with a reply to a wp mention with attributes' do - let(:permissions) { %i[add_work_package_notes view_work_packages edit_work_packages] } + let(:permissions) { %i[add_work_package_notes view_work_packages edit_work_packages work_package_assigned] } let(:role) do create(:role, permissions: permissions) end diff --git a/spec/models/principals/scopes/possible_assignee_spec.rb b/spec/models/principals/scopes/possible_assignee_spec.rb index 313b66acfb..1fccb16053 100644 --- a/spec/models/principals/scopes/possible_assignee_spec.rb +++ b/spec/models/principals/scopes/possible_assignee_spec.rb @@ -34,7 +34,7 @@ describe Principals::Scopes::PossibleAssignee, type: :model do let(:project) { create(:project) } let(:other_project) { create(:project) } let(:role_assignable) { true } - let(:role) { create(:role, assignable: role_assignable) } + let(:role) { create(:role, permissions: (role_assignable ? [:work_package_assigned] : [])) } let(:user_status) { :active } let!(:member_user) do create(:user, diff --git a/spec/requests/api/v3/work_packages/form/work_package_form_resource_spec.rb b/spec/requests/api/v3/work_packages/form/work_package_form_resource_spec.rb index 63b67cf332..2e6ab0a4a3 100644 --- a/spec/requests/api/v3/work_packages/form/work_package_form_resource_spec.rb +++ b/spec/requests/api/v3/work_packages/form/work_package_form_resource_spec.rb @@ -404,7 +404,8 @@ describe 'API v3 Work package form resource', type: :request, with_mail: false d let(:path) { "_embedded/payload/_links/#{property}/href" } let(:visible_user) do create(:user, - member_in_project: project) + member_in_project: project, + member_with_permissions: [:work_package_assigned]) end let(:user_parameter) { { _links: { property => { href: user_link } } } } let(:params) { valid_params.merge(user_parameter) } @@ -441,7 +442,7 @@ describe 'API v3 Work package form resource', type: :request, with_mail: false d context 'existing group' do let(:user_link) { api_v3_paths.group group.id } let(:group) { create(:group) } - let(:role) { create(:role) } + let(:role) { create(:role, permissions: %i[work_package_assigned]) } let(:group_member) do create(:member, principal: group, @@ -458,11 +459,10 @@ describe 'API v3 Work package form resource', type: :request, with_mail: false d context 'existing placeholder_user' do let(:user_link) { api_v3_paths.placeholder_user placeholder_user.id } - let(:role) { create(:role) } let(:placeholder_user) do create(:placeholder_user, member_in_project: project, - member_through_role: role) + member_with_permissions: %i[work_package_assigned]) end it_behaves_like 'valid user assignment' diff --git a/spec/requests/api/v3/work_packages/update_resource_spec.rb b/spec/requests/api/v3/work_packages/update_resource_spec.rb index 8beebcbba9..3b73503e0b 100644 --- a/spec/requests/api/v3/work_packages/update_resource_spec.rb +++ b/spec/requests/api/v3/work_packages/update_resource_spec.rb @@ -45,7 +45,7 @@ describe 'API v3 Work package resource', create(:project, identifier: 'test_project', public: false) end let(:role) { create(:role, permissions: permissions) } - let(:permissions) { %i[view_work_packages edit_work_packages assign_versions] } + let(:permissions) { %i[view_work_packages edit_work_packages assign_versions work_package_assigned] } let(:type) { create(:type) } current_user do @@ -442,7 +442,7 @@ describe 'API v3 Work package resource', end context 'assignee and responsible' do - let(:user) { create(:user, member_in_project: project) } + let(:user) { create(:user, member_in_project: project, member_with_permissions: %i[work_package_assigned]) } let(:params) { valid_params.merge(user_parameter) } let(:work_package) do create(:work_package, @@ -455,7 +455,7 @@ describe 'API v3 Work package resource', shared_context 'setup group membership' do let(:group) { create(:group) } - let(:group_role) { create(:role) } + let(:group_role) { create(:role, permissions: %i[work_package_assigned]) } let!(:group_member) do create(:member, principal: group, diff --git a/spec/services/members/cleanup_service_integration_spec.rb b/spec/services/members/cleanup_service_integration_spec.rb index 3cbcc5e00c..edbc9d77a2 100644 --- a/spec/services/members/cleanup_service_integration_spec.rb +++ b/spec/services/members/cleanup_service_integration_spec.rb @@ -58,7 +58,7 @@ describe Members::CleanupService, 'integration', type: :model do create(:member, principal: user, project: project, - roles: [create(:role, assignable: true)]) + roles: [create(:role, permissions: %i[work_package_assigned])]) end it 'keeps assigned_to to the user' do @@ -74,7 +74,8 @@ describe Members::CleanupService, 'integration', type: :model do create(:member, principal: user, project: project, - roles: [create(:role, assignable: false)]) + # Lacking work_package_assigned + roles: [create(:role, permissions: [])]) end it 'sets assigned_to to nil' do diff --git a/spec/services/projects/copy_service_integration_spec.rb b/spec/services/projects/copy_service_integration_spec.rb index 0216705dbe..d6cc888320 100644 --- a/spec/services/projects/copy_service_integration_spec.rb +++ b/spec/services/projects/copy_service_integration_spec.rb @@ -51,7 +51,7 @@ describe Projects::CopyService, 'integration', type: :model do member_in_project: source, member_through_role: role) end - let(:role) { create :role, permissions: %i[copy_projects view_work_packages] } + let(:role) { create :role, permissions: %i[copy_projects view_work_packages work_package_assigned] } shared_let(:new_project_role) { create :role, permissions: %i[] } let(:instance) do described_class.new(source: source, user: current_user) diff --git a/spec/support/api/v3/shared_available_principals_examples.rb b/spec/support/api/v3/shared_available_principals_examples.rb index cce464c79b..15021397e3 100644 --- a/spec/support/api/v3/shared_available_principals_examples.rb +++ b/spec/support/api/v3/shared_available_principals_examples.rb @@ -39,21 +39,23 @@ shared_examples_for 'available principals' do |principals| let(:other_user) do create(:user, member_in_project: project, - member_through_role: role) + member_through_role: assignable_role) end let(:role) { create(:role, permissions: permissions) } + let(:assignable_role) { create(:role, permissions: assignable_permissions) } let(:project) { create(:project) } let(:group) do create(:group, member_in_project: project, - member_through_role: role) + member_through_role: assignable_role) end let(:placeholder_user) do create(:placeholder_user, member_in_project: project, - member_through_role: role) + member_through_role: assignable_role) end let(:permissions) { [:view_work_packages] } + let(:assignable_permissions) { [:work_package_assigned] } shared_context "request available #{principals}" do before { get href } @@ -67,13 +69,15 @@ shared_examples_for 'available principals' do |principals| end describe 'users' do - context 'single user' do + let(:permissions) { %i[view_work_packages work_package_assigned] } + + context 'for a single user' do # The current user it_behaves_like "returns available #{principals}", 1, 1, 'User' end - context 'multiple users' do + context 'for multiple users' do before do other_user # and the current user @@ -81,26 +85,31 @@ shared_examples_for 'available principals' do |principals| it_behaves_like "returns available #{principals}", 2, 2, 'User' end + + context 'if the user lacks the assignable permission' do + let(:permissions) { %i[view_work_packages] } + + it_behaves_like "returns available #{principals}", 0, 0, 'User' + end end describe 'groups' do let!(:users) { [group] } - # current user and group - it_behaves_like "returns available #{principals}", 2, 2, 'Group' + it_behaves_like "returns available #{principals}", 1, 1, 'Group' end describe 'placeholder users' do let!(:users) { [placeholder_user] } - # current user and placeholder user - it_behaves_like "returns available #{principals}", 2, 2, 'PlaceholderUser' + it_behaves_like "returns available #{principals}", 1, 1, 'PlaceholderUser' end end describe 'if not allowed' do include Rack::Test::Methods let(:permissions) { [] } + before { get href } it_behaves_like 'unauthorized access' diff --git a/spec_legacy/fixtures/role_permissions.yml b/spec_legacy/fixtures/role_permissions.yml index b97c12fd76..64a366238c 100644 --- a/spec_legacy/fixtures/role_permissions.yml +++ b/spec_legacy/fixtures/role_permissions.yml @@ -340,6 +340,10 @@ role_permission132: id: 132 role_id: 2 permission: 'assign_versions' +role_permission133: + id: 133 + role_id: 2 + permission: 'work_package_assigned' role_permission200: id: 200 diff --git a/spec_legacy/unit/mail_handler_spec.rb b/spec_legacy/unit/mail_handler_spec.rb index 6470fa412e..94f36897c2 100644 --- a/spec_legacy/unit/mail_handler_spec.rb +++ b/spec_legacy/unit/mail_handler_spec.rb @@ -114,7 +114,7 @@ describe MailHandler, type: :model do it 'should add work package should match assignee on display name' do # added from redmine - not sure if it is ok here user = create(:user, firstname: 'Foo', lastname: 'Bar') - role = create(:role, name: 'Superhero') + role = create(:role, name: 'Superhero', permissions: ['work_package_assigned']) create(:member, user: user, project: Project.find(2), role_ids: [role.id]) issue = submit_email('ticket_on_given_project.eml') do |email| email.sub!(/^Assigned to.*$/, 'Assigned to: Foo Bar')