Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-18 13:34:06 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-18 13:34:06 +0300
commit859a6fb938bb9ee2a317c46dfa4fcc1af49608f0 (patch)
treed7f2700abe6b4ffcb2dcfc80631b2d87d0609239 /spec/lib/gitlab/auth
parent446d496a6d000c73a304be52587cd9bbc7493136 (diff)
Add latest changes from gitlab-org/gitlab@13-9-stable-eev13.9.0-rc42
Diffstat (limited to 'spec/lib/gitlab/auth')
-rw-r--r--spec/lib/gitlab/auth/auth_finders_spec.rb329
-rw-r--r--spec/lib/gitlab/auth/ip_rate_limiter_spec.rb3
-rw-r--r--spec/lib/gitlab/auth/otp/session_enforcer_spec.rb41
-rw-r--r--spec/lib/gitlab/auth/u2f_webauthn_converter_spec.rb29
4 files changed, 174 insertions, 228 deletions
diff --git a/spec/lib/gitlab/auth/auth_finders_spec.rb b/spec/lib/gitlab/auth/auth_finders_spec.rb
index 775f8f056b5..cddcaf09b74 100644
--- a/spec/lib/gitlab/auth/auth_finders_spec.rb
+++ b/spec/lib/gitlab/auth/auth_finders_spec.rb
@@ -7,7 +7,18 @@ RSpec.describe Gitlab::Auth::AuthFinders do
include HttpBasicAuthHelpers
# Create the feed_token and static_object_token for the user
- let_it_be(:user) { create(:user).tap(&:feed_token).tap(&:static_object_token) }
+ let_it_be(:user, freeze: true) { create(:user).tap(&:feed_token).tap(&:static_object_token) }
+ let_it_be(:personal_access_token, freeze: true) { create(:personal_access_token, user: user) }
+
+ let_it_be(:project, freeze: true) { create(:project, :private) }
+ let_it_be(:pipeline, freeze: true) { create(:ci_pipeline, project: project) }
+ let_it_be(:job, freeze: true) { create(:ci_build, :running, pipeline: pipeline, user: user) }
+ let_it_be(:failed_job, freeze: true) { create(:ci_build, :failed, pipeline: pipeline, user: user) }
+
+ let_it_be(:project2, freeze: true) { create(:project, :private) }
+ let_it_be(:pipeline2, freeze: true) { create(:ci_pipeline, project: project2) }
+ let_it_be(:job2, freeze: true) { create(:ci_build, :running, pipeline: pipeline2, user: user) }
+
let(:env) do
{
'rack.input' => ''
@@ -15,6 +26,12 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
let(:request) { ActionDispatch::Request.new(env) }
+ let(:params) { {} }
+
+ before_all do
+ project.add_developer(user)
+ project2.add_developer(user)
+ end
def set_param(key, value)
request.update_param(key, value)
@@ -28,75 +45,93 @@ RSpec.describe Gitlab::Auth::AuthFinders do
env.merge!(basic_auth_header(username, password))
end
- shared_examples 'find user from job token' do
+ def set_bearer_token(token)
+ env['HTTP_AUTHORIZATION'] = "Bearer #{token}"
+ end
+
+ shared_examples 'find user from job token' do |without_job_token_allowed|
context 'when route is allowed to be authenticated' do
let(:route_authentication_setting) { { job_token_allowed: true } }
- it "returns an Unauthorized exception for an invalid token" do
- set_token('invalid token')
+ context 'for an invalid token' do
+ let(:token) { 'invalid token' }
- expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ it "returns an Unauthorized exception" do
+ expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ expect(@current_authenticated_job).to be_nil
+ end
end
context 'with a running job' do
- before do
- job.update!(status: :running)
- end
-
- it 'return user if token is valid' do
- set_token(job.token)
+ let(:token) { job.token }
+ it 'return user' do
expect(subject).to eq(user)
expect(@current_authenticated_job).to eq job
end
end
context 'with a job that is not running' do
- before do
- job.update!(status: :failed)
- end
+ let(:token) { failed_job.token }
it 'returns an Unauthorized exception' do
- set_token(job.token)
-
expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ expect(@current_authenticated_job).to be_nil
+ end
+ end
+ end
+
+ context 'when route is not allowed to be authenticated' do
+ let(:route_authentication_setting) { { job_token_allowed: false } }
+
+ context 'with a running job' do
+ let(:token) { job.token }
+
+ if without_job_token_allowed == :error
+ it 'returns an Unauthorized exception' do
+ expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ expect(@current_authenticated_job).to be_nil
+ end
+ elsif without_job_token_allowed == :user
+ it 'returns the user' do
+ expect(subject).to eq(user)
+ expect(@current_authenticated_job).to eq job
+ end
+ else
+ it 'returns nil' do
+ is_expected.to be_nil
+ expect(@current_authenticated_job).to be_nil
+ end
end
end
end
end
describe '#find_user_from_bearer_token' do
- let_it_be_with_reload(:job) { create(:ci_build, user: user) }
-
subject { find_user_from_bearer_token }
context 'when the token is passed as an oauth token' do
- def set_token(token)
- env['HTTP_AUTHORIZATION'] = "Bearer #{token}"
+ before do
+ set_bearer_token(token)
end
- context 'with a job token' do
- it_behaves_like 'find user from job token'
- end
+ it_behaves_like 'find user from job token', :error
+ end
- context 'with oauth token' do
- let(:application) { Doorkeeper::Application.create!(name: 'MyApp', redirect_uri: 'https://app.com', owner: user) }
- let(:token) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api').token }
+ context 'with oauth token' do
+ let(:application) { Doorkeeper::Application.create!(name: 'MyApp', redirect_uri: 'https://app.com', owner: user) }
+ let(:doorkeeper_access_token) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api') }
- before do
- set_token(token)
- end
-
- it { is_expected.to eq user }
+ before do
+ set_bearer_token(doorkeeper_access_token.token)
end
+
+ it { is_expected.to eq user }
end
context 'with a personal access token' do
- let_it_be(:pat) { create(:personal_access_token, user: user) }
- let(:token) { pat.token }
-
before do
- env[described_class::PRIVATE_TOKEN_HEADER] = pat.token
+ env[described_class::PRIVATE_TOKEN_HEADER] = personal_access_token.token
end
it { is_expected.to eq user }
@@ -277,7 +312,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
describe '#deploy_token_from_request' do
- let_it_be(:deploy_token) { create(:deploy_token) }
+ let_it_be(:deploy_token, freeze: true) { create(:deploy_token) }
let_it_be(:route_authentication_setting) { { deploy_token_allowed: true } }
subject { deploy_token_from_request }
@@ -293,11 +328,13 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
context 'with deploy token headers' do
- before do
- set_header(described_class::DEPLOY_TOKEN_HEADER, deploy_token.token)
- end
+ context 'with valid deploy token' do
+ before do
+ set_header(described_class::DEPLOY_TOKEN_HEADER, deploy_token.token)
+ end
- it { is_expected.to eq deploy_token }
+ it { is_expected.to eq deploy_token }
+ end
it_behaves_like 'an unauthenticated route'
@@ -311,17 +348,19 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
context 'with oauth headers' do
- before do
- set_header('HTTP_AUTHORIZATION', "Bearer #{deploy_token.token}")
- end
+ context 'with valid token' do
+ before do
+ set_bearer_token(deploy_token.token)
+ end
- it { is_expected.to eq deploy_token }
+ it { is_expected.to eq deploy_token }
- it_behaves_like 'an unauthenticated route'
+ it_behaves_like 'an unauthenticated route'
+ end
context 'with invalid token' do
before do
- set_header('HTTP_AUTHORIZATION', "Bearer invalid_token")
+ set_bearer_token('invalid_token')
end
it { is_expected.to be_nil }
@@ -348,8 +387,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
describe '#find_user_from_access_token' do
- let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
-
before do
set_header('SCRIPT_NAME', 'url.atom')
end
@@ -374,24 +411,34 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
context 'with OAuth headers' do
- it 'returns user' do
- set_header('HTTP_AUTHORIZATION', "Bearer #{personal_access_token.token}")
+ context 'with valid personal access token' do
+ before do
+ set_bearer_token(personal_access_token.token)
+ end
- expect(find_user_from_access_token).to eq user
+ it 'returns user' do
+ expect(find_user_from_access_token).to eq user
+ end
end
- it 'returns exception if invalid personal_access_token' do
- env['HTTP_AUTHORIZATION'] = 'Bearer invalid_20byte_token'
+ context 'with invalid personal_access_token' do
+ before do
+ set_bearer_token('invalid_20byte_token')
+ end
- expect { find_personal_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ it 'returns exception' do
+ expect { find_personal_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ end
end
context 'when using a non-prefixed access token' do
- let_it_be(:personal_access_token) { create(:personal_access_token, :no_prefix, user: user) }
+ let_it_be(:personal_access_token, freeze: true) { create(:personal_access_token, :no_prefix, user: user) }
- it 'returns user' do
- set_header('HTTP_AUTHORIZATION', "Bearer #{personal_access_token.token}")
+ before do
+ set_bearer_token(personal_access_token.token)
+ end
+ it 'returns user' do
expect(find_user_from_access_token).to eq user
end
end
@@ -399,8 +446,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
describe '#find_user_from_web_access_token' do
- let_it_be_with_reload(:personal_access_token) { create(:personal_access_token, user: user) }
-
before do
set_header(described_class::PRIVATE_TOKEN_HEADER, personal_access_token.token)
end
@@ -451,9 +496,9 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
context 'when the token has read_api scope' do
- before do
- personal_access_token.update!(scopes: ['read_api'])
+ let_it_be(:personal_access_token, freeze: true) { create(:personal_access_token, user: user, scopes: ['read_api']) }
+ before do
set_header('SCRIPT_NAME', '/api/endpoint')
end
@@ -481,8 +526,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
describe '#find_personal_access_token' do
- let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
-
before do
set_header('SCRIPT_NAME', 'url.atom')
end
@@ -516,21 +559,23 @@ RSpec.describe Gitlab::Auth::AuthFinders do
describe '#find_oauth_access_token' do
let(:application) { Doorkeeper::Application.create!(name: 'MyApp', redirect_uri: 'https://app.com', owner: user) }
- let(:token) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api') }
+ let(:doorkeeper_access_token) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api') }
context 'passed as header' do
- it 'returns token if valid oauth_access_token' do
- set_header('HTTP_AUTHORIZATION', "Bearer #{token.token}")
+ before do
+ set_bearer_token(doorkeeper_access_token.token)
+ end
- expect(find_oauth_access_token.token).to eq token.token
+ it 'returns token if valid oauth_access_token' do
+ expect(find_oauth_access_token.token).to eq doorkeeper_access_token.token
end
end
context 'passed as param' do
it 'returns user if valid oauth_access_token' do
- set_param(:access_token, token.token)
+ set_param(:access_token, doorkeeper_access_token.token)
- expect(find_oauth_access_token.token).to eq token.token
+ expect(find_oauth_access_token.token).to eq doorkeeper_access_token.token
end
end
@@ -538,10 +583,14 @@ RSpec.describe Gitlab::Auth::AuthFinders do
expect(find_oauth_access_token).to be_nil
end
- it 'returns exception if invalid oauth_access_token' do
- set_header('HTTP_AUTHORIZATION', "Bearer invalid_token")
+ context 'with invalid token' do
+ before do
+ set_bearer_token('invalid_token')
+ end
- expect { find_oauth_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ it 'returns exception if invalid oauth_access_token' do
+ expect { find_oauth_access_token }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ end
end
end
@@ -551,7 +600,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
context 'access token is valid' do
- let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
let(:route_authentication_setting) { { basic_auth_personal_access_token: true } }
it 'finds the token from basic auth' do
@@ -572,8 +620,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
context 'route_setting is not set' do
- let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
-
it 'returns nil' do
auth_header_with(personal_access_token.token)
@@ -582,7 +628,6 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
context 'route_setting is not correct' do
- let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
let(:route_authentication_setting) { { basic_auth_personal_access_token: false } }
it 'returns nil' do
@@ -629,44 +674,18 @@ RSpec.describe Gitlab::Auth::AuthFinders do
context 'with CI username' do
let(:username) { ::Gitlab::Auth::CI_JOB_USER }
- let_it_be(:user) { create(:user) }
- let_it_be(:build) { create(:ci_build, user: user, status: :running) }
-
- it 'returns nil without password' do
- set_basic_auth_header(username, nil)
-
- is_expected.to be_nil
- end
-
- it 'returns user with valid token' do
- set_basic_auth_header(username, build.token)
-
- is_expected.to eq user
- expect(@current_authenticated_job).to eq build
- end
-
- it 'raises error with invalid token' do
- set_basic_auth_header(username, 'token')
-
- expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ before do
+ set_basic_auth_header(username, token)
end
- it 'returns exception if the job is not running' do
- set_basic_auth_header(username, build.token)
- build.success!
-
- expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
- end
+ it_behaves_like 'find user from job token', :user
end
end
describe '#validate_access_token!' do
subject { validate_access_token! }
- let_it_be_with_reload(:personal_access_token) { create(:personal_access_token, user: user) }
-
context 'with a job token' do
- let_it_be(:job) { create(:ci_build, user: user, status: :running) }
let(:route_authentication_setting) { { job_token_allowed: true } }
before do
@@ -684,6 +703,8 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
context 'token is not valid' do
+ let_it_be_with_reload(:personal_access_token) { create(:personal_access_token, user: user) }
+
before do
allow_any_instance_of(described_class).to receive(:access_token).and_return(personal_access_token)
end
@@ -706,7 +727,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
context 'with impersonation token' do
- let_it_be(:personal_access_token) { create(:personal_access_token, :impersonation, user: user) }
+ let_it_be(:personal_access_token, freeze: true) { create(:personal_access_token, :impersonation, user: user) }
context 'when impersonation is disabled' do
before do
@@ -722,96 +743,30 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
describe '#find_user_from_job_token' do
- let_it_be(:job) { create(:ci_build, user: user, status: :running) }
- let(:route_authentication_setting) { { job_token_allowed: true } }
-
subject { find_user_from_job_token }
- context 'when the job token is in the headers' do
- it 'returns the user if valid job token' do
- set_header(described_class::JOB_TOKEN_HEADER, job.token)
-
- is_expected.to eq(user)
- expect(@current_authenticated_job).to eq(job)
- end
-
- it 'returns nil without job token' do
- set_header(described_class::JOB_TOKEN_HEADER, '')
-
- is_expected.to be_nil
- end
-
- it 'returns exception if invalid job token' do
- set_header(described_class::JOB_TOKEN_HEADER, 'invalid token')
-
- expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ context 'when the token is in the headers' do
+ before do
+ set_header(described_class::JOB_TOKEN_HEADER, token)
end
- it 'returns exception if the job is not running' do
- set_header(described_class::JOB_TOKEN_HEADER, job.token)
- job.success!
+ it_behaves_like 'find user from job token'
+ end
- expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
+ context 'when the token is in the job_token param' do
+ before do
+ set_param(described_class::JOB_TOKEN_PARAM, token)
end
- context 'when route is not allowed to be authenticated' do
- let(:route_authentication_setting) { { job_token_allowed: false } }
-
- it 'sets current_user to nil' do
- set_header(described_class::JOB_TOKEN_HEADER, job.token)
-
- allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(true)
-
- is_expected.to be_nil
- end
- end
+ it_behaves_like 'find user from job token'
end
- context 'when the job token is in the params' do
- shared_examples 'job token params' do |token_key_name|
- before do
- set_param(token_key_name, token)
- end
-
- context 'with valid job token' do
- let(:token) { job.token }
-
- it 'returns the user' do
- is_expected.to eq(user)
- expect(@current_authenticated_job).to eq(job)
- end
- end
-
- context 'with empty job token' do
- let(:token) { '' }
-
- it 'returns nil' do
- is_expected.to be_nil
- end
- end
-
- context 'with invalid job token' do
- let(:token) { 'invalid token' }
-
- it 'returns exception' do
- expect { subject }.to raise_error(Gitlab::Auth::UnauthorizedError)
- end
- end
-
- context 'when route is not allowed to be authenticated' do
- let(:route_authentication_setting) { { job_token_allowed: false } }
- let(:token) { job.token }
-
- it 'sets current_user to nil' do
- allow_any_instance_of(Gitlab::UserAccess).to receive(:allowed?).and_return(true)
-
- is_expected.to be_nil
- end
- end
+ context 'when the token is in the token param' do
+ before do
+ set_param(described_class::RUNNER_JOB_TOKEN_PARAM, token)
end
- it_behaves_like 'job token params', described_class::JOB_TOKEN_PARAM
- it_behaves_like 'job token params', described_class::RUNNER_JOB_TOKEN_PARAM
+ it_behaves_like 'find user from job token'
end
context 'when the job token is provided via basic auth' do
@@ -834,7 +789,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
describe '#cluster_agent_token_from_authorization_token' do
- let_it_be(:agent_token) { create(:cluster_agent_token) }
+ let_it_be(:agent_token, freeze: true) { create(:cluster_agent_token) }
context 'when route_setting is empty' do
it 'returns nil' do
@@ -884,7 +839,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
end
describe '#find_runner_from_token' do
- let_it_be(:runner) { create(:ci_runner) }
+ let_it_be(:runner, freeze: true) { create(:ci_runner) }
context 'with API requests' do
before do
diff --git a/spec/lib/gitlab/auth/ip_rate_limiter_spec.rb b/spec/lib/gitlab/auth/ip_rate_limiter_spec.rb
index 3d782272d7e..f23fdd3fbcb 100644
--- a/spec/lib/gitlab/auth/ip_rate_limiter_spec.rb
+++ b/spec/lib/gitlab/auth/ip_rate_limiter_spec.rb
@@ -19,6 +19,9 @@ RSpec.describe Gitlab::Auth::IpRateLimiter, :use_clean_rails_memory_store_cachin
before do
stub_rack_attack_setting(options)
+ Rack::Attack.reset!
+ Rack::Attack.clear_configuration
+ Gitlab::RackAttack.configure(Rack::Attack)
end
after do
diff --git a/spec/lib/gitlab/auth/otp/session_enforcer_spec.rb b/spec/lib/gitlab/auth/otp/session_enforcer_spec.rb
deleted file mode 100644
index 928aade4008..00000000000
--- a/spec/lib/gitlab/auth/otp/session_enforcer_spec.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Auth::Otp::SessionEnforcer, :clean_gitlab_redis_shared_state do
- let_it_be(:key) { create(:key)}
-
- describe '#update_session' do
- it 'registers a session in Redis' do
- redis = double(:redis)
- expect(Gitlab::Redis::SharedState).to receive(:with).and_yield(redis)
-
- expect(redis).to(
- receive(:setex)
- .with("#{described_class::OTP_SESSIONS_NAMESPACE}:#{key.id}",
- described_class::DEFAULT_EXPIRATION,
- true)
- .once)
-
- described_class.new(key).update_session
- end
- end
-
- describe '#access_restricted?' do
- subject { described_class.new(key).access_restricted? }
-
- context 'with existing session' do
- before do
- Gitlab::Redis::SharedState.with do |redis|
- redis.set("#{described_class::OTP_SESSIONS_NAMESPACE}:#{key.id}", true )
- end
- end
-
- it { is_expected.to be_falsey }
- end
-
- context 'without an existing session' do
- it { is_expected.to be_truthy }
- end
- end
-end
diff --git a/spec/lib/gitlab/auth/u2f_webauthn_converter_spec.rb b/spec/lib/gitlab/auth/u2f_webauthn_converter_spec.rb
new file mode 100644
index 00000000000..deddc7f5294
--- /dev/null
+++ b/spec/lib/gitlab/auth/u2f_webauthn_converter_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Auth::U2fWebauthnConverter do
+ let_it_be(:u2f_registration) do
+ device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5))
+ create(:u2f_registration, name: 'u2f_device',
+ certificate: Base64.strict_encode64(device.cert_raw),
+ key_handle: U2F.urlsafe_encode64(device.key_handle_raw),
+ public_key: Base64.strict_encode64(device.origin_public_key_raw))
+ end
+
+ it 'converts u2f registration' do
+ webauthn_credential = WebAuthn::U2fMigrator.new(
+ app_id: Gitlab.config.gitlab.url,
+ certificate: u2f_registration.certificate,
+ key_handle: u2f_registration.key_handle,
+ public_key: u2f_registration.public_key,
+ counter: u2f_registration.counter
+ ).credential
+
+ converted_webauthn = described_class.new(u2f_registration).convert
+
+ expect(converted_webauthn).to(
+ include(user_id: u2f_registration.user_id,
+ credential_xid: Base64.strict_encode64(webauthn_credential.id)))
+ end
+end