1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
require 'spec_helper'
describe MergeRequestPolicy do
include ExternalAuthorizationServiceHelpers
let(:guest) { create(:user) }
let(:author) { create(:user) }
let(:developer) { create(:user) }
let(:non_team_member) { create(:user) }
let(:project) { create(:project, :public) }
def permissions(user, merge_request)
described_class.new(user, merge_request)
end
before do
project.add_guest(guest)
project.add_guest(author)
project.add_developer(developer)
end
MR_PERMS = %i[create_merge_request_in
create_merge_request_from
read_merge_request
create_note].freeze
shared_examples_for 'a denied user' do
let(:perms) { permissions(subject, merge_request) }
MR_PERMS.each do |thing|
it "cannot #{thing}" do
expect(perms).to be_disallowed(thing)
end
end
end
shared_examples_for 'a user with access' do
let(:perms) { permissions(subject, merge_request) }
MR_PERMS.each do |thing|
it "can #{thing}" do
expect(perms).to be_allowed(thing)
end
end
end
context 'when merge requests have been disabled' do
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: author) }
before do
project.project_feature.update(merge_requests_access_level: ProjectFeature::DISABLED)
end
describe 'the author' do
subject { author }
it_behaves_like 'a denied user'
end
describe 'a guest' do
subject { guest }
it_behaves_like 'a denied user'
end
describe 'a developer' do
subject { developer }
it_behaves_like 'a denied user'
end
describe 'any other user' do
subject { non_team_member }
it_behaves_like 'a denied user'
end
end
context 'when merge requests are private' do
let!(:merge_request) { create(:merge_request, source_project: project, target_project: project, author: author) }
before do
project.update(visibility_level: Gitlab::VisibilityLevel::PUBLIC)
project.project_feature.update(merge_requests_access_level: ProjectFeature::PRIVATE)
end
describe 'a non-team-member' do
subject { non_team_member }
it_behaves_like 'a denied user'
end
describe 'a developer' do
subject { developer }
it_behaves_like 'a user with access'
end
end
context 'when merge request is unlocked' do
let(:merge_request) { create(:merge_request, :closed, source_project: project, target_project: project, author: author) }
it 'allows author to reopen merge request' do
expect(permissions(author, merge_request)).to be_allowed(:reopen_merge_request)
end
it 'allows developer to reopen merge request' do
expect(permissions(developer, merge_request)).to be_allowed(:reopen_merge_request)
end
it 'prevents guest from reopening merge request' do
expect(permissions(guest, merge_request)).to be_disallowed(:reopen_merge_request)
end
end
context 'when merge request is locked' do
let(:merge_request_locked) { create(:merge_request, :closed, discussion_locked: true, source_project: project, target_project: project, author: author) }
it 'prevents author from reopening merge request' do
expect(permissions(author, merge_request_locked)).to be_disallowed(:reopen_merge_request)
end
it 'prevents developer from reopening merge request' do
expect(permissions(developer, merge_request_locked)).to be_disallowed(:reopen_merge_request)
end
it 'prevents guests from reopening merge request' do
expect(permissions(guest, merge_request_locked)).to be_disallowed(:reopen_merge_request)
end
context 'when the user is not a project member' do
let(:user) { create(:user) }
it 'cannot create a note' do
expect(permissions(user, merge_request_locked)).to be_disallowed(:create_note)
end
end
context 'when the user is project member, with at least guest access' do
let(:user) { guest }
it 'can create a note' do
expect(permissions(user, merge_request_locked)).to be_allowed(:create_note)
end
end
end
context 'with external authorization enabled' do
let(:user) { create(:user) }
let(:project) { create(:project, :public) }
let(:merge_request) { create(:merge_request, source_project: project) }
let(:policies) { described_class.new(user, merge_request) }
before do
enable_external_authorization_service_check
end
it 'can read the issue iid without accessing the external service' do
expect(::Gitlab::ExternalAuthorization).not_to receive(:access_allowed?)
expect(policies).to be_allowed(:read_merge_request_iid)
end
end
end
|