Commit 70bb5adb authored by Bob Van Landuyt's avatar Bob Van Landuyt

Add abilities for designs

This enables creating, reading and destroying designs for anyone with
developer access and up.

It allows reading designs linked to issues that are readable to the
current user.
parent 3987423c
......@@ -12,3 +12,5 @@ module Types
end
end
end
Types::PermissionTypes::Issue.prepend(::EE::Types::PermissionTypes::Issue)
......@@ -20,3 +20,5 @@ module Types
end
end
end
Types::PermissionTypes::Project.prepend(EE::Types::PermissionTypes::Project)
......@@ -25,3 +25,5 @@ class IssuePolicy < IssuablePolicy
prevent :reopen_issue
end
end
IssuePolicy.prepend(::EE::IssuePolicy)
# frozen_string_literal: true
module EE
module Types
module PermissionTypes
module Issue
extend ActiveSupport::Concern
prepended do
abilities :read_design, :create_design, :destroy_design
end
end
end
end
end
# frozen_string_literal: true
module EE
module Types
module PermissionTypes
module Project
extend ActiveSupport::Concern
prepended do
abilities :read_design, :create_design, :destroy_design
end
end
end
end
end
......@@ -575,6 +575,13 @@ module EE
super.presence || build_feature_usage
end
def design_management_enabled?
# Checking both feature availability on the license, as well as the feature
# flag, because we don't want to enable design_management by default on
# on prem installs yet.
feature_available?(:design_management) && ::Feature.enabled?(:design_management)
end
private
def set_override_pull_mirror_available
......
# frozen_string_literal: true
module DesignManagement
class DesignPolicy < ::BasePolicy
# The IssuePolicy will delegate to the ProjectPolicy
delegate { @subject.issue }
end
end
# frozen_string_literal: true
module EE
module IssuePolicy
extend ActiveSupport::Concern
prepended do
rule { ~can?(:read_issue) }.policy do
prevent :read_design
prevent :create_design
prevent :destroy_design
end
end
end
end
......@@ -75,8 +75,17 @@ module EE
!@subject.feature_available?(:feature_flags)
end
with_scope :subject
condition(:design_management_disabled) do
!@subject.design_management_enabled?
end
rule { admin }.enable :change_repository_storage
rule { can?(:public_access) }.policy do
enable :read_design
end
rule { support_bot }.enable :guest_access
rule { support_bot & ~service_desk_enabled }.policy do
prevent :create_note
......@@ -114,6 +123,8 @@ module EE
enable :update_feature_flag
enable :destroy_feature_flag
enable :admin_feature_flag
enable :create_design
enable :destroy_design
end
rule { can?(:public_access) }.enable :read_package
......@@ -209,6 +220,14 @@ module EE
end
rule { web_ide_terminal_available & can?(:create_pipeline) & can?(:maintainer_access) }.enable :create_web_ide_terminal
# Design abilities could also be prevented in the issue policy.
# If the user cannot read the issue, then they cannot see the designs.
rule { design_management_disabled }.policy do
prevent :read_design
prevent :create_design
prevent :destroy_design
end
end
end
end
......
- if @project.feature_available?(:design_management, current_user) && Feature.enabled?(:design_management)
- if can?(current_user, :read_design, @issue)
%ul.nav-tabs.nav.nav-links{ role: 'tablist' }
%li
= link_to '#discussion-tab', class: 'active js-issue-tabs', id: 'discussion', role: 'tab', 'aria-controls': 'js-discussion', 'aria-selected': 'true', data: { toggle: 'tab', target: '#discussion-tab' } do
......
require 'spec_helper'
describe Types::PermissionTypes::Issue do
it "exposes design permissions" do
expected_permissions = [
:read_design, :create_design, :destroy_design
]
expected_permissions.each do |permission|
expect(described_class).to have_graphql_field(permission)
end
end
end
require 'spec_helper'
describe Types::PermissionTypes::Project do
it "exposes design permissions" do
expected_permissions = [
:read_design, :create_design, :destroy_design
]
expected_permissions.each do |permission|
expect(described_class).to have_graphql_field(permission)
end
end
end
......@@ -1767,6 +1767,27 @@ describe Project do
end
end
describe "#design_management_enabled?" do
let(:project) { build(:project) }
where(:feature_enabled, :license_enabled, :expected) do
false | false | false
false | true | false
true | false | false
true | true | true
end
with_them do
before do
stub_licensed_features(design_management: license_enabled)
stub_feature_flags(design_management: feature_enabled)
end
it "knows if design management is available" do
expect(project.design_management_enabled?).to be(expected)
end
end
end
# Despite stubbing the current node as the primary or secondary, the
# behaviour for EE::Project#lfs_http_url_to_repo() is to call
# Project#lfs_http_url_to_repo() which does not have a Geo context.
......
# frozen_string_literal: true
require 'spec_helper'
describe DesignManagement::DesignPolicy do
include_context 'ProjectPolicy context'
let(:guest_design_abilities) { %i[read_design] }
let(:developer_design_abilities) do
%i[create_design destroy_design]
end
let(:design_abilities) { guest_design_abilities + developer_design_abilities }
let(:issue) { create(:issue, project: project) }
let(:design) { create(:design, issue: issue) }
subject { described_class.new(current_user, design) }
shared_examples_for "design abilities not available" do
context "for owners" do
let(:current_user) { owner }
it { is_expected.to be_disallowed(*design_abilities) }
end
context "for admins" do
let(:current_user) { admin }
it { is_expected.to be_disallowed(*design_abilities) }
end
context "for maintainers" do
let(:current_user) { maintainer }
it { is_expected.to be_disallowed(*design_abilities) }
end
context "for developers" do
let(:current_user) { developer }
it { is_expected.to be_disallowed(*design_abilities) }
end
context "for reporters" do
let(:current_user) { reporter }
it { is_expected.to be_disallowed(*design_abilities) }
end
context "for guests" do
let(:current_user) { guest }
it { is_expected.to be_disallowed(*design_abilities) }
end
context "for anonymous users" do
let(:current_user) { nil }
it { is_expected.to be_disallowed(*design_abilities) }
end
end
shared_examples_for "design abilities available for members" do
context "for owners" do
let(:current_user) { owner }
it { is_expected.to be_allowed(*design_abilities) }
end
context "for admins" do
let(:current_user) { admin }
it { is_expected.to be_allowed(*design_abilities) }
end
context "for maintainers" do
let(:current_user) { maintainer }
it { is_expected.to be_allowed(*design_abilities) }
end
context "for developers" do
let(:current_user) { developer }
it { is_expected.to be_allowed(*design_abilities) }
end
context "for reporters" do
let(:current_user) { reporter }
it { is_expected.to be_allowed(*guest_design_abilities) }
it { is_expected.to be_disallowed(*developer_design_abilities) }
end
end
context "when the feature flag is off" do
before do
stub_licensed_features(design_management: true)
stub_feature_flags(design_management: false)
end
it_behaves_like "design abilities not available"
end
context "when the license does not include the feature" do
before do
stub_licensed_features(design_management: false)
stub_feature_flags(design_management: true)
end
it_behaves_like "design abilities not available"
end
context "when the feature is available" do
before do
stub_licensed_features(design_management: true)
stub_feature_flags(design_management: true)
end
it_behaves_like "design abilities available for members"
context "for guests" do
let(:current_user) { guest }
it { is_expected.to be_allowed(*guest_design_abilities) }
it { is_expected.to be_disallowed(*developer_design_abilities) }
end
context "for anonymous users" do
let(:current_user) { nil }
it { is_expected.to be_allowed(*guest_design_abilities) }
it { is_expected.to be_disallowed(*developer_design_abilities) }
end
context "when the issue is confidential" do
let(:issue) { create(:issue, :confidential, project: project) }
it_behaves_like "design abilities available for members"
context "for guests" do
let(:current_user) { guest }
it { is_expected.to be_disallowed(*design_abilities) }
end
context "for anonymous users" do
let(:current_user) { nil }
it { is_expected.to be_disallowed(*design_abilities)}
end
end
end
end
......@@ -13,6 +13,8 @@ describe Types::PermissionTypes::Project do
:update_wiki, :destroy_wiki, :create_pages, :destroy_pages, :read_pages_content
]
expect(described_class).to have_graphql_fields(expected_permissions)
expected_permissions.each do |permission|
expect(described_class).to have_graphql_field(permission)
end
end
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