Commit b94f9c91 authored by Stan Hu's avatar Stan Hu

Merge branch '300100_allow_guests_to_define_metadata_on_issue_create' into 'master'

Allow guest user to assign issue metadata on issue create

See merge request gitlab-org/gitlab!62816
parents 2f550f60 ae50169e
......@@ -15,6 +15,9 @@ class IssuePolicy < IssuablePolicy
desc "Issue is confidential"
condition(:confidential, scope: :subject) { @subject.confidential? }
desc "Issue is persisted"
condition(:persisted, scope: :subject) { @subject.persisted? }
rule { confidential & ~can_read_confidential }.policy do
prevent(*create_read_update_admin_destroy(:issue))
prevent :read_issue_iid
......@@ -40,6 +43,14 @@ class IssuePolicy < IssuablePolicy
enable :create_todo
enable :update_subscription
end
rule { ~persisted & can?(:guest_access) }.policy do
enable :set_issue_metadata
end
rule { persisted & can?(:admin_issue) }.policy do
enable :set_issue_metadata
end
end
IssuePolicy.prepend_mod_with('IssuePolicy')
......@@ -28,6 +28,10 @@ class MergeRequestPolicy < IssuablePolicy
rule { can_merge }.policy do
enable :accept_merge_request
end
rule { can?(:admin_merge_request) }.policy do
enable :set_merge_request_metadata
end
end
MergeRequestPolicy.prepend_mod_with('MergeRequestPolicy')
......@@ -27,8 +27,14 @@ class IssuableBaseService < ::BaseProjectService
can?(current_user, ability_name, issuable)
end
def can_set_issuable_metadata?(issuable)
ability_name = :"set_#{issuable.to_ability_name}_metadata"
can?(current_user, ability_name, issuable)
end
def filter_params(issuable)
unless can_admin_issuable?(issuable)
unless can_set_issuable_metadata?(issuable)
params.delete(:milestone)
params.delete(:milestone_id)
params.delete(:labels)
......@@ -45,6 +51,7 @@ class IssuableBaseService < ::BaseProjectService
params.delete(:canonical_issue_id)
params.delete(:project)
params.delete(:discussion_locked)
params.delete(:confidential)
end
filter_assignees(issuable)
......
......@@ -20,17 +20,6 @@ module Issues
super
end
override :filter_params
def filter_params(issue)
super
# filter confidential in `Issues::UpdateService` and not in `IssuableBaseService#filter_params`
# because we do allow users that cannot admin issues to set confidential flag when creating an issue
unless can_admin_issuable?(issue)
params.delete(:confidential)
end
end
def before_update(issue, skip_spam_check: false)
return if skip_spam_check
......
......@@ -24,14 +24,6 @@
= render 'shared/form_elements/description', model: issuable, form: form, project: project
- if issuable.respond_to?(:confidential)
.form-group.row
.offset-sm-2.col-sm-10
.form-check
= form.check_box :confidential, class: 'form-check-input'
= form.label :confidential, class: 'form-check-label' do
This issue is confidential and should only be visible to team members with at least Reporter access.
= render 'shared/issuable/form/metadata', issuable: issuable, form: form, project: project, presenter: presenter
= render_if_exists 'shared/issuable/approvals', issuable: issuable, presenter: presenter, form: form
......
......@@ -2,11 +2,19 @@
- issuable = local_assigns.fetch(:issuable)
- presenter = local_assigns.fetch(:presenter)
- return unless can?(current_user, :"admin_#{issuable.to_ability_name}", issuable.project)
- return unless can?(current_user, :"set_#{issuable.to_ability_name}_metadata", issuable)
- has_due_date = issuable.has_attribute?(:due_date)
- form = local_assigns.fetch(:form)
- if issuable.respond_to?(:confidential)
.form-group.row
.offset-sm-2.col-sm-10
.form-check
= form.check_box :confidential, class: 'form-check-input'
= form.label :confidential, class: 'form-check-label' do
This issue is confidential and should only be visible to team members with at least Reporter access.
%hr
.row
%div{ class: (has_due_date ? "col-lg-6" : "col-12") }
......
......@@ -35,4 +35,8 @@ class EpicPolicy < BasePolicy
rule { ~anonymous & can?(:read_epic) }.policy do
enable :create_todo
end
rule { can?(:admin_epic) }.policy do
enable :set_epic_metadata
end
end
......@@ -12,6 +12,11 @@ RSpec.describe Epics::CreateService do
subject { described_class.new(group: group, current_user: user, params: params).execute }
describe '#execute' do
before do
group.add_reporter(user)
stub_licensed_features(epics: true, subepics: true)
end
it 'creates one epic correctly' do
allow(NewEpicWorker).to receive(:perform_async)
......@@ -26,7 +31,6 @@ RSpec.describe Epics::CreateService do
expect(epic.confidential).to be_truthy
expect(NewEpicWorker).to have_received(:perform_async).with(epic.id, user.id)
end
end
context 'handling fixed dates' do
it 'sets the fixed date correctly' do
......@@ -85,11 +89,6 @@ RSpec.describe Epics::CreateService do
end
context 'when description param has quick action' do
before do
stub_licensed_features(epics: true, subepics: true)
group.add_developer(user)
end
context 'for /parent_epic' do
it 'assigns parent epic' do
parent_epic = create(:epic, group: group)
......@@ -142,4 +141,5 @@ RSpec.describe Epics::CreateService do
end
end
end
end
end
......@@ -30,7 +30,7 @@ RSpec.describe "User creates issue" do
end
end
context "when signed in as guest" do
context "when signed in as guest", :js do
before do
project.add_guest(user)
sign_in(user)
......@@ -38,43 +38,21 @@ RSpec.describe "User creates issue" do
visit(new_project_issue_path(project))
end
it "creates issue", :js do
context 'available metadata' do
it 'allows guest to set issue metadata' do
page.within(".issue-form") do
expect(page).to have_no_content("Assign to")
.and have_no_content("Labels")
.and have_no_content("Milestone")
expect(page.find('#issue_title')['placeholder']).to eq 'Title'
expect(page.find('#issue_description')['placeholder']).to eq 'Write a description or drag your files here…'
expect(page).to have_content("Title")
.and have_content("Description")
.and have_content("Type")
.and have_content("Assignee")
.and have_content("Milestone")
.and have_content("Labels")
.and have_content("Due date")
.and have_content("This issue is confidential and should only be visible to team members with at least Reporter access.")
end
issue_title = "500 error on profile"
fill_in("Title", with: issue_title)
first('.js-md').click
first('.rspec-issuable-form-description').native.send_keys('Description')
click_button("Create issue")
expect(page).to have_content(issue_title)
.and have_content(user.name)
.and have_content(project.name)
expect(page).to have_selector('strong', text: 'Description')
end
it 'does not render the issue type dropdown' do
expect(page).not_to have_selector('.s-issuable-type-filter-dropdown-wrap')
end
end
context "when signed in as developer", :js do
before do
project.add_developer(user)
sign_in(user)
visit(new_project_issue_path(project))
end
context "when previewing" do
it "previews content" do
form = first(".gfm-form")
......
This diff is collapsed.
......@@ -18,8 +18,8 @@ RSpec.describe Issues::CreateService do
let_it_be(:labels) { create_pair(:label, project: project) }
before_all do
project.add_maintainer(user)
project.add_maintainer(assignee)
project.add_guest(user)
project.add_guest(assignee)
end
let(:opts) do
......@@ -88,15 +88,11 @@ RSpec.describe Issues::CreateService do
expect { issue }.to change { project.open_issues_count }.from(0).to(1)
end
context 'when current user cannot admin issues in the project' do
let_it_be(:guest) { create(:user) }
before_all do
project.add_guest(guest)
end
context 'when current user cannot set issue metadata in the project' do
let_it_be(:non_member) { create(:user) }
it 'filters out params that cannot be set without the :admin_issue permission' do
issue = described_class.new(project: project, current_user: guest, params: opts).execute
it 'filters out params that cannot be set without the :set_issue_metadata permission' do
issue = described_class.new(project: project, current_user: non_member, params: opts).execute
expect(issue).to be_persisted
expect(issue.title).to eq('Awesome issue')
......@@ -107,8 +103,8 @@ RSpec.describe Issues::CreateService do
expect(issue.due_date).to be_nil
end
it 'creates confidential issues' do
issue = described_class.new(project: project, current_user: guest, params: { confidential: true }).execute
it 'can create confidential issues' do
issue = described_class.new(project: project, current_user: non_member, params: { confidential: true }).execute
expect(issue.confidential).to be_truthy
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment