debian-mirror-gitlab/spec/lib/gitlab/auth/current_user_mode_spec.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

364 lines
11 KiB
Ruby
Raw Permalink Normal View History

2019-12-21 20:55:43 +05:30
# frozen_string_literal: true
require 'spec_helper'
2021-03-08 18:12:59 +05:30
RSpec.describe Gitlab::Auth::CurrentUserMode, :request_store do
2020-03-13 15:44:24 +05:30
let(:user) { build_stubbed(:user) }
2019-12-21 20:55:43 +05:30
subject { described_class.new(user) }
2020-04-08 14:13:33 +05:30
context 'when session is available' do
include_context 'custom session'
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
before do
allow(ActiveSession).to receive(:list_sessions).with(user).and_return([session])
2020-03-13 15:44:24 +05:30
end
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
shared_examples 'admin mode cannot be enabled' do
it 'is false by default' do
expect(subject.admin_mode?).to be(false)
end
2020-03-13 15:44:24 +05:30
it 'cannot be enabled with a valid password' do
2020-04-08 14:13:33 +05:30
subject.enable_admin_mode!(password: user.password)
2019-12-21 20:55:43 +05:30
expect(subject.admin_mode?).to be(false)
end
2020-03-13 15:44:24 +05:30
it 'cannot be enabled with an invalid password' do
2020-04-08 14:13:33 +05:30
subject.enable_admin_mode!(password: nil)
2019-12-21 20:55:43 +05:30
2020-03-13 15:44:24 +05:30
expect(subject.admin_mode?).to be(false)
end
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
it 'cannot be enabled with empty params' do
subject.enable_admin_mode!
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
expect(subject.admin_mode?).to be(false)
2019-12-21 20:55:43 +05:30
end
2020-04-08 14:13:33 +05:30
it 'disable has no effect' do
subject.enable_admin_mode!
subject.disable_admin_mode!
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
expect(subject.admin_mode?).to be(false)
2019-12-21 20:55:43 +05:30
end
2020-04-08 14:13:33 +05:30
context 'skipping password validation' do
it 'cannot be enabled with a valid password' do
subject.enable_admin_mode!(password: user.password, skip_password_validation: true)
2019-12-21 20:55:43 +05:30
2020-01-01 13:55:28 +05:30
expect(subject.admin_mode?).to be(false)
end
2019-12-21 20:55:43 +05:30
2020-01-01 13:55:28 +05:30
it 'cannot be enabled with an invalid password' do
2020-04-08 14:13:33 +05:30
subject.enable_admin_mode!(skip_password_validation: true)
2019-12-21 20:55:43 +05:30
2020-01-01 13:55:28 +05:30
expect(subject.admin_mode?).to be(false)
2019-12-21 20:55:43 +05:30
end
2020-04-08 14:13:33 +05:30
end
end
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
describe '#admin_mode?' do
context 'when the user is a regular user' do
it_behaves_like 'admin mode cannot be enabled'
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
context 'bypassing session' do
it_behaves_like 'admin mode cannot be enabled' do
around do |example|
described_class.bypass_session!(user.id) { example.run }
end
end
2019-12-21 20:55:43 +05:30
end
2020-04-08 14:13:33 +05:30
end
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
context 'when the user is an admin' do
let(:user) { build_stubbed(:user, :admin) }
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
context 'when admin mode not requested' do
it 'is false by default' do
expect(subject.admin_mode?).to be(false)
end
it 'raises exception if we try to enable it' do
expect do
subject.enable_admin_mode!(password: user.password)
end.to raise_error(::Gitlab::Auth::CurrentUserMode::NotRequestedError)
expect(subject.admin_mode?).to be(false)
end
2019-12-21 20:55:43 +05:30
end
2020-04-08 14:13:33 +05:30
context 'when admin mode requested first' do
before do
subject.request_admin_mode!
end
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
it 'is false by default' do
expect(subject.admin_mode?).to be(false)
end
it 'cannot be enabled with an invalid password' do
subject.enable_admin_mode!(password: nil)
2020-01-01 13:55:28 +05:30
2020-04-08 14:13:33 +05:30
expect(subject.admin_mode?).to be(false)
2020-01-01 13:55:28 +05:30
end
2019-12-21 20:55:43 +05:30
2020-01-01 13:55:28 +05:30
it 'can be enabled with a valid password' do
2020-04-08 14:13:33 +05:30
subject.enable_admin_mode!(password: user.password)
2020-01-01 13:55:28 +05:30
expect(subject.admin_mode?).to be(true)
2019-12-21 20:55:43 +05:30
end
2020-04-08 14:13:33 +05:30
it 'can be disabled' do
subject.enable_admin_mode!(password: user.password)
subject.disable_admin_mode!
2020-01-01 13:55:28 +05:30
2020-04-08 14:13:33 +05:30
expect(subject.admin_mode?).to be(false)
2020-01-01 13:55:28 +05:30
end
2020-04-08 14:13:33 +05:30
it 'will expire in the future' do
subject.enable_admin_mode!(password: user.password)
expect(subject.admin_mode?).to be(true), 'admin mode is not active in the present'
2020-01-01 13:55:28 +05:30
2021-01-03 14:25:43 +05:30
travel_to(Gitlab::Auth::CurrentUserMode::MAX_ADMIN_MODE_TIME.from_now) do
2020-04-08 14:13:33 +05:30
# in the future this will be a new request, simulate by clearing the RequestStore
Gitlab::SafeRequestStore.clear!
expect(subject.admin_mode?).to be(false), 'admin mode did not expire in the future'
end
2020-01-01 13:55:28 +05:30
end
2020-04-08 14:13:33 +05:30
context 'skipping password validation' do
it 'can be enabled with a valid password' do
subject.enable_admin_mode!(password: user.password, skip_password_validation: true)
expect(subject.admin_mode?).to be(true)
2020-01-01 13:55:28 +05:30
end
2020-04-08 14:13:33 +05:30
it 'can be enabled with an invalid password' do
subject.enable_admin_mode!(skip_password_validation: true)
expect(subject.admin_mode?).to be(true)
end
2020-01-01 13:55:28 +05:30
end
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
context 'with two independent sessions' do
let(:another_session) { {} }
let(:another_subject) { described_class.new(user) }
before do
allow(ActiveSession).to receive(:list_sessions).with(user).and_return([session, another_session])
end
2020-04-22 19:07:51 +05:30
it 'cannot be enabled in one and seen in the other' do
2020-04-08 14:13:33 +05:30
Gitlab::Session.with_session(another_session) do
another_subject.request_admin_mode!
another_subject.enable_admin_mode!(password: user.password)
end
2020-04-22 19:07:51 +05:30
expect(subject.admin_mode?).to be(false)
2020-04-08 14:13:33 +05:30
end
2020-03-13 15:44:24 +05:30
end
end
2020-04-08 14:13:33 +05:30
context 'bypassing session' do
it 'is active by default' do
described_class.bypass_session!(user.id) do
expect(subject.admin_mode?).to be(true)
end
end
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
it 'enable has no effect' do
described_class.bypass_session!(user.id) do
subject.request_admin_mode!
subject.enable_admin_mode!(password: user.password)
expect(subject.admin_mode?).to be(true)
end
2020-03-13 15:44:24 +05:30
end
2020-04-08 14:13:33 +05:30
it 'disable has no effect' do
described_class.bypass_session!(user.id) do
subject.disable_admin_mode!
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
expect(subject.admin_mode?).to be(true)
end
2020-03-13 15:44:24 +05:30
end
end
end
2019-12-21 20:55:43 +05:30
end
2020-04-08 14:13:33 +05:30
describe '#enable_admin_mode!' do
let(:user) { build_stubbed(:user, :admin) }
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
it 'creates a timestamp in the session' do
subject.request_admin_mode!
2023-03-04 22:38:38 +05:30
2020-04-08 14:13:33 +05:30
subject.enable_admin_mode!(password: user.password)
2019-12-21 20:55:43 +05:30
2020-04-22 19:07:51 +05:30
expect(session).to include(expected_session_entry(be_within(1.second).of(Time.now)))
2020-04-08 14:13:33 +05:30
end
2023-03-04 22:38:38 +05:30
it 'returns true after successful enable' do
subject.request_admin_mode!
expect(subject.enable_admin_mode!(password: user.password)).to eq(true)
end
it 'returns false after unsuccessful enable' do
subject.request_admin_mode!
expect(subject.enable_admin_mode!(password: 'wrong password')).to eq(false)
end
context 'when user is not an admin' do
let(:user) { build_stubbed(:user) }
it 'returns false' do
subject.request_admin_mode!
expect(subject.enable_admin_mode!(password: user.password)).to eq(false)
end
end
context 'when admin mode is not requested' do
it 'raises error' do
expect do
subject.enable_admin_mode!(password: user.password)
end.to raise_error(Gitlab::Auth::CurrentUserMode::NotRequestedError)
end
end
2019-12-21 20:55:43 +05:30
end
2020-04-08 14:13:33 +05:30
describe '#disable_admin_mode!' do
let(:user) { build_stubbed(:user, :admin) }
2020-01-01 13:55:28 +05:30
2020-04-08 14:13:33 +05:30
it 'sets the session timestamp to nil' do
subject.request_admin_mode!
subject.disable_admin_mode!
2020-01-01 13:55:28 +05:30
2020-04-08 14:13:33 +05:30
expect(session).to include(expected_session_entry(be_nil))
end
2020-01-01 13:55:28 +05:30
end
2020-04-08 14:13:33 +05:30
describe '.with_current_request_admin_mode' do
context 'with a regular user' do
it 'user is not available inside nor outside the yielded block' do
described_class.with_current_admin(user) do
expect(described_class.current_admin).to be_nil
end
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
expect(described_class.bypass_session_admin_id).to be_nil
end
end
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
context 'with an admin user' do
let(:user) { build_stubbed(:user, :admin) }
2019-12-21 20:55:43 +05:30
2020-04-08 14:13:33 +05:30
context 'admin mode is disabled' do
it 'user is not available inside nor outside the yielded block' do
described_class.with_current_admin(user) do
expect(described_class.current_admin).to be_nil
end
expect(described_class.bypass_session_admin_id).to be_nil
end
2020-03-13 15:44:24 +05:30
end
2020-04-08 14:13:33 +05:30
context 'admin mode is enabled' do
before do
subject.request_admin_mode!
subject.enable_admin_mode!(password: user.password)
end
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
it 'user is available only inside the yielded block' do
described_class.with_current_admin(user) do
expect(described_class.current_admin).to be(user)
end
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
expect(described_class.current_admin).to be_nil
end
2020-03-13 15:44:24 +05:30
end
end
end
2020-04-08 14:13:33 +05:30
def expected_session_entry(value_matcher)
{
Gitlab::Auth::CurrentUserMode::SESSION_STORE_KEY => a_hash_including(
Gitlab::Auth::CurrentUserMode::ADMIN_MODE_START_TIME_KEY => value_matcher)
}
end
end
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
context 'when no session available' do
around do |example|
Gitlab::Session.with_session(nil) do
example.run
2020-03-13 15:44:24 +05:30
end
end
2020-04-08 14:13:33 +05:30
describe '.bypass_session!' do
context 'when providing a block' do
context 'with a regular user' do
it 'admin mode is false' do
described_class.bypass_session!(user.id) do
expect(Gitlab::Session.current).to be_nil
expect(subject.admin_mode?).to be(false)
expect(described_class.bypass_session_admin_id).to be(user.id)
end
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
expect(described_class.bypass_session_admin_id).to be_nil
2020-03-13 15:44:24 +05:30
end
2020-04-08 14:13:33 +05:30
end
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
context 'with an admin user' do
let(:user) { build_stubbed(:user, :admin) }
it 'admin mode is true' do
described_class.bypass_session!(user.id) do
expect(Gitlab::Session.current).to be_nil
expect(subject.admin_mode?).to be(true)
expect(described_class.bypass_session_admin_id).to be(user.id)
end
expect(described_class.bypass_session_admin_id).to be_nil
end
2020-03-13 15:44:24 +05:30
end
end
2020-04-08 14:13:33 +05:30
context 'when not providing a block' do
context 'with a regular user' do
it 'admin mode is false' do
described_class.bypass_session!(user.id)
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
expect(Gitlab::Session.current).to be_nil
expect(subject.admin_mode?).to be(false)
expect(described_class.bypass_session_admin_id).to be(user.id)
described_class.reset_bypass_session!
expect(described_class.bypass_session_admin_id).to be_nil
2020-03-13 15:44:24 +05:30
end
2020-04-08 14:13:33 +05:30
end
2020-03-13 15:44:24 +05:30
2020-04-08 14:13:33 +05:30
context 'with an admin user' do
let(:user) { build_stubbed(:user, :admin) }
it 'admin mode is true' do
described_class.bypass_session!(user.id)
expect(Gitlab::Session.current).to be_nil
expect(subject.admin_mode?).to be(true)
expect(described_class.bypass_session_admin_id).to be(user.id)
described_class.reset_bypass_session!
expect(described_class.bypass_session_admin_id).to be_nil
end
2020-03-13 15:44:24 +05:30
end
end
end
end
2019-12-21 20:55:43 +05:30
end