Commit 57f864fa authored by Peter Leitzen's avatar Peter Leitzen

Merge branch 'task_bot' into 'master'

Introduce Project bot user

See merge request gitlab-org/gitlab!28169
parents 37952697 fc7a89c4
...@@ -337,7 +337,8 @@ class User < ApplicationRecord ...@@ -337,7 +337,8 @@ class User < ApplicationRecord
scope :with_dashboard, -> (dashboard) { where(dashboard: dashboard) } scope :with_dashboard, -> (dashboard) { where(dashboard: dashboard) }
scope :with_public_profile, -> { where(private_profile: false) } scope :with_public_profile, -> { where(private_profile: false) }
scope :bots, -> { where(user_type: UserTypeEnums.bots.values) } scope :bots, -> { where(user_type: UserTypeEnums.bots.values) }
scope :not_bots, -> { humans.or(where.not(user_type: UserTypeEnums.bots.values)) } scope :bots_without_project_bot, -> { bots.where.not(user_type: UserTypeEnums.bots[:project_bot]) }
scope :with_project_bots, -> { humans.or(where.not(user_type: UserTypeEnums.bots.except(:project_bot).values)) }
scope :humans, -> { where(user_type: nil) } scope :humans, -> { where(user_type: nil) }
scope :with_expiring_and_not_notified_personal_access_tokens, ->(at) do scope :with_expiring_and_not_notified_personal_access_tokens, ->(at) do
...@@ -657,8 +658,10 @@ class User < ApplicationRecord ...@@ -657,8 +658,10 @@ class User < ApplicationRecord
UserTypeEnums.bots.has_key?(user_type) UserTypeEnums.bots.has_key?(user_type)
end end
# The explicit check for project_bot will be removed with Bot Categorization
# Ref: https://gitlab.com/gitlab-org/gitlab/-/issues/213945
def internal? def internal?
ghost? || bot? ghost? || (bot? && !project_bot?)
end end
# We are transitioning from ghost boolean column to user_type # We are transitioning from ghost boolean column to user_type
...@@ -668,12 +671,16 @@ class User < ApplicationRecord ...@@ -668,12 +671,16 @@ class User < ApplicationRecord
ghost ghost
end end
# The explicit check for project_bot will be removed with Bot Categorization
# Ref: https://gitlab.com/gitlab-org/gitlab/-/issues/213945
def self.internal def self.internal
where(ghost: true).or(bots) where(ghost: true).or(bots_without_project_bot)
end end
# The explicit check for project_bot will be removed with Bot Categorization
# Ref: https://gitlab.com/gitlab-org/gitlab/-/issues/213945
def self.non_internal def self.non_internal
without_ghosts.not_bots without_ghosts.with_project_bots
end end
# #
......
...@@ -6,7 +6,7 @@ module UserTypeEnums ...@@ -6,7 +6,7 @@ module UserTypeEnums
end end
def self.bots def self.bots
@bots ||= { alert_bot: 2 }.with_indifferent_access @bots ||= { alert_bot: 2, project_bot: 6 }.with_indifferent_access
end end
end end
......
...@@ -17,6 +17,8 @@ class GlobalPolicy < BasePolicy ...@@ -17,6 +17,8 @@ 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? }
rule { admin | (~private_instance_statistics & ~anonymous) } rule { admin | (~private_instance_statistics & ~anonymous) }
.enable :read_instance_statistics .enable :read_instance_statistics
...@@ -51,6 +53,11 @@ class GlobalPolicy < BasePolicy ...@@ -51,6 +53,11 @@ class GlobalPolicy < BasePolicy
prevent :use_slash_commands prevent :use_slash_commands
end end
rule { project_bot }.policy do
prevent :log_in
prevent :receive_notifications
end
rule { deactivated }.policy do rule { deactivated }.policy do
prevent :access_git prevent :access_git
prevent :access_api prevent :access_api
......
...@@ -262,6 +262,7 @@ module EE ...@@ -262,6 +262,7 @@ module EE
def using_license_seat? def using_license_seat?
active? && active? &&
!internal? && !internal? &&
!project_bot? &&
has_current_license? && has_current_license? &&
paid_in_current_license? paid_in_current_license?
end end
......
...@@ -27,6 +27,10 @@ FactoryBot.define do ...@@ -27,6 +27,10 @@ FactoryBot.define do
user_type { :alert_bot } user_type { :alert_bot }
end end
trait :project_bot do
user_type { :project_bot }
end
trait :external do trait :external do
external { true } external { true }
end end
......
...@@ -4357,18 +4357,19 @@ describe User, :do_not_mock_admin_mode do ...@@ -4357,18 +4357,19 @@ describe User, :do_not_mock_admin_mode do
describe 'internal methods' do describe 'internal methods' do
let_it_be(:user) { create(:user) } let_it_be(:user) { create(:user) }
let!(:ghost) { described_class.ghost } let_it_be(:ghost) { described_class.ghost }
let!(:alert_bot) { described_class.alert_bot } let_it_be(:alert_bot) { described_class.alert_bot }
let!(:non_internal) { [user] } let_it_be(:project_bot) { create(:user, :project_bot) }
let!(:internal) { [ghost, alert_bot] } let_it_be(:non_internal) { [user, project_bot] }
let_it_be(:internal) { [ghost, alert_bot] }
it 'returns internal users' do it 'returns internal users' do
expect(described_class.internal).to eq(internal) expect(described_class.internal).to match_array(internal)
expect(internal.all?(&:internal?)).to eq(true) expect(internal.all?(&:internal?)).to eq(true)
end end
it 'returns non internal users' do it 'returns non internal users' do
expect(described_class.non_internal).to eq(non_internal) expect(described_class.non_internal).to match_array(non_internal)
expect(non_internal.all?(&:internal?)).to eq(false) expect(non_internal.all?(&:internal?)).to eq(false)
end end
...@@ -4420,9 +4421,12 @@ describe User, :do_not_mock_admin_mode do ...@@ -4420,9 +4421,12 @@ describe User, :do_not_mock_admin_mode do
it 'returns corresponding users' do it 'returns corresponding users' do
human = create(:user) human = create(:user)
bot = create(:user, :bot) bot = create(:user, :bot)
project_bot = create(:user, :project_bot)
expect(described_class.humans).to match_array([human]) expect(described_class.humans).to match_array([human])
expect(described_class.bots).to match_array([bot]) expect(described_class.bots).to match_array([bot, project_bot])
expect(described_class.bots_without_project_bot).to match_array([bot])
expect(described_class.with_project_bots).to match_array([human, project_bot])
end end
end end
......
# frozen_string_literal: true
require 'spec_helper'
describe UserTypeEnums do
it '.types' do
expect(described_class.types.keys).to include('alert_bot', 'project_bot', 'human', 'ghost')
end
it '.bots' do
expect(described_class.bots.keys).to include('alert_bot', 'project_bot')
end
end
...@@ -5,6 +5,7 @@ require 'spec_helper' ...@@ -5,6 +5,7 @@ require 'spec_helper'
describe GlobalPolicy do describe GlobalPolicy do
include TermsHelper include TermsHelper
let_it_be(:project_bot) { create(:user, :project_bot) }
let(:current_user) { create(:user) } let(:current_user) { create(:user) }
let(:user) { create(:user) } let(:user) { create(:user) }
...@@ -120,6 +121,12 @@ describe GlobalPolicy do ...@@ -120,6 +121,12 @@ describe GlobalPolicy do
it { is_expected.to be_allowed(:access_api) } it { is_expected.to be_allowed(:access_api) }
end end
context 'project bot' do
let(:current_user) { project_bot }
it { is_expected.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
...@@ -203,6 +210,12 @@ describe GlobalPolicy do ...@@ -203,6 +210,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 'project bot' do
let(:current_user) { project_bot }
it { is_expected.not_to be_allowed(:receive_notifications) }
end
end end
describe 'git access' do describe 'git access' do
...@@ -265,6 +278,12 @@ describe GlobalPolicy do ...@@ -265,6 +278,12 @@ describe GlobalPolicy do
it { is_expected.to be_allowed(:access_git) } it { is_expected.to be_allowed(:access_git) }
end end
end end
context 'project bot' do
let(:current_user) { project_bot }
it { is_expected.to be_allowed(:access_git) }
end
end end
describe 'read instance metadata' do describe 'read instance metadata' do
...@@ -361,6 +380,12 @@ describe GlobalPolicy do ...@@ -361,6 +380,12 @@ describe GlobalPolicy do
it { is_expected.not_to be_allowed(:use_slash_commands) } it { is_expected.not_to be_allowed(:use_slash_commands) }
end end
context 'project bot' do
let(:current_user) { project_bot }
it { is_expected.to be_allowed(:use_slash_commands) }
end
end end
describe 'create_snippet' do describe 'create_snippet' do
...@@ -380,4 +405,12 @@ describe GlobalPolicy do ...@@ -380,4 +405,12 @@ describe GlobalPolicy do
it { is_expected.not_to be_allowed(:create_snippet) } it { is_expected.not_to be_allowed(:create_snippet) }
end end
end end
describe 'log in' do
context 'project bot' do
let(:current_user) { project_bot }
it { is_expected.not_to be_allowed(:log_in) }
end
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