Commit c9a3e0d4 authored by Subashis's avatar Subashis

Auditor can see and add projects

- Add the ability to pass membership param from frontend
- Adds new policy for add project to accomodate auditor
- Adds and update specs
- Adds change log
parent 42c050db
......@@ -19,6 +19,12 @@ export default {
ProjectList,
ProjectSelector,
},
props: {
isAuditor: {
type: Boolean,
required: true,
},
},
data() {
return {
searchQuery: '',
......@@ -217,6 +223,7 @@ export default {
after: pageInfo.endCursor,
searchNamespaces: true,
sort: 'similarity',
membership: !this.isAuditor,
},
});
},
......
......@@ -7,12 +7,13 @@ query getProjects(
$first: Int!
$searchNamespaces: Boolean = false
$sort: String
$membership: Boolean = true
) {
projects(
search: $search
after: $after
first: $first
membership: true
membership: $membership
searchNamespaces: $searchNamespaces
sort: $sort
) {
......
import Vue from 'vue';
import { parseBoolean } from '~/lib/utils/common_utils';
import ProjectManager from './components/first_class_project_manager/project_manager.vue';
import apolloProvider from './graphql/provider';
......@@ -7,11 +8,17 @@ export default (el) => {
return null;
}
const { isAuditor } = el.dataset;
return new Vue({
el,
apolloProvider,
render(createElement) {
return createElement(ProjectManager);
return createElement(ProjectManager, {
props: {
isAuditor: parseBoolean(isAuditor),
},
});
},
});
};
......@@ -5,7 +5,7 @@ module Mutations
class AddProject < BaseMutation
graphql_name 'AddProjectToSecurityDashboard'
authorize :developer_access
authorize :add_project_to_instance_security_dashboard
field :project, Types::ProjectType,
null: true,
......
......@@ -23,4 +23,10 @@ module SecurityHelper
is_unavailable: "true"
}
end
def instance_security_settings_data
{
is_auditor: current_user.auditor?.to_s
}
end
end
......@@ -370,6 +370,8 @@ module EE
prevent(*create_update_admin(feature))
end
end
rule { auditor | can?(:developer_access) }.enable :add_project_to_instance_security_dashboard
end
override :lookup_access_level!
......
- page_title _('Settings')
#js-security
#js-security{ data: instance_security_settings_data }
---
title: "“Security Center project selector returns projects and gives the ability to
add project for Auditor user”"
merge_request: 58841
author:
type: added
......@@ -32,6 +32,10 @@ describe('Project Manager component', () => {
},
};
const defaultProps = {
isAuditor: false,
};
const createWrapper = ({ data = {}, mocks = {}, props = {} }) => {
spyQuery = defaultMocks.$apollo.query;
spyMutate = defaultMocks.$apollo.mutate;
......@@ -40,7 +44,7 @@ describe('Project Manager component', () => {
return { ...data };
},
mocks: { ...defaultMocks, ...mocks },
propsData: props,
propsData: { ...defaultProps, ...props },
});
};
......@@ -83,6 +87,7 @@ describe('Project Manager component', () => {
after: '',
searchNamespaces: true,
sort: 'similarity',
membership: true,
},
});
});
......@@ -217,4 +222,18 @@ describe('Project Manager component', () => {
expect(spyQuery).not.toHaveBeenCalled();
});
});
describe('membership prop', () => {
it.each([true, false])('calls the expected query when membership prop is $s', (isAuditor) => {
createWrapper({ props: { isAuditor } });
findProjectSelector().vm.$emit('searched', 'test');
expect(spyQuery).toHaveBeenCalledTimes(1);
expect(spyQuery).toHaveBeenCalledWith(
expect.objectContaining({
variables: expect.objectContaining({ membership: !isAuditor }),
}),
);
});
});
});
......@@ -64,7 +64,18 @@ RSpec.describe Mutations::InstanceSecurityDashboard::AddProject do
end
end
context 'when project is not available to the user' do
context 'when user is auditor and project is not available to the user explicitly' do
let(:selected_project) { project }
let(:current_user) { create(:user, :auditor) }
it 'adds project to the security dashboard', :aggregate_failures do
expect(subject[:project]).to eq(project)
expect(subject[:errors]).to be_empty
expect(current_user.security_dashboard_projects).to include(project)
end
end
context 'when project is not available to the user and user is not auditor' do
let(:selected_project) { project }
it 'raises Gitlab::Graphql::Errors::ResourceNotAvailable error' do
......
......@@ -23,4 +23,20 @@ RSpec.describe SecurityHelper do
})
end
end
describe '#instance_security_settings_data' do
subject { instance_security_settings_data }
context 'when user is not auditor' do
let_it_be(:current_user) { create(:user) }
it { is_expected.to eq({ is_auditor: "false" }) }
end
context 'when user is auditor' do
let_it_be(:current_user) { create(:user, :auditor) }
it { is_expected.to eq({ is_auditor: "true" }) }
end
end
end
......@@ -1102,6 +1102,30 @@ RSpec.describe ProjectPolicy do
end
end
describe 'add_project_to_instance_security_dashboard' do
let(:policy) { :add_project_to_instance_security_dashboard }
context 'when user is auditor' do
let(:current_user) { create(:user, :auditor) }
it { is_expected.to be_allowed(policy) }
end
context 'when user is not auditor' do
context 'with developer access' do
let(:current_user) { developer }
it { is_expected.to be_allowed(policy) }
end
context 'without developer access' do
let(:current_user) { create(:user) }
it { is_expected.to be_disallowed(policy) }
end
end
end
context 'visual review bot' do
let(:current_user) { User.visual_review_bot }
......
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