Feature 50849, added separate permission change_work_package_status

Permission `change_work_package_status` is similar to `assign_versions`
permission as it:
- Allows edit for status field, without the need for edit WP.
- Now `edit_work_packages` alone does not allow status edit; this is
how `assign_versions` works too, migration adding the new permission
to existing roles with edit WP is provided.

Some tests were fixed, but more fixes and some new tests will be added.
This commit is contained in:
Richard "Virgo" Richter
2023-11-07 11:49:35 +00:00
parent c32efbe6e5
commit 3bb2eb0401
24 changed files with 123 additions and 25 deletions
@@ -34,6 +34,7 @@ module WorkPackages
attribute :subject
attribute :description
attribute :status_id,
permission: :change_work_package_status,
writable: ->(*) {
# If we did not change into the status,
# mark unwritable if status and version is closed
@@ -52,6 +52,7 @@ module WorkPackages
with_unchanged_project_id do
next if @can.allowed?(model, :edit) ||
@can.allowed?(model, :assign_version) ||
@can.allowed?(model, :change_status) ||
@can.allowed?(model, :manage_subtasks) ||
@can.allowed?(model, :move)
next if allowed_journal_addition?
+9
View File
@@ -51,6 +51,7 @@ class WorkPackagePolicy < BasePolicy
delete: delete_allowed?(work_package),
manage_subtasks: manage_subtasks_allowed?(work_package),
comment: comment_allowed?(work_package),
change_status: change_status_allowed?(work_package),
assign_version: assign_version_allowed?(work_package)
}
end
@@ -124,4 +125,12 @@ class WorkPackagePolicy < BasePolicy
@assign_version_cache[work_package.project]
end
def change_status_allowed?(work_package)
@change_status_cache ||= Hash.new do |hash, project|
hash[project] = user.allowed_in_project?(:change_work_package_status, work_package.project)
end
@change_status_cache[work_package.project]
end
end
+2
View File
@@ -247,6 +247,7 @@ work_package_roles:
permissions:
- :view_work_packages
- :edit_work_packages
- :change_work_package_status
- :work_package_assigned
- :add_work_package_notes
- :edit_own_work_package_notes
@@ -300,6 +301,7 @@ project_roles:
- :add_work_packages
- :move_work_packages
- :edit_work_packages
- :change_work_package_status
- :assign_versions
- :work_package_assigned
- :add_work_package_notes
+5
View File
@@ -307,6 +307,11 @@ Rails.application.reloader.to_prepare do
permissible_on: :project,
dependencies: :view_work_packages
wpt.permission :change_work_package_status,
{},
permissible_on: :project,
dependencies: :view_work_packages
# A user having the following permission can become assignee and/or responsible of a work package.
# This is a passive permission in the sense that a user having the permission isn't eligible to perform
# actions but rather to have actions taken together with him/her.
+2
View File
@@ -2493,6 +2493,8 @@ en:
permission_assign_versions: "Assign versions"
permission_browse_repository: "Read-only access to repository (browse and checkout)"
permission_change_wiki_parent_page: "Change parent wiki page"
permission_change_work_package_status: "Change work package status"
permission_change_work_package_status_explanation: "Allows changing the status of work packages. Note that Edit work packages alone does not allow the status change."
permission_comment_news: "Comment news"
permission_commit_access: "Read/write access to repository (commit)"
permission_copy_projects: "Copy projects"
@@ -0,0 +1,41 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2023 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
require "#{Rails.root}/db/migrate/migration_utils/permission_adder"
class SetChangeWorkPackageStatusPermission < ActiveRecord::Migration[7.0]
def up
::Migration::MigrationUtils::PermissionAdder
.add(:edit_work_packages,
:change_work_package_status)
end
def down
# nothing to do
end
end
+1 -1
View File
@@ -169,7 +169,7 @@ patch:
description: |-
Returned if the client does not have sufficient permissions.
**Required permission:** edit work package, assign version, manage subtasks or move work package
**Required permission:** edit work package, assign version, change work package status, manage subtasks or move work package
'404':
content:
application/hal+json:
+1 -1
View File
@@ -42,7 +42,7 @@ post:
description: |-
Returned if the client does not have sufficient permissions.
**Required permission:** edit work package, assign version, manage subtasks or move work package
**Required permission:** edit work package, assign version, change work package status, manage subtasks or move work package
*Note that you will only receive this error, if you are at least allowed to see the corresponding work package.*
headers: {}
@@ -566,6 +566,7 @@ module API
def current_user_update_allowed?
@current_user_update_allowed ||=
current_user.allowed_in_project?(:edit_work_packages, represented.project) ||
current_user.allowed_in_project?(:change_work_package_status, represented.project) ||
current_user.allowed_in_project?(:assign_versions, represented.project)
end
@@ -59,6 +59,7 @@ RSpec.describe 'Impediments on taskboard',
add_work_packages
view_work_packages
edit_work_packages
change_work_package_status
manage_subtasks
assign_versions
work_package_assigned))
@@ -56,6 +56,7 @@ RSpec.describe 'Stories in backlog',
add_work_packages
view_work_packages
edit_work_packages
change_work_package_status
manage_subtasks
assign_versions))
end
@@ -56,6 +56,7 @@ RSpec.describe 'Tasks on taskboard',
add_work_packages
view_work_packages
edit_work_packages
change_work_package_status
manage_subtasks
assign_versions
work_package_assigned))
@@ -32,7 +32,7 @@ RSpec.describe Impediments::UpdateService, type: :model do
let(:instance) { described_class.new(user:, impediment:) }
let(:user) { create(:user) }
let(:role) { create(:project_role, permissions: %i(edit_work_packages view_work_packages)) }
let(:role) { create(:project_role, permissions: %i(edit_work_packages change_work_package_status view_work_packages)) }
let(:type_feature) { create(:type_feature) }
let(:type_task) { create(:type_task) }
let(:priority) { impediment.priority }
@@ -50,7 +50,7 @@ RSpec.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 work_package_assigned]
edit_work_packages change_work_package_status view_work_packages manage_public_queries work_package_assigned]
end
let!(:priority) { create(:default_priority) }
@@ -43,7 +43,7 @@ RSpec.describe 'Custom field filter in boards', js: true, with_ee: %i[board_view
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 change_work_package_status view_work_packages manage_public_queries]
end
let!(:priority) { create(:default_priority) }
@@ -43,7 +43,7 @@ RSpec.describe 'Status action board', js: true, with_ee: %i[board_view] do
let(:permissions) do
%i[show_board_views manage_board_views add_work_packages
edit_work_packages move_work_packages view_work_packages manage_public_queries]
edit_work_packages change_work_package_status move_work_packages view_work_packages manage_public_queries]
end
let!(:priority) { create(:default_priority) }
@@ -37,7 +37,7 @@ RSpec.describe 'Status action board', js: true, with_ee: %i[board_view] do
end
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 change_work_package_status view_work_packages manage_public_queries]
end
let(:role) { create(:project_role, permissions:) }
@@ -51,7 +51,7 @@ RSpec.describe 'Subproject action board', :js, with_ee: %i[board_view] do
let(:permissions) do
%i[show_board_views manage_board_views add_work_packages
edit_work_packages view_work_packages manage_public_queries move_work_packages]
edit_work_packages change_work_package_status view_work_packages manage_public_queries move_work_packages]
end
let!(:priority) { create(:default_priority) }
@@ -78,7 +78,7 @@ RSpec.describe 'Subtasks action board', js: true, with_ee: %i[board_view] do
let(:permissions) do
%i[show_board_views manage_board_views add_work_packages
edit_work_packages view_work_packages manage_public_queries manage_subtasks]
edit_work_packages change_work_package_status view_work_packages manage_public_queries manage_subtasks]
end
it 'allows management of subtasks work packages' do
@@ -50,7 +50,7 @@ RSpec.describe 'Version action board', :js, with_ee: %i[board_view] do
let(:board_index) { Pages::BoardIndex.new(project) }
let(:permissions) do
%i[show_board_views manage_board_views add_work_packages manage_versions
edit_work_packages view_work_packages manage_public_queries assign_versions]
edit_work_packages view_work_packages manage_public_queries change_work_package_status assign_versions]
end
let(:permissions_board_manager) do
%i[show_board_views manage_board_views view_work_packages manage_public_queries]
@@ -58,6 +58,7 @@ RSpec.describe 'Board management spec', js: true, with_ee: %i[board_view] do
add_work_packages
view_work_packages
edit_work_packages
change_work_package_status
manage_public_queries
]
end
@@ -236,8 +237,8 @@ RSpec.describe 'Board management spec', js: true, with_ee: %i[board_view] do
end
end
context 'with view boards + edit work package permission' do
let(:permissions) { %i[show_board_views view_work_packages add_work_packages edit_work_packages] }
context 'with view boards + edit work package and change work package status permissions' do
let(:permissions) { %i[show_board_views view_work_packages add_work_packages edit_work_packages change_work_package_status] }
let(:board_view) { create(:board_grid_with_queries, project:) }
it 'allows viewing boards index and moving items around' do
@@ -844,20 +844,38 @@ RSpec.describe API::V3::WorkPackages::Schema::WorkPackageSchemaRepresenter do
end
describe 'status' do
it_behaves_like 'has basic schema properties' do
let(:path) { 'status' }
let(:type) { 'Status' }
let(:name) { I18n.t('attributes.status') }
let(:required) { true }
let(:writable) { true }
let(:has_default) { true }
let(:location) { '_links' }
context 'if having the assign_versions permission' do
let(:permissions) { [:change_work_package_status] }
it_behaves_like 'has basic schema properties' do
let(:path) { 'status' }
let(:type) { 'Status' }
let(:name) { I18n.t('attributes.status') }
let(:required) { true }
let(:writable) { true }
let(:has_default) { true }
let(:location) { '_links' }
end
it_behaves_like 'has a collection of allowed values' do
let(:json_path) { 'status' }
let(:href_path) { 'statuses' }
let(:factory) { :status }
end
end
it_behaves_like 'has a collection of allowed values' do
let(:json_path) { 'status' }
let(:href_path) { 'statuses' }
let(:factory) { :status }
context 'if having the edit_work_packages permission' do
let(:permissions) { [:edit_work_packages] }
it_behaves_like 'has basic schema properties' do
let(:path) { 'status' }
let(:type) { 'Status' }
let(:name) { I18n.t('attributes.status') }
let(:required) { true }
let(:writable) { false }
let(:has_default) { true }
let(:location) { '_links' }
end
end
end
@@ -466,7 +466,7 @@ RSpec.describe API::V3::WorkPackages::WorkPackageRepresenter do
end
end
context 'when user is lacks edit permission but has assign_versions' do
context 'when user lacks edit permission but has assign_versions' do
let(:permissions) { all_permissions - [:edit_work_packages] + [:assign_versions] }
it_behaves_like 'has an untitled link' do
@@ -479,6 +479,20 @@ RSpec.describe API::V3::WorkPackages::WorkPackageRepresenter do
let(:href) { api_v3_paths.work_package(work_package.id) }
end
end
context 'when user lacks edit permission but has change_work_package_status' do
let(:permissions) { all_permissions - [:edit_work_packages] + [:change_work_package_status] }
it_behaves_like 'has an untitled link' do
let(:link) { 'update' }
let(:href) { api_v3_paths.work_package_form(work_package.id) }
end
it_behaves_like 'has an untitled link' do
let(:link) { 'updateImmediately' }
let(:href) { api_v3_paths.work_package(work_package.id) }
end
end
end
describe 'status' do