Commit 8a8790ef authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Merge branch 'fj-add-migration-user' into 'master'

Add migration user

See merge request gitlab-org/gitlab!30738
parents 12ec2681 59463988
...@@ -10,10 +10,11 @@ module HasUserType ...@@ -10,10 +10,11 @@ module HasUserType
visual_review_bot: 3, visual_review_bot: 3,
service_user: 4, service_user: 4,
ghost: 5, ghost: 5,
project_bot: 6 project_bot: 6,
migration_bot: 7
}.with_indifferent_access.freeze }.with_indifferent_access.freeze
BOT_USER_TYPES = %w[alert_bot project_bot support_bot visual_review_bot].freeze BOT_USER_TYPES = %w[alert_bot project_bot support_bot visual_review_bot migration_bot].freeze
NON_INTERNAL_USER_TYPES = %w[human project_bot service_user].freeze NON_INTERNAL_USER_TYPES = %w[human project_bot service_user].freeze
INTERNAL_USER_TYPES = (USER_TYPES.keys - NON_INTERNAL_USER_TYPES).freeze INTERNAL_USER_TYPES = (USER_TYPES.keys - NON_INTERNAL_USER_TYPES).freeze
......
...@@ -636,6 +636,16 @@ class User < ApplicationRecord ...@@ -636,6 +636,16 @@ class User < ApplicationRecord
end end
end end
def migration_bot
email_pattern = "noreply+gitlab-migration-bot%s@#{Settings.gitlab.host}"
unique_internal(where(user_type: :migration_bot), 'migration-bot', email_pattern) do |u|
u.bio = 'The GitLab migration bot'
u.name = 'GitLab Migration Bot'
u.confirmed_at = Time.zone.now
end
end
# Return true if there is only single non-internal user in the deployment, # Return true if there is only single non-internal user in the deployment,
# ghost user is ignored. # ghost user is ignored.
def single_user? def single_user?
......
...@@ -18,6 +18,7 @@ class GlobalPolicy < BasePolicy ...@@ -18,6 +18,7 @@ class GlobalPolicy < BasePolicy
condition(:private_instance_statistics, score: 0) { Gitlab::CurrentSettings.instance_statistics_visibility_private? } condition(:private_instance_statistics, score: 0) { Gitlab::CurrentSettings.instance_statistics_visibility_private? }
condition(:project_bot, scope: :user) { @user&.project_bot? } condition(:project_bot, scope: :user) { @user&.project_bot? }
condition(:migration_bot, scope: :user) { @user&.migration_bot? }
rule { admin | (~private_instance_statistics & ~anonymous) } rule { admin | (~private_instance_statistics & ~anonymous) }
.enable :read_instance_statistics .enable :read_instance_statistics
...@@ -48,11 +49,14 @@ class GlobalPolicy < BasePolicy ...@@ -48,11 +49,14 @@ class GlobalPolicy < BasePolicy
rule { blocked | internal }.policy do rule { blocked | internal }.policy do
prevent :log_in prevent :log_in
prevent :access_api prevent :access_api
prevent :access_git
prevent :receive_notifications prevent :receive_notifications
prevent :use_slash_commands prevent :use_slash_commands
end end
rule { blocked | (internal & ~migration_bot) }.policy do
prevent :access_git
end
rule { project_bot }.policy do rule { project_bot }.policy do
prevent :log_in prevent :log_in
prevent :receive_notifications prevent :receive_notifications
......
---
title: Add migration bot user
merge_request: 30738
author:
type: added
...@@ -31,6 +31,10 @@ FactoryBot.define do ...@@ -31,6 +31,10 @@ FactoryBot.define do
user_type { :project_bot } user_type { :project_bot }
end end
trait :migration_bot do
user_type { :migration_bot }
end
trait :external do trait :external do
external { true } external { true }
end end
......
...@@ -4,8 +4,8 @@ require 'spec_helper' ...@@ -4,8 +4,8 @@ require 'spec_helper'
describe User do describe User do
specify 'types consistency checks', :aggregate_failures do specify 'types consistency checks', :aggregate_failures do
expect(described_class::USER_TYPES) expect(described_class::USER_TYPES.keys)
.to include(*%i[human ghost alert_bot project_bot support_bot service_user visual_review_bot]) .to match_array(%w[human ghost alert_bot project_bot support_bot service_user visual_review_bot migration_bot])
expect(described_class::USER_TYPES).to include(*described_class::BOT_USER_TYPES) expect(described_class::USER_TYPES).to include(*described_class::BOT_USER_TYPES)
expect(described_class::USER_TYPES).to include(*described_class::NON_INTERNAL_USER_TYPES) expect(described_class::USER_TYPES).to include(*described_class::NON_INTERNAL_USER_TYPES)
expect(described_class::USER_TYPES).to include(*described_class::INTERNAL_USER_TYPES) expect(described_class::USER_TYPES).to include(*described_class::INTERNAL_USER_TYPES)
......
...@@ -4584,4 +4584,20 @@ describe User, :do_not_mock_admin_mode do ...@@ -4584,4 +4584,20 @@ describe User, :do_not_mock_admin_mode do
it_behaves_like 'does not require password to be present' it_behaves_like 'does not require password to be present'
end end
end end
describe '#migration_bot' do
it 'creates the user if it does not exist' do
expect do
described_class.migration_bot
end.to change { User.where(user_type: :migration_bot).count }.by(1)
end
it 'does not create a new user if it already exists' do
described_class.migration_bot
expect do
described_class.migration_bot
end.not_to change { User.count }
end
end
end end
...@@ -6,6 +6,7 @@ describe GlobalPolicy do ...@@ -6,6 +6,7 @@ describe GlobalPolicy do
include TermsHelper include TermsHelper
let_it_be(:project_bot) { create(:user, :project_bot) } let_it_be(:project_bot) { create(:user, :project_bot) }
let_it_be(:migration_bot) { create(:user, :migration_bot) }
let(:current_user) { create(:user) } let(:current_user) { create(:user) }
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -155,6 +156,12 @@ describe GlobalPolicy do ...@@ -155,6 +156,12 @@ describe GlobalPolicy do
it { is_expected.to be_allowed(:access_api) } it { is_expected.to be_allowed(:access_api) }
end end
context 'migration bot' do
let(:current_user) { migration_bot }
it { is_expected.not_to be_allowed(:access_api) }
end
context 'when terms are enforced' do context 'when terms are enforced' do
before do before do
enforce_terms enforce_terms
...@@ -244,6 +251,12 @@ describe GlobalPolicy do ...@@ -244,6 +251,12 @@ describe GlobalPolicy do
it { is_expected.not_to be_allowed(:receive_notifications) } it { is_expected.not_to be_allowed(:receive_notifications) }
end end
context 'migration bot' do
let(:current_user) { migration_bot }
it { is_expected.not_to be_allowed(:receive_notifications) }
end
end end
describe 'git access' do describe 'git access' do
...@@ -263,6 +276,12 @@ describe GlobalPolicy do ...@@ -263,6 +276,12 @@ describe GlobalPolicy do
it { is_expected.to be_allowed(:access_git) } it { is_expected.to be_allowed(:access_git) }
end end
context 'migration bot' do
let(:current_user) { migration_bot }
it { is_expected.to be_allowed(:access_git) }
end
describe 'deactivated user' do describe 'deactivated user' do
before do before do
current_user.deactivate current_user.deactivate
...@@ -414,6 +433,12 @@ describe GlobalPolicy do ...@@ -414,6 +433,12 @@ describe GlobalPolicy do
it { is_expected.to be_allowed(:use_slash_commands) } it { is_expected.to be_allowed(:use_slash_commands) }
end end
context 'migration bot' do
let(:current_user) { migration_bot }
it { is_expected.not_to be_allowed(:use_slash_commands) }
end
end end
describe 'create_snippet' do describe 'create_snippet' do
...@@ -440,5 +465,11 @@ describe GlobalPolicy do ...@@ -440,5 +465,11 @@ describe GlobalPolicy do
it { is_expected.not_to be_allowed(:log_in) } it { is_expected.not_to be_allowed(:log_in) }
end end
context 'migration bot' do
let(:current_user) { migration_bot }
it { is_expected.not_to be_allowed(:log_in) }
end
end end
end end
...@@ -27,6 +27,16 @@ describe 'admin/users/_user.html.haml' do ...@@ -27,6 +27,16 @@ describe 'admin/users/_user.html.haml' do
expect(rendered).not_to have_selector('.table-action-buttons') expect(rendered).not_to have_selector('.table-action-buttons')
end end
end end
context 'when showing a `Migration User`' do
let(:user) { create(:user, user_type: :migration_bot) }
it 'does not render action buttons' do
render
expect(rendered).not_to have_selector('.table-action-buttons')
end
end
end end
context 'when showing an external user' do context 'when showing an external user' do
......
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