Commit ee979be5 authored by Imre Farkas's avatar Imre Farkas

Merge branch '257878-introduce-blocked-pending-approval-user-status' into 'master'

Introduce `blocked_pending_approval` user state

See merge request gitlab-org/gitlab!44260
parents 10d63c75 81556f2f
...@@ -304,13 +304,18 @@ class User < ApplicationRecord ...@@ -304,13 +304,18 @@ class User < ApplicationRecord
transition deactivated: :active transition deactivated: :active
transition blocked: :active transition blocked: :active
transition ldap_blocked: :active transition ldap_blocked: :active
transition blocked_pending_approval: :active
end
event :block_pending_approval do
transition active: :blocked_pending_approval
end end
event :deactivate do event :deactivate do
transition active: :deactivated transition active: :deactivated
end end
state :blocked, :ldap_blocked do state :blocked, :ldap_blocked, :blocked_pending_approval do
def blocked? def blocked?
true true
end end
...@@ -333,7 +338,7 @@ class User < ApplicationRecord ...@@ -333,7 +338,7 @@ class User < ApplicationRecord
# Scopes # Scopes
scope :admins, -> { where(admin: true) } scope :admins, -> { where(admin: true) }
scope :blocked, -> { with_states(:blocked, :ldap_blocked) } scope :blocked, -> { with_states(:blocked, :ldap_blocked, :blocked_pending_approval) }
scope :external, -> { where(external: true) } scope :external, -> { where(external: true) }
scope :confirmed, -> { where.not(confirmed_at: nil) } scope :confirmed, -> { where.not(confirmed_at: nil) }
scope :active, -> { with_state(:active).non_internal } scope :active, -> { with_state(:active).non_internal }
...@@ -378,7 +383,9 @@ class User < ApplicationRecord ...@@ -378,7 +383,9 @@ class User < ApplicationRecord
# The messages for these keys are defined in `devise.en.yml` # The messages for these keys are defined in `devise.en.yml`
def inactive_message def inactive_message
if blocked? if blocked_pending_approval?
:blocked_pending_approval
elsif blocked?
:blocked :blocked
elsif internal? elsif internal?
:forbidden :forbidden
......
...@@ -18,6 +18,7 @@ en: ...@@ -18,6 +18,7 @@ en:
unconfirmed: "You have to confirm your email address before continuing. Please check your email for the link we sent you, or click 'Resend confirmation email'." unconfirmed: "You have to confirm your email address before continuing. Please check your email for the link we sent you, or click 'Resend confirmation email'."
blocked: "Your account has been blocked. Please contact your GitLab administrator if you think this is an error." blocked: "Your account has been blocked. Please contact your GitLab administrator if you think this is an error."
forbidden: "Your account does not have the required permission to login. Please contact your GitLab administrator if you think this is an error." forbidden: "Your account does not have the required permission to login. Please contact your GitLab administrator if you think this is an error."
blocked_pending_approval: "Your account is pending approval from your GitLab administrator and hence blocked. Please contact your GitLab administrator if you think this is an error."
mailer: mailer:
confirmation_instructions: confirmation_instructions:
subject: "Confirmation instructions" subject: "Confirmation instructions"
......
...@@ -11,6 +11,8 @@ module Gitlab ...@@ -11,6 +11,8 @@ module Gitlab
case rejection_type case rejection_type
when :internal when :internal
"This action cannot be performed by internal users" "This action cannot be performed by internal users"
when :blocked_pending_approval
"Your account is pending approval from your administrator and hence blocked."
when :terms_not_accepted when :terms_not_accepted
"You (#{@user.to_reference}) must accept the Terms of Service in order to perform this action. "\ "You (#{@user.to_reference}) must accept the Terms of Service in order to perform this action. "\
"Please access GitLab from a web browser to accept these terms." "Please access GitLab from a web browser to accept these terms."
...@@ -31,6 +33,8 @@ module Gitlab ...@@ -31,6 +33,8 @@ module Gitlab
def rejection_type def rejection_type
if @user.internal? if @user.internal?
:internal :internal
elsif @user.blocked_pending_approval?
:blocked_pending_approval
elsif @user.required_terms_not_accepted? elsif @user.required_terms_not_accepted?
:terms_not_accepted :terms_not_accepted
elsif @user.deactivated? elsif @user.deactivated?
......
...@@ -100,6 +100,16 @@ RSpec.describe SessionsController do ...@@ -100,6 +100,16 @@ RSpec.describe SessionsController do
end end
end end
context 'a `blocked pending approval` user' do
it 'does not authenticate the user' do
user.block_pending_approval!
post_action
expect(@request.env['warden']).not_to be_authenticated
expect(flash[:alert]).to include('Your account is pending approval from your GitLab administrator and hence blocked')
end
end
context 'an internal user' do context 'an internal user' do
it 'does not authenticate the user' do it 'does not authenticate the user' do
user.ghost! user.ghost!
......
...@@ -23,6 +23,14 @@ FactoryBot.define do ...@@ -23,6 +23,14 @@ FactoryBot.define do
after(:build) { |user, _| user.block! } after(:build) { |user, _| user.block! }
end end
trait :blocked_pending_approval do
after(:build) { |user, _| user.block_pending_approval! }
end
trait :ldap_blocked do
after(:build) { |user, _| user.ldap_block! }
end
trait :bot do trait :bot do
user_type { :alert_bot } user_type { :alert_bot }
end end
......
...@@ -49,5 +49,13 @@ RSpec.describe Gitlab::Auth::UserAccessDeniedReason do ...@@ -49,5 +49,13 @@ RSpec.describe Gitlab::Auth::UserAccessDeniedReason do
it { is_expected.to match /Your primary email address is not confirmed/ } it { is_expected.to match /Your primary email address is not confirmed/ }
end end
context 'when the user is blocked pending approval' do
before do
user.block_pending_approval!
end
it { is_expected.to eq('Your account is pending approval from your administrator and hence blocked.') }
end
end end
end end
...@@ -726,6 +726,12 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do ...@@ -726,6 +726,12 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do
expect( gl_auth.find_with_user_password(username, password) ).not_to eql user expect( gl_auth.find_with_user_password(username, password) ).not_to eql user
end end
it 'does not find user in blocked_pending_approval state' do
user.block_pending_approval
expect( gl_auth.find_with_user_password(username, password) ).not_to eql user
end
context 'with increment_failed_attempts' do context 'with increment_failed_attempts' do
wrong_password = 'incorrect_password' wrong_password = 'incorrect_password'
......
...@@ -420,6 +420,13 @@ RSpec.describe Gitlab::GitAccess do ...@@ -420,6 +420,13 @@ RSpec.describe Gitlab::GitAccess do
expect { pull_access_check }.to raise_forbidden('Your account has been blocked.') expect { pull_access_check }.to raise_forbidden('Your account has been blocked.')
end end
it 'disallows users that are blocked pending approval to pull' do
project.add_maintainer(user)
user.block_pending_approval
expect { pull_access_check }.to raise_forbidden('Your account is pending approval from your administrator and hence blocked.')
end
it 'disallows deactivated users to pull' do it 'disallows deactivated users to pull' do
project.add_maintainer(user) project.add_maintainer(user)
user.deactivate! user.deactivate!
...@@ -915,6 +922,12 @@ RSpec.describe Gitlab::GitAccess do ...@@ -915,6 +922,12 @@ RSpec.describe Gitlab::GitAccess do
project.add_developer(user) project.add_developer(user)
end end
it 'disallows users that are blocked pending approval to push' do
user.block_pending_approval
expect { push_access_check }.to raise_forbidden('Your account is pending approval from your administrator and hence blocked.')
end
it 'does not allow deactivated users to push' do it 'does not allow deactivated users to push' do
user.deactivate! user.deactivate!
......
...@@ -705,6 +705,25 @@ RSpec.describe User do ...@@ -705,6 +705,25 @@ RSpec.describe User do
end end
describe "scopes" do describe "scopes" do
describe '.blocked' do
subject { described_class.blocked }
it 'returns only blocked users' do
active_user = create(:user)
blocked_user = create(:user, :blocked)
blocked_pending_approval_user = create(:user, :blocked_pending_approval)
ldap_blocked_user = create(:omniauth_user, :ldap_blocked)
expect(subject).to include(
blocked_user,
blocked_pending_approval_user,
ldap_blocked_user
)
expect(subject).not_to include(active_user)
end
end
describe ".with_two_factor" do describe ".with_two_factor" do
it "returns users with 2fa enabled via OTP" do it "returns users with 2fa enabled via OTP" do
user_with_2fa = create(:user, :two_factor_via_otp) user_with_2fa = create(:user, :two_factor_via_otp)
...@@ -1694,6 +1713,24 @@ RSpec.describe User do ...@@ -1694,6 +1713,24 @@ RSpec.describe User do
end end
end end
describe 'blocking a user pending approval' do
let(:user) { create(:user) }
before do
user.block_pending_approval
end
context 'an active user' do
it 'can be blocked pending approval' do
expect(user.blocked_pending_approval?).to eq(true)
end
it 'behaves like a blocked user' do
expect(user.blocked?).to eq(true)
end
end
end
describe '.filter_items' do describe '.filter_items' do
let(:user) { double } let(:user) { double }
...@@ -4917,6 +4954,14 @@ RSpec.describe User do ...@@ -4917,6 +4954,14 @@ RSpec.describe User do
it { is_expected.to be :locked } it { is_expected.to be :locked }
end end
context 'when user is blocked pending approval' do
before do
user.block_pending_approval!
end
it { is_expected.to be :blocked_pending_approval }
end
end end
describe '#password_required?' do describe '#password_required?' do
......
...@@ -187,6 +187,14 @@ RSpec.describe GlobalPolicy do ...@@ -187,6 +187,14 @@ RSpec.describe GlobalPolicy do
it { is_expected.not_to be_allowed(:access_api) } it { is_expected.not_to be_allowed(:access_api) }
end end
context 'user blocked pending approval' do
before do
current_user.block_pending_approval
end
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
...@@ -276,6 +284,14 @@ RSpec.describe GlobalPolicy do ...@@ -276,6 +284,14 @@ RSpec.describe GlobalPolicy do
it { is_expected.not_to be_allowed(:receive_notifications) } it { is_expected.not_to be_allowed(:receive_notifications) }
end end
context 'user blocked pending approval' do
before do
current_user.block_pending_approval
end
it { is_expected.not_to be_allowed(:receive_notifications) }
end
end end
describe 'git access' do describe 'git access' do
...@@ -344,6 +360,14 @@ RSpec.describe GlobalPolicy do ...@@ -344,6 +360,14 @@ RSpec.describe GlobalPolicy do
it { is_expected.to be_allowed(:access_git) } it { is_expected.to be_allowed(:access_git) }
end end
context 'user blocked pending approval' do
before do
current_user.block_pending_approval
end
it { is_expected.not_to be_allowed(:access_git) }
end
end end
describe 'read instance metadata' do describe 'read instance metadata' do
...@@ -412,6 +436,14 @@ RSpec.describe GlobalPolicy do ...@@ -412,6 +436,14 @@ RSpec.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 'user blocked pending approval' do
before do
current_user.block_pending_approval
end
it { is_expected.not_to be_allowed(:use_slash_commands) }
end
end end
describe 'create_snippet' do describe 'create_snippet' do
...@@ -444,5 +476,13 @@ RSpec.describe GlobalPolicy do ...@@ -444,5 +476,13 @@ RSpec.describe GlobalPolicy do
it { is_expected.not_to be_allowed(:log_in) } it { is_expected.not_to be_allowed(:log_in) }
end end
context 'user blocked pending approval' do
before do
current_user.block_pending_approval
end
it { is_expected.not_to be_allowed(:log_in) }
end
end end
end end
...@@ -71,4 +71,12 @@ RSpec.describe 'doorkeeper access' do ...@@ -71,4 +71,12 @@ RSpec.describe 'doorkeeper access' do
it_behaves_like 'forbidden request' it_behaves_like 'forbidden request'
end end
context 'when user is blocked pending approval' do
before do
user.block_pending_approval
end
it_behaves_like 'forbidden request'
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