Skip to content
Snippets Groups Projects
Commit b69fdb6f authored by Joe Woodward's avatar Joe Woodward Committed by Joe Woodward
Browse files

Add new policy abilities for path locks

Introduces read_path_locks and create_path_locks to the project policy
and destroy_path_lock to the path lock policy.

Note: admin_path_locks is defined in the project policy and the
path_lock policy. Currently it is exposed in the graph API:

https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/graphql/ee/types/permission_types/project.rb

and also referenced in the path lock helper when checking if a user can
unlock a file:

https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/helpers/path_locks_helper.rb

We will retain the project policy ability to retain backwards
compatability in the API, however, in a future commit we will remove the
path lock policy ability and update the helper to reference
destroy_path_lock which is more descriptive.

Related to #512677
parent fb19e0ee
No related branches found
No related tags found
1 merge request!182573Add new policy abilities for path locks
......@@ -414,6 +414,10 @@ module ProjectPolicy
rule { oncall_schedules_available & can?(:reporter_access) }.enable :read_incident_management_oncall_schedule
rule { escalation_policies_available & can?(:reporter_access) }.enable :read_incident_management_escalation_policy
rule { can?(:read_code) }.policy do
enable :read_path_locks
end
rule { can?(:developer_access) }.policy do
enable :admin_issue_board
enable :admin_feature_flags_issue_links
......@@ -424,6 +428,10 @@ module ProjectPolicy
enable :read_security_settings
end
rule { can?(:push_code) }.policy do
enable :create_path_lock
end
rule { planner_or_reporter_access & iterations_available }.policy do
enable :create_iteration
enable :admin_iteration
......
......@@ -4,7 +4,8 @@ class PathLockPolicy < BasePolicy # rubocop:disable Gitlab/NamespacedClass
delegate { @subject.project }
condition(:is_author) { @user && @subject.user == @user }
condition(:is_project_member) { @subject.project&.member?(user) }
condition(:is_project_member) { @subject.project&.member?(@user) }
rule { is_author & is_project_member }.enable :admin_path_locks
rule { (is_author & is_project_member) }.enable :admin_path_locks
rule { (is_author & is_project_member) | can?(:admin_path_locks) }.enable :destroy_path_lock
end
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe PathLockPolicy do
RSpec.describe PathLockPolicy, feature_category: :source_code_management do
let(:project) { create(:project) }
let(:maintainer) { create(:user) }
let(:developer) { create(:user) }
......@@ -15,24 +15,41 @@
project.add_developer(developer)
end
def permissions(user, path_lock)
described_class.new(user, path_lock)
end
subject(:policy) { described_class.new(user, path_lock) }
it 'disallows non-member from administrating path lock they created' do
expect(permissions(non_member, non_member_path_lock)).to be_disallowed(:admin_path_locks)
end
context 'with a non-member' do
let(:user) { non_member }
context 'and a path lock they created' do
let(:path_lock) { non_member_path_lock }
it 'disallows developer from administrating path lock they did not create' do
expect(permissions(developer, non_member_path_lock)).to be_disallowed(:admin_path_locks)
it { is_expected.to be_disallowed(:destroy_path_lock) }
end
end
it 'allows developer to administrating path lock they created' do
expect(permissions(developer, developer_path_lock)).to be_allowed(:admin_path_locks)
context 'with a developer' do
let(:user) { developer }
context 'and a path lock they created' do
let(:path_lock) { developer_path_lock }
it { is_expected.to be_allowed(:destroy_path_lock) }
end
context 'and path lock they did not create' do
let(:path_lock) { non_member_path_lock }
it { is_expected.to be_disallowed(:destroy_path_lock) }
end
end
it 'allows maintainer to administrating path lock they did not create' do
expect(permissions(maintainer, non_member_path_lock)).to be_allowed(:admin_path_locks)
expect(permissions(maintainer, developer_path_lock)).to be_allowed(:admin_path_locks)
context 'with a maintainer' do
let(:user) { maintainer }
context 'and a path lock they did not create' do
let(:path_lock) { non_member_path_lock }
it { is_expected.to be_allowed(:destroy_path_lock) }
end
end
end
......@@ -26,7 +26,7 @@
context 'basic permissions' do
let(:additional_guest_permissions) { %i[read_limit_alert] }
let(:additional_reporter_permissions) do
%i[read_software_license_policy admin_value_stream read_product_analytics]
%i[read_software_license_policy admin_value_stream read_product_analytics read_path_locks]
end
let(:additional_developer_permissions) do
......@@ -34,7 +34,7 @@
admin_vulnerability_feedback read_project_audit_events read_project_security_dashboard
admin_vulnerability_issue_link admin_vulnerability_external_issue_link
read_security_resource read_vulnerability_scanner admin_vulnerability read_vulnerability
create_vulnerability_export read_merge_train
create_vulnerability_export read_merge_train create_path_locks
]
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment