Commit 1eb7e79c authored by Max Woolf's avatar Max Woolf

Create compliance framework creation service

Adds a new service:

ComplianceManagement::Frameworks::CreateService to
GitLab EE.
parent c7c3323e
......@@ -133,6 +133,7 @@ class License < ApplicationRecord
container_scanning
coverage_fuzzing
credentials_inventory
custom_compliance_frameworks
dast
dependency_scanning
devops_adoption
......
......@@ -5,6 +5,7 @@ module EE
extend ActiveSupport::Concern
prepended do
condition(:custom_compliance_frameworks_enabled) { License.feature_available?(:custom_compliance_frameworks) }
condition(:over_storage_limit, scope: :subject) { @subject.over_storage_limit? }
rule { admin & is_gitlab_com }.enable :update_subscription_limit
......@@ -12,6 +13,10 @@ module EE
rule { over_storage_limit }.policy do
prevent :create_projects
end
rule { (owner | admin) & custom_compliance_frameworks_enabled }.policy do
enable :create_custom_compliance_frameworks
end
end
end
end
# frozen_string_literal: true
module ComplianceManagement
module Frameworks
class CreateService < BaseService
attr_reader :namespace, :params, :current_user, :framework
def initialize(namespace:, params:, current_user:)
@namespace = namespace.root_ancestor
@params = params
@current_user = current_user
@framework = ComplianceManagement::Framework.new
end
def execute
return ServiceResponse.error(message: _('Feature not available')) unless permitted?
framework.assign_attributes(
namespace: namespace,
name: params[:name],
description: params[:description],
color: params[:color]
)
framework.save ? success : error
end
private
def permitted?
can?(current_user, :create_custom_compliance_frameworks, namespace)
end
def success
ServiceResponse.success(payload: { framework: framework })
end
def error
ServiceResponse.error(message: _('Failed to create framework'), payload: framework.errors )
end
end
end
end
......@@ -23,6 +23,40 @@ RSpec.describe NamespacePolicy do
end
end
context 'custom_compliance_frameworks_enabled' do
let(:current_user) { owner }
context 'is licensed' do
before do
stub_licensed_features(custom_compliance_frameworks: true)
end
context 'current_user is namespace owner' do
it { is_expected.to be_allowed(:create_custom_compliance_frameworks) }
end
context 'current_user is not namespace owner' do
let(:current_user) { build_stubbed(:user) }
it { is_expected.to be_disallowed(:create_custom_compliance_frameworks) }
end
context 'current_user is administrator', :enable_admin_mode do
let(:current_user) { build_stubbed(:admin) }
it { is_expected.to be_allowed(:create_custom_compliance_frameworks) }
end
end
context 'not licensed' do
before do
stub_licensed_features(custom_compliance_frameworks: false)
end
it { is_expected.to be_disallowed(:create_custom_compliance_frameworks) }
end
end
context ':over_storage_limit' do
let(:current_user) { owner }
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ComplianceManagement::Frameworks::CreateService do
let_it_be(:namespace) { create(:namespace) }
let(:params) do
{
name: 'GDPR',
description: 'The EUs data protection directive',
color: '#abc123'
}
end
context 'custom_compliance_frameworks is disabled' do
before do
stub_licensed_features(custom_compliance_frameworks: false)
end
subject { described_class.new(namespace: namespace, params: params, current_user: namespace.owner) }
it 'does not create a new compliance framework' do
expect { subject.execute }.not_to change { ComplianceManagement::Framework.count }
end
it 'responds with an error message' do
expect(subject.execute.message).to eq('Feature not available')
end
end
context 'custom_compliance_frameworks is enabled' do
before do
stub_licensed_features(custom_compliance_frameworks: true)
end
context 'namespace has a parent' do
let_it_be(:namespace) { create(:namespace, :with_hierarchy) }
let(:descendant) { namespace.descendants.first }
subject { described_class.new(namespace: descendant, params: params, current_user: namespace.owner) }
it 'responds with a successful service response' do
expect(subject.execute.success?).to be true
end
it 'creates the new framework in the root namespace' do
expect(subject.execute.payload[:framework].namespace).to eq(namespace)
end
end
context 'when using invalid parameters' do
subject { described_class.new(namespace: namespace, params: params.except(:name), current_user: namespace.owner) }
let(:response) { subject.execute }
it 'responds with an error service response' do
expect(response.success?).to eq false
expect(response.payload.messages[:name]).to contain_exactly "can't be blank"
end
end
context 'when creating a compliance framework for a namespace that current_user is not the owner of' do
subject { described_class.new(namespace: namespace, params: params, current_user: create(:user)) }
it 'responds with an error service response' do
expect(subject.execute.success?).to be false
end
it 'does not create a new compliance framework' do
expect { subject.execute }.not_to change { ComplianceManagement::Framework.count }
end
end
context 'when using parameters for a valid compliance framework' do
subject { described_class.new(namespace: namespace, params: params, current_user: namespace.owner) }
it 'creates a new compliance framework' do
expect { subject.execute }.to change { ComplianceManagement::Framework.count }.by(1)
end
it 'responds with a successful service response' do
expect(subject.execute.success?).to be true
end
it 'has the expected attributes' do
framework = subject.execute.payload[:framework]
expect(framework.name).to eq('GDPR')
expect(framework.description).to eq('The EUs data protection directive')
expect(framework.color).to eq('#abc123')
end
end
end
end
......@@ -11288,6 +11288,9 @@ msgstr ""
msgid "Failed to create a branch for this issue. Please try again."
msgstr ""
msgid "Failed to create framework"
msgstr ""
msgid "Failed to create import label for jira import."
msgstr ""
......@@ -11513,6 +11516,9 @@ msgstr ""
msgid "Feature flag was successfully removed."
msgstr ""
msgid "Feature not available"
msgstr ""
msgid "FeatureFlags|%d user"
msgid_plural "FeatureFlags|%d users"
msgstr[0] ""
......
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