Commit c8df8fec authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 095fe6ab ed63ca4b
import $ from 'jquery';
// bootstrap jQuery plugins
import 'bootstrap';
import 'bootstrap/js/dist/alert';
import 'bootstrap/js/dist/button';
import 'bootstrap/js/dist/collapse';
import 'bootstrap/js/dist/modal';
import 'bootstrap/js/dist/dropdown';
import 'bootstrap/js/dist/popover';
import 'bootstrap/js/dist/tooltip';
import 'bootstrap/js/dist/tab';
// custom jQuery functions
$.fn.extend({
......
......@@ -467,9 +467,7 @@ module ProjectsHelper
}
end
def can_view_operations_tab?(current_user, project)
return false unless project.feature_available?(:operations, current_user)
def view_operations_tab_ability
[
:metrics_dashboard,
:read_alert_management_alert,
......@@ -479,7 +477,13 @@ module ProjectsHelper
:read_cluster,
:read_feature_flag,
:read_terraform_state
].any? do |ability|
]
end
def can_view_operations_tab?(current_user, project)
return false unless project.feature_available?(:operations, current_user)
view_operations_tab_ability.any? do |ability|
can?(current_user, ability, project)
end
end
......
......@@ -726,6 +726,7 @@ class User < ApplicationRecord
u.name = 'GitLab Security Bot'
u.website_url = Gitlab::Routing.url_helpers.help_page_url('user/application_security/security_bot/index.md')
u.avatar = bot_avatar(image: 'security-bot.png')
u.confirmed_at = Time.zone.now
end
end
......
......@@ -25,6 +25,10 @@ class BasePolicy < DeclarativePolicy::Base
with_options scope: :user, score: 0
condition(:support_bot) { @user&.support_bot? }
desc "User is security bot"
with_options scope: :user, score: 0
condition(:security_bot) { @user&.security_bot? }
desc "User email is unconfirmed or user account is locked"
with_options scope: :user, score: 0
condition(:inactive) { @user&.confirmation_required_on_sign_in? || @user&.access_locked? }
......
......@@ -48,7 +48,7 @@ class GlobalPolicy < BasePolicy
prevent :use_slash_commands
end
rule { blocked | (internal & ~migration_bot) }.policy do
rule { blocked | (internal & ~migration_bot & ~security_bot) }.policy do
prevent :access_git
end
......
......@@ -75,3 +75,5 @@ class PipelineSerializer < BaseSerializer
]
end
end
PipelineSerializer.prepend_if_ee('EE::PipelineSerializer')
.well-confirmation.text-center.append-bottom-20
.well-confirmation.text-center.gl-mb-6
%h1.gl-mt-0
Almost there...
%p.lead.append-bottom-20
%p.lead.gl-mb-6
Please check your email to confirm your account
%hr
- if Gitlab::CurrentSettings.after_sign_up_text.present?
......@@ -9,6 +9,6 @@
= markdown_field(Gitlab::CurrentSettings, :after_sign_up_text)
%p.text-center
No confirmation email received? Please check your spam folder or
.append-bottom-20.prepend-top-20.text-center
.gl-mb-6.prepend-top-20.text-center
%a.btn.btn-lg.btn-success{ href: new_user_confirmation_path }
Request new confirmation email
......@@ -23,7 +23,7 @@
.form-group
= f.label :email, class: 'label-bold'
= f.email_field :email, value: @invite_email, class: 'form-control middle', data: { qa_selector: 'new_user_email_field' }, required: true, title: _('Please provide a valid email address.')
.form-group.append-bottom-20#password-strength
.form-group.gl-mb-5#password-strength
= f.label :password, class: 'label-bold'
= f.password_field :password, class: 'form-control bottom', data: { qa_selector: 'new_user_password_field' }, required: true, pattern: ".{#{@minimum_password_length},}", title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
%p.gl-field-hint.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
......
......@@ -4,7 +4,7 @@
= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post, class: 'gl-show-field-errors' }) do |f|
.devise-errors
= render "devise/shared/error_messages", resource: resource
.form-group.append-bottom-20
.form-group.gl-mb-6
= f.label :email
= f.email_field :email, class: 'form-control', autofocus: 'autofocus', autocapitalize: 'off', autocorrect: 'off', title: 'Please provide a valid email address.'
.clearfix
......
......@@ -262,6 +262,8 @@
%span
= _('Incidents')
= render_if_exists 'projects/sidebar/oncall_schedules'
- if project_nav_tab? :serverless
= nav_link(controller: :functions) do
= link_to project_serverless_functions_path(@project), title: _('Serverless') do
......
......@@ -362,6 +362,18 @@ module.exports = {
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default'],
Alert: 'exports-loader?Alert!bootstrap/js/dist/alert',
Button: 'exports-loader?Button!bootstrap/js/dist/button',
Carousel: 'exports-loader?Carousel!bootstrap/js/dist/carousel',
Collapse: 'exports-loader?Collapse!bootstrap/js/dist/collapse',
Dropdown: 'exports-loader?Dropdown!bootstrap/js/dist/dropdown',
Modal: 'exports-loader?Modal!bootstrap/js/dist/modal',
Popover: 'exports-loader?Popover!bootstrap/js/dist/popover',
Scrollspy: 'exports-loader?Scrollspy!bootstrap/js/dist/scrollspy',
Tab: 'exports-loader?Tab!bootstrap/js/dist/tab',
Tooltip: 'exports-loader?Tooltip!bootstrap/js/dist/tooltip',
Util: 'exports-loader?Util!bootstrap/js/dist/util',
}),
// if DLLs are enabled, detect whether the DLL exists and create it automatically if necessary
......
import $ from 'jquery';
import 'bootstrap/js/dist/modal';
import initEETrialBanner from 'ee/ee_trial_banner';
import trackNavbarEvents from 'ee/event_tracking/navbar';
import initNamespaceStorageLimitAlert from 'ee/namespace_storage_limit_alert';
......
<script>
import { GlEmptyState, GlButton } from '@gitlab/ui';
import { s__ } from '~/locale';
export const i18n = {
emptyState: {
title: s__('OnCallSchedules|Create on-call schedules in GitLab'),
description: s__('OnCallSchedules|Route alerts directly to specific members of your team'),
button: s__('OnCallSchedules|Add a schedule'),
},
};
export default {
i18n,
inject: ['emptyOncallSchedulesSvgPath'],
components: {
GlEmptyState,
GlButton,
},
methods: {
createSchedule() {},
},
};
</script>
<template>
<gl-empty-state
:title="$options.i18n.emptyState.title"
:description="$options.i18n.emptyState.description"
:svg-path="emptyOncallSchedulesSvgPath"
>
<template #actions>
<gl-button variant="info" @click="createSchedule">{{
$options.i18n.emptyState.button
}}</gl-button>
</template>
</gl-empty-state>
</template>
import Vue from 'vue';
import OnCallSchedulesWrapper from './components/oncall_schedules_wrapper.vue';
export default () => {
const el = document.querySelector('#js-oncall_schedule');
if (!el) return null;
const { emptyOncallSchedulesSvgPath } = el.dataset;
return new Vue({
el,
provide: {
emptyOncallSchedulesSvgPath,
},
render(createElement) {
return createElement(OnCallSchedulesWrapper);
},
});
};
import initOnCallScheduleManagement from 'ee/oncall_schedules';
initOnCallScheduleManagement();
# frozen_string_literal: true
module Projects
module IncidentManagement
class OncallSchedulesController < Projects::ApplicationController
before_action :authorize_read_incident_management_oncall_schedule!
feature_category :incident_management
def index
end
end
end
end
......@@ -17,6 +17,13 @@ module EE
super + %w(path_locks)
end
override :sidebar_operations_paths
def sidebar_operations_paths
super + %w[
oncall_schedules
]
end
override :get_project_nav_tabs
def get_project_nav_tabs(project, current_user)
nav_tabs = super
......@@ -43,6 +50,10 @@ module EE
nav_tabs << :requirements
end
if can?(current_user, :read_incident_management_oncall_schedule, project)
nav_tabs << :oncall_schedule
end
nav_tabs
end
......@@ -338,5 +349,12 @@ module EE
}
}
end
override :view_operations_tab_ability
def view_operations_tab_ability
super + [
:read_incident_management_oncall_schedule
]
end
end
end
# frozen_string_literal: true
module IncidentManagement
module OncallScheduleHelper
def oncall_schedule_data
{
'empty-oncall-schedules-svg-path' => image_path('illustrations/empty-state/empty-on-call.svg')
}
end
end
end
......@@ -3,6 +3,11 @@
class ProjectSecuritySetting < ApplicationRecord
self.primary_key = :project_id
# Note: Even if we store settings for all types of security scanning
# Currently, Auto-fix feature is available only for container_scanning and
# dependency_scanning features.
AVAILABLE_AUTO_FIX_TYPES = [:dependency_scanning, :container_scanning].freeze
belongs_to :project, inverse_of: :security_setting
def self.safe_find_or_create_for(project)
......@@ -10,4 +15,14 @@ class ProjectSecuritySetting < ApplicationRecord
rescue ActiveRecord::RecordNotUnique
retry
end
def auto_fix_enabled?
auto_fix_enabled_types.any?
end
def auto_fix_enabled_types
AVAILABLE_AUTO_FIX_TYPES.filter_map do |type|
type if public_send("auto_fix_#{type}") # rubocop:disable GitlabSecurity/PublicSend
end
end
end
......@@ -6,6 +6,9 @@ module EE
extend ::Gitlab::Utils::Override
prepended do
with_scope :subject
condition(:auto_fix_enabled) { @subject.security_setting&.auto_fix_enabled? }
with_scope :subject
condition(:repository_mirrors_enabled) { @subject.feature_available?(:repository_mirrors) }
......@@ -153,6 +156,12 @@ module EE
!@subject.feature_available?(:feature_flags_related_issues)
end
with_scope :subject
condition(:oncall_schedules_available) do
::Feature.enabled?(:oncall_schedules_mvc, @subject) &&
@subject.feature_available?(:oncall_schedules)
end
rule { visual_review_bot }.policy do
prevent :read_note
enable :create_note
......@@ -178,9 +187,10 @@ module EE
enable :read_deploy_board
enable :admin_epic_issue
enable :read_group_timelogs
enable :read_incident_management_oncall_schedule
end
rule { oncall_schedules_available & can?(:reporter_access) }.enable :read_incident_management_oncall_schedule
rule { can?(:developer_access) }.policy do
enable :admin_board
enable :read_vulnerability_feedback
......@@ -218,6 +228,12 @@ module EE
enable :admin_vulnerability_issue_link
end
rule { security_bot && auto_fix_enabled }.policy do
enable :push_code
enable :create_merge_request_from
enable :create_vulnerability_feedback
end
rule { issues_disabled & merge_requests_disabled }.policy do
prevent(*create_read_update_admin_destroy(:iteration))
end
......@@ -242,11 +258,12 @@ module EE
enable :modify_auto_fix_setting
enable :modify_merge_request_author_setting
enable :modify_merge_request_committer_setting
enable :admin_incident_management_oncall_schedule
end
rule { license_scanning_enabled & can?(:maintainer_access) }.enable :admin_software_license_policy
rule { oncall_schedules_available & can?(:maintainer_access) }.enable :admin_incident_management_oncall_schedule
rule { auditor }.policy do
enable :public_user_access
prevent :request_access
......@@ -365,6 +382,7 @@ module EE
def lookup_access_level!
return ::Gitlab::Access::NO_ACCESS if needs_new_sso_session?
return ::Gitlab::Access::NO_ACCESS if visual_review_bot?
return ::Gitlab::Access::REPORTER if security_bot? && auto_fix_enabled?
super
end
......
......@@ -7,6 +7,7 @@ module Vulnerabilities
condition(:issue) { @subject.for_issue? }
condition(:merge_request) { @subject.for_merge_request? }
condition(:dismissal) { @subject.for_dismissal? }
condition(:auto_fix_enabled) { @subject.project.security_setting&.auto_fix_enabled? }
rule { issue & ~can?(:create_issue) }.prevent :create_vulnerability_feedback
......@@ -14,6 +15,14 @@ module Vulnerabilities
merge_request & ~can?(:create_merge_request_in)
end.prevent :create_vulnerability_feedback
# Prevent Security bot from creating vulnerability feedback
# if auto-fix feature is disabled
rule do
merge_request &
security_bot &
~auto_fix_enabled
end.prevent :create_vulnerability_feedback
rule { ~dismissal }.prevent :destroy_vulnerability_feedback, :update_vulnerability_feedback
end
end
# frozen_string_literal: true
module EE
module PipelineSerializer
extend ActiveSupport::Concern
private
def preloaded_relations
relations = super
project_relation = relations.detect { |item| item.is_a?(Hash) }
project_relation[:project].push(:security_setting)
relations
end
end
end
- page_title _('On-call schedules')
#js-oncall_schedule{ data: oncall_schedule_data }
- return unless project_nav_tab? :oncall_schedule
= nav_link(controller: :oncall_schedules) do
= link_to project_incident_management_oncall_schedules_path(@project), title: _('On-call Schedules') do
%span
= _('On-call Schedules')
......@@ -120,6 +120,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
namespace :iterations do
resources :inherited, only: [:show], constraints: { id: /\d+/ }
end
namespace :incident_management, path: '' do
resources :oncall_schedules, only: [:index], path: 'oncall_schedules'
end
end
# End of the /-/ scope.
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::IncidentManagement::OncallSchedulesController do
let_it_be(:registered_user) { create(:user) }
let_it_be(:user_with_read_permissions) { create(:user) }
let_it_be(:user_with_admin_permissions) { create(:user) }
let_it_be(:project) { create(:project) }
let(:current_user) { user_with_admin_permissions }
describe 'GET #index' do
let(:request) do
get :index, params: { project_id: project.to_param, namespace_id: project.namespace.to_param }
end
before do
project.add_reporter(user_with_read_permissions)
project.add_maintainer(user_with_admin_permissions)
stub_licensed_features(oncall_schedules: true)
sign_in(current_user)
end
context 'with read permissions' do
let(:current_user) { user_with_read_permissions }
it 'renders index with 200 status code' do
request
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:index)
end
end
context 'with admin permissions' do
let(:current_user) { user_with_admin_permissions }
it 'renders index with 200 status code' do
request
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:index)
end
end
context 'unauthorized' do
let(:current_user) { registered_user }
it 'responds with 404' do
request
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'with feature flag off' do
before do
stub_feature_flags(oncall_schedules_mvc: false)
end
it 'responds with 404' do
request
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'with unavailable feature' do
before do
stub_licensed_features(oncall_schedules: false)
end
it 'responds with 404' do
request
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
import { shallowMount } from '@vue/test-utils';
import { GlEmptyState } from '@gitlab/ui';
import OnCallScheduleWrapper, {
i18n,
} from 'ee/oncall_schedules/components/oncall_schedules_wrapper.vue';
describe('AlertManagementEmptyState', () => {
let wrapper;
const emptyOncallSchedulesSvgPath = 'illustration/path.svg';
function mountComponent() {
wrapper = shallowMount(OnCallScheduleWrapper, {
provide: {
emptyOncallSchedulesSvgPath,
},
});
}
beforeEach(() => {
mountComponent();
});
afterEach(() => {
if (wrapper) {
wrapper.destroy();
wrapper = null;
}
});
const findEmptyState = () => wrapper.find(GlEmptyState);
describe('Empty state', () => {
it('shows empty state and passed correct attributes to it', () => {
expect(findEmptyState().exists()).toBe(true);
expect(findEmptyState().attributes('title')).toBe(i18n.emptyState.title);
expect(findEmptyState().attributes('description')).toBe(i18n.emptyState.description);
expect(findEmptyState().attributes('svgpath')).toBe(emptyOncallSchedulesSvgPath);
});
});
});
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe IncidentManagement::OncallScheduleHelper do
let_it_be(:project) { create(:project) }
describe '#oncall_schedule_data' do
subject(:data) { helper.oncall_schedule_data }
it 'returns on-call schedule data' do
is_expected.to eq(
'empty-oncall-schedules-svg-path' => helper.image_path('illustrations/empty-state/empty-on-call.svg')
)
end
end
end
......@@ -249,11 +249,12 @@ RSpec.describe ProjectsHelper do
using RSpec::Parameterized::TableSyntax
where(:ability, :nav_tabs) do
:read_dependencies | [:dependencies]
:read_feature_flag | [:operations]
:read_licenses | [:licenses]
:read_project_security_dashboard | [:security, :security_configuration]
:read_threat_monitoring | [:threat_monitoring]
:read_dependencies | [:dependencies]
:read_feature_flag | [:operations]
:read_licenses | [:licenses]
:read_project_security_dashboard | [:security, :security_configuration]
:read_threat_monitoring | [:threat_monitoring]
:read_incident_management_oncall_schedule | [:oncall_schedule]
end
with_them do
......@@ -352,4 +353,38 @@ RSpec.describe ProjectsHelper do
it { expect(helper.scheduled_for_deletion?(archived_project)).to be true }
end
end
describe '#can_view_operations_tab?' do
let_it_be(:user) { create(:user) }
before do
allow(helper).to receive(:current_user).and_return(user)
allow(helper).to receive(:can?).and_return(false)
end
subject { helper.send(:can_view_operations_tab?, user, project) }
where(:ability) do
[
:read_incident_management_oncall_schedule
]
end
with_them do
it 'includes operations tab' do
allow(helper).to receive(:can?).with(user, ability, project).and_return(true)
is_expected.to be(true)
end
context 'when operations feature is disabled' do
it 'does not include operations tab' do
allow(helper).to receive(:can?).with(user, ability, project).and_return(true)
project.project_feature.update_attribute(:operations_access_level, ProjectFeature::DISABLED)
is_expected.to be(false)
end
end
end
end
end
......@@ -32,4 +32,49 @@ RSpec.describe ProjectSecuritySetting do
end
end
end
describe '#auto_fix_enabled?' do
subject { setting.auto_fix_enabled? }
let_it_be(:setting) { build(:project_security_setting) }
context 'when auto fix is enabled for available feature' do
before do
setting.auto_fix_container_scanning = false
setting.auto_fix_dependency_scanning = true
end
it 'marks auto_fix as enabled' do
is_expected.to be_truthy
end
end
context 'when a auto_fix setting is disabled for available features' do
before do
setting.auto_fix_container_scanning = false
setting.auto_fix_dependency_scanning = false
setting.auto_fix_sast = false
end
it 'marks auto_fix as disabled' do
is_expected.to be_falsey
end
end
end
describe '#auto_fix_enabled_types' do
subject { setting.auto_fix_enabled_types }
let_it_be(:setting) { build(:project_security_setting) }
before do
setting.auto_fix_container_scanning = false
setting.auto_fix_dependency_scanning = true
setting.auto_fix_sast = true
end
it 'return status only for available types' do
is_expected.to eq([:dependency_scanning])
end
end
end
......@@ -9,6 +9,11 @@ RSpec.describe IncidentManagement::OncallSchedulePolicy do
subject(:policy) { described_class.new(user, oncall_schedule) }
before do
stub_licensed_features(oncall_schedules: true)
stub_feature_flags(oncall_schedules_mvc: project)
end
describe 'rules' do
it { is_expected.to be_disallowed :read_incident_management_oncall_schedule }
......
......@@ -527,6 +527,34 @@ RSpec.describe ProjectPolicy do
end
end
describe 'permissions for security bot' do
let_it_be(:current_user) { create(:user, :security_bot) }
let(:project) { private_project }
context 'when auto_fix feature is enabled' do
before do
build(:project_security_setting, project: project)
end
it { is_expected.to be_allowed(:reporter_access) }
it { is_expected.to be_allowed(:push_code) }
it { is_expected.to be_allowed(:create_merge_request_from) }
it { is_expected.to be_allowed(:create_vulnerability_feedback) }
it { is_expected.to be_allowed(:create_merge_request_in) }
it { is_expected.to be_allowed(:read_project) }
end
context 'when auto_fix feature is disabled' do
it { is_expected.to be_disallowed(:reporter_access) }
it { is_expected.to be_disallowed(:push_code) }
it { is_expected.to be_disallowed(:create_merge_request_from) }
it { is_expected.to be_disallowed(:create_vulnerability_feedback) }
it { is_expected.to be_disallowed(:create_merge_request_in) }
it { is_expected.to be_disallowed(:read_project) }
end
end
describe 'read_threat_monitoring' do
context 'when threat monitoring feature is available' do
before do
......@@ -1360,12 +1388,29 @@ RSpec.describe ProjectPolicy do
before do
enable_admin_mode!(current_user) if admin_mode
stub_licensed_features(oncall_schedules: true)
end
with_them do
let(:current_user) { public_send(role) }
it { is_expected.to(allowed ? be_allowed(policy) : be_disallowed(policy)) }
context 'with disabled feature flag' do
before do
stub_feature_flags(oncall_schedules_mvc: false)
end
it { is_expected.to(be_disallowed(policy)) }
end
context 'with unavailable license' do
before do
stub_licensed_features(oncall_schedules: false)
end
it { is_expected.to(be_disallowed(policy)) }
end
end
end
......@@ -1384,12 +1429,29 @@ RSpec.describe ProjectPolicy do
before do
enable_admin_mode!(current_user) if admin_mode
stub_licensed_features(oncall_schedules: true)
end
with_them do
let(:current_user) { public_send(role) }
it { is_expected.to(allowed ? be_allowed(policy) : be_disallowed(policy)) }
context 'with disabled feature flag' do
before do
stub_feature_flags(oncall_schedules_mvc: false)
end
it { is_expected.to(be_disallowed(policy)) }
end
context 'with unavailable license' do
before do
stub_licensed_features(oncall_schedules: false)
end
it { is_expected.to(be_disallowed(policy)) }
end
end
end
end
......
......@@ -71,6 +71,20 @@ RSpec.describe Vulnerabilities::FeedbackPolicy do
is_expected.to be_disallowed(:create_vulnerability_feedback)
end
end
context 'with security bot' do
let(:current_user) { create(:user, :security_bot) }
context 'when auto-fix is enabled' do
let!(:setting) { build(:project_security_setting, project: project) }
it { is_expected.to be_allowed(:create_vulnerability_feedback) }
end
context 'when auto-fix is disabled' do
it { is_expected.to be_disallowed(:create_vulnerability_feedback) }
end
end
end
end
......
......@@ -18991,6 +18991,21 @@ msgstr ""
msgid "On track"
msgstr ""
msgid "On-call Schedules"
msgstr ""
msgid "On-call schedules"
msgstr ""
msgid "OnCallSchedules|Add a schedule"
msgstr ""
msgid "OnCallSchedules|Create on-call schedules in GitLab"
msgstr ""
msgid "OnCallSchedules|Route alerts directly to specific members of your team"
msgstr ""
msgid "OnDemandScans|Could not fetch scanner profiles. Please refresh the page, or try again later."
msgstr ""
......
......@@ -47,6 +47,10 @@ FactoryBot.define do
user_type { :migration_bot }
end
trait :security_bot do
user_type { :security_bot }
end
trait :external do
external { true }
end
......
......@@ -493,14 +493,18 @@ RSpec.describe ProjectsHelper do
subject { helper.send(:can_view_operations_tab?, user, project) }
[
:metrics_dashboard,
:read_alert_management_alert,
:read_environment,
:read_issue,
:read_sentry_issue,
:read_cluster
].each do |ability|
where(:ability) do
[
:metrics_dashboard,
:read_alert_management_alert,
:read_environment,
:read_issue,
:read_sentry_issue,
:read_cluster
]
end
with_them do
it 'includes operations tab' do
allow(helper).to receive(:can?).with(user, ability, project).and_return(true)
......
......@@ -7,6 +7,8 @@ RSpec.describe GlobalPolicy do
let_it_be(:project_bot) { create(:user, :project_bot) }
let_it_be(:migration_bot) { create(:user, :migration_bot) }
let_it_be(:security_bot) { create(:user, :security_bot) }
let(:current_user) { create(:user) }
let(:user) { create(:user) }
......@@ -205,6 +207,12 @@ RSpec.describe GlobalPolicy do
it { is_expected.not_to be_allowed(:access_api) }
end
context 'security bot' do
let(:current_user) { security_bot }
it { is_expected.not_to be_allowed(:access_api) }
end
context 'user blocked pending approval' do
before do
current_user.block_pending_approval
......@@ -335,6 +343,12 @@ RSpec.describe GlobalPolicy do
it { is_expected.to be_allowed(:access_git) }
end
context 'security bot' do
let(:current_user) { security_bot }
it { is_expected.to be_allowed(:access_git) }
end
describe 'deactivated user' do
before do
current_user.deactivate
......@@ -495,6 +509,12 @@ RSpec.describe GlobalPolicy do
it { is_expected.not_to be_allowed(:log_in) }
end
context 'security bot' do
let(:current_user) { security_bot }
it { is_expected.not_to be_allowed(:log_in) }
end
context 'user blocked pending approval' do
before do
current_user.block_pending_approval
......
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