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
path: root/spec/lib
diff options
context:
space:
mode:
authorImre Farkas <ifarkas@gitlab.com>2019-04-09 18:38:58 +0300
committerAndreas Brandl <abrandl@gitlab.com>2019-04-09 18:38:58 +0300
commit9bc5ed14fe97fe63cd5be30c013c6af978715621 (patch)
tree74e1548a29b4683e94720b346a4fc41a068b2583 /spec/lib
parenta6218f1bcd78f656d57330e764d3f98e1fb1f3f3 (diff)
Move Contribution Analytics related spec in spec/features/groups/group_page_with_external_authorization_service_spec to EE
Diffstat (limited to 'spec/lib')
-rw-r--r--spec/lib/gitlab/external_authorization/access_spec.rb142
-rw-r--r--spec/lib/gitlab/external_authorization/cache_spec.rb48
-rw-r--r--spec/lib/gitlab/external_authorization/client_spec.rb97
-rw-r--r--spec/lib/gitlab/external_authorization/logger_spec.rb45
-rw-r--r--spec/lib/gitlab/external_authorization/response_spec.rb52
-rw-r--r--spec/lib/gitlab/external_authorization_spec.rb54
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
7 files changed, 439 insertions, 0 deletions
diff --git a/spec/lib/gitlab/external_authorization/access_spec.rb b/spec/lib/gitlab/external_authorization/access_spec.rb
new file mode 100644
index 00000000000..5dc2521b310
--- /dev/null
+++ b/spec/lib/gitlab/external_authorization/access_spec.rb
@@ -0,0 +1,142 @@
+require 'spec_helper'
+
+describe Gitlab::ExternalAuthorization::Access, :clean_gitlab_redis_cache do
+ subject(:access) { described_class.new(build(:user), 'dummy_label') }
+
+ describe '#loaded?' do
+ it 'is `true` when it was loaded recently' do
+ Timecop.freeze do
+ allow(access).to receive(:loaded_at).and_return(5.minutes.ago)
+
+ expect(access).to be_loaded
+ end
+ end
+
+ it 'is `false` when there is no loading time' do
+ expect(access).not_to be_loaded
+ end
+
+ it 'is `false` when there the result was loaded a long time ago' do
+ Timecop.freeze do
+ allow(access).to receive(:loaded_at).and_return(2.weeks.ago)
+
+ expect(access).not_to be_loaded
+ end
+ end
+ end
+
+ describe 'load!' do
+ let(:fake_client) { double('ExternalAuthorization::Client') }
+ let(:fake_response) do
+ double(
+ 'Response',
+ 'successful?' => true,
+ 'valid?' => true,
+ 'reason' => nil
+ )
+ end
+
+ before do
+ allow(access).to receive(:load_from_cache)
+ allow(fake_client).to receive(:request_access).and_return(fake_response)
+ allow(Gitlab::ExternalAuthorization::Client).to receive(:new) { fake_client }
+ end
+
+ context 'when loading from the webservice' do
+ it 'loads from the webservice it the cache was empty' do
+ expect(access).to receive(:load_from_cache)
+ expect(access).to receive(:load_from_service).and_call_original
+
+ access.load!
+
+ expect(access).to be_loaded
+ end
+
+ it 'assigns the accessibility, reason and loaded_at' do
+ allow(fake_response).to receive(:successful?).and_return(false)
+ allow(fake_response).to receive(:reason).and_return('Inaccessible label')
+
+ access.load!
+
+ expect(access.reason).to eq('Inaccessible label')
+ expect(access).not_to have_access
+ expect(access.loaded_at).not_to be_nil
+ end
+
+ it 'returns itself' do
+ expect(access.load!).to eq(access)
+ end
+
+ it 'stores the result in redis' do
+ Timecop.freeze do
+ fake_cache = double
+ expect(fake_cache).to receive(:store).with(true, nil, Time.now)
+ expect(access).to receive(:cache).and_return(fake_cache)
+
+ access.load!
+ end
+ end
+
+ context 'when the request fails' do
+ before do
+ allow(fake_client).to receive(:request_access) do
+ raise ::Gitlab::ExternalAuthorization::RequestFailed.new('Service unavailable')
+ end
+ end
+
+ it 'is loaded' do
+ access.load!
+
+ expect(access).to be_loaded
+ end
+
+ it 'assigns the correct accessibility, reason and loaded_at' do
+ access.load!
+
+ expect(access.reason).to eq('Service unavailable')
+ expect(access).not_to have_access
+ expect(access.loaded_at).not_to be_nil
+ end
+
+ it 'does not store the result in redis' do
+ fake_cache = double
+ expect(fake_cache).not_to receive(:store)
+ allow(access).to receive(:cache).and_return(fake_cache)
+
+ access.load!
+ end
+ end
+ end
+
+ context 'When loading from cache' do
+ let(:fake_cache) { double('ExternalAuthorization::Cache') }
+
+ before do
+ allow(access).to receive(:cache).and_return(fake_cache)
+ end
+
+ it 'does not load from the webservice' do
+ Timecop.freeze do
+ expect(fake_cache).to receive(:load).and_return([true, nil, Time.now])
+
+ expect(access).to receive(:load_from_cache).and_call_original
+ expect(access).not_to receive(:load_from_service)
+
+ access.load!
+ end
+ end
+
+ it 'loads from the webservice when the cached result was too old' do
+ Timecop.freeze do
+ expect(fake_cache).to receive(:load).and_return([true, nil, 2.days.ago])
+
+ expect(access).to receive(:load_from_cache).and_call_original
+ expect(access).to receive(:load_from_service).and_call_original
+ allow(fake_cache).to receive(:store)
+
+ access.load!
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/external_authorization/cache_spec.rb b/spec/lib/gitlab/external_authorization/cache_spec.rb
new file mode 100644
index 00000000000..58e7d626707
--- /dev/null
+++ b/spec/lib/gitlab/external_authorization/cache_spec.rb
@@ -0,0 +1,48 @@
+require 'spec_helper'
+
+describe Gitlab::ExternalAuthorization::Cache, :clean_gitlab_redis_cache do
+ let(:user) { build_stubbed(:user) }
+ let(:cache_key) { "external_authorization:user-#{user.id}:label-dummy_label" }
+
+ subject(:cache) { described_class.new(user, 'dummy_label') }
+
+ def read_from_redis(key)
+ Gitlab::Redis::Cache.with do |redis|
+ redis.hget(cache_key, key)
+ end
+ end
+
+ def set_in_redis(key, value)
+ Gitlab::Redis::Cache.with do |redis|
+ redis.hmset(cache_key, key, value)
+ end
+ end
+
+ describe '#load' do
+ it 'reads stored info from redis' do
+ Timecop.freeze do
+ set_in_redis(:access, false)
+ set_in_redis(:reason, 'Access denied for now')
+ set_in_redis(:refreshed_at, Time.now)
+
+ access, reason, refreshed_at = cache.load
+
+ expect(access).to eq(false)
+ expect(reason).to eq('Access denied for now')
+ expect(refreshed_at).to be_within(1.second).of(Time.now)
+ end
+ end
+ end
+
+ describe '#store' do
+ it 'sets the values in redis' do
+ Timecop.freeze do
+ cache.store(true, 'the reason', Time.now)
+
+ expect(read_from_redis(:access)).to eq('true')
+ expect(read_from_redis(:reason)).to eq('the reason')
+ expect(read_from_redis(:refreshed_at)).to eq(Time.now.to_s)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/external_authorization/client_spec.rb b/spec/lib/gitlab/external_authorization/client_spec.rb
new file mode 100644
index 00000000000..fa18c1e56e8
--- /dev/null
+++ b/spec/lib/gitlab/external_authorization/client_spec.rb
@@ -0,0 +1,97 @@
+require 'spec_helper'
+
+describe Gitlab::ExternalAuthorization::Client do
+ let(:user) { build(:user, email: 'dummy_user@example.com') }
+ let(:dummy_url) { 'https://dummy.net/' }
+ subject(:client) { described_class.new(user, 'dummy_label') }
+
+ before do
+ stub_application_setting(external_authorization_service_url: dummy_url)
+ end
+
+ describe '#request_access' do
+ it 'performs requests to the configured endpoint' do
+ expect(Excon).to receive(:post).with(dummy_url, any_args)
+
+ client.request_access
+ end
+
+ it 'adds the correct params for the user to the body of the request' do
+ expected_body = {
+ user_identifier: 'dummy_user@example.com',
+ project_classification_label: 'dummy_label'
+ }.to_json
+ expect(Excon).to receive(:post)
+ .with(dummy_url, hash_including(body: expected_body))
+
+ client.request_access
+ end
+
+ it 'respects the the timeout' do
+ stub_application_setting(
+ external_authorization_service_timeout: 3
+ )
+
+ expect(Excon).to receive(:post).with(dummy_url,
+ hash_including(
+ connect_timeout: 3,
+ read_timeout: 3,
+ write_timeout: 3
+ ))
+
+ client.request_access
+ end
+
+ it 'adds the mutual tls params when they are present' do
+ stub_application_setting(
+ external_auth_client_cert: 'the certificate data',
+ external_auth_client_key: 'the key data',
+ external_auth_client_key_pass: 'open sesame'
+ )
+ expected_params = {
+ client_cert_data: 'the certificate data',
+ client_key_data: 'the key data',
+ client_key_pass: 'open sesame'
+ }
+
+ expect(Excon).to receive(:post).with(dummy_url, hash_including(expected_params))
+
+ client.request_access
+ end
+
+ it 'returns an expected response' do
+ expect(Excon).to receive(:post)
+
+ expect(client.request_access)
+ .to be_kind_of(::Gitlab::ExternalAuthorization::Response)
+ end
+
+ it 'wraps exceptions if the request fails' do
+ expect(Excon).to receive(:post) { raise Excon::Error.new('the request broke') }
+
+ expect { client.request_access }
+ .to raise_error(::Gitlab::ExternalAuthorization::RequestFailed)
+ end
+
+ describe 'for ldap users' do
+ let(:user) do
+ create(:omniauth_user,
+ email: 'dummy_user@example.com',
+ extern_uid: 'external id',
+ provider: 'ldapprovider')
+ end
+
+ it 'includes the ldap dn for ldap users' do
+ expected_body = {
+ user_identifier: 'dummy_user@example.com',
+ project_classification_label: 'dummy_label',
+ user_ldap_dn: 'external id'
+ }.to_json
+ expect(Excon).to receive(:post)
+ .with(dummy_url, hash_including(body: expected_body))
+
+ client.request_access
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/external_authorization/logger_spec.rb b/spec/lib/gitlab/external_authorization/logger_spec.rb
new file mode 100644
index 00000000000..81f1b2390e6
--- /dev/null
+++ b/spec/lib/gitlab/external_authorization/logger_spec.rb
@@ -0,0 +1,45 @@
+require 'spec_helper'
+
+describe Gitlab::ExternalAuthorization::Logger do
+ let(:request_time) { Time.parse('2018-03-26 20:22:15') }
+
+ def fake_access(has_access, user, load_type = :request)
+ access = double('access')
+ allow(access).to receive_messages(user: user,
+ has_access?: has_access,
+ loaded_at: request_time,
+ label: 'dummy_label',
+ load_type: load_type)
+
+ access
+ end
+
+ describe '.log_access' do
+ it 'logs a nice message for an access request' do
+ expected_message = "GRANTED admin@example.com access to 'dummy_label' (the/project/path)"
+ fake_access = fake_access(true, build(:user, email: 'admin@example.com'))
+
+ expect(described_class).to receive(:info).with(expected_message)
+
+ described_class.log_access(fake_access, 'the/project/path')
+ end
+
+ it 'does not trip without a project path' do
+ expected_message = "DENIED admin@example.com access to 'dummy_label'"
+ fake_access = fake_access(false, build(:user, email: 'admin@example.com'))
+
+ expect(described_class).to receive(:info).with(expected_message)
+
+ described_class.log_access(fake_access, nil)
+ end
+
+ it 'adds the load time for cached accesses' do
+ expected_message = "DENIED admin@example.com access to 'dummy_label' - cache #{request_time}"
+ fake_access = fake_access(false, build(:user, email: 'admin@example.com'), :cache)
+
+ expect(described_class).to receive(:info).with(expected_message)
+
+ described_class.log_access(fake_access, nil)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/external_authorization/response_spec.rb b/spec/lib/gitlab/external_authorization/response_spec.rb
new file mode 100644
index 00000000000..43211043eca
--- /dev/null
+++ b/spec/lib/gitlab/external_authorization/response_spec.rb
@@ -0,0 +1,52 @@
+require 'spec_helper'
+
+describe Gitlab::ExternalAuthorization::Response do
+ let(:excon_response) { double }
+ subject(:response) { described_class.new(excon_response) }
+
+ describe '#valid?' do
+ it 'is valid for 200, 401, and 403 responses' do
+ [200, 401, 403].each do |status|
+ allow(excon_response).to receive(:status).and_return(status)
+
+ expect(response).to be_valid
+ end
+ end
+
+ it "is invalid for other statuses" do
+ expect(excon_response).to receive(:status).and_return(500)
+
+ expect(response).not_to be_valid
+ end
+ end
+
+ describe '#reason' do
+ it 'returns a reason if it was included in the response body' do
+ expect(excon_response).to receive(:body).and_return({ reason: 'Not authorized' }.to_json)
+
+ expect(response.reason).to eq('Not authorized')
+ end
+
+ it 'returns nil when there was no body' do
+ expect(excon_response).to receive(:body).and_return('')
+
+ expect(response.reason).to eq(nil)
+ end
+ end
+
+ describe '#successful?' do
+ it 'is `true` if the status is 200' do
+ allow(excon_response).to receive(:status).and_return(200)
+
+ expect(response).to be_successful
+ end
+
+ it 'is `false` if the status is 401 or 403' do
+ [401, 403].each do |status|
+ allow(excon_response).to receive(:status).and_return(status)
+
+ expect(response).not_to be_successful
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/external_authorization_spec.rb b/spec/lib/gitlab/external_authorization_spec.rb
new file mode 100644
index 00000000000..7394fbfe0ce
--- /dev/null
+++ b/spec/lib/gitlab/external_authorization_spec.rb
@@ -0,0 +1,54 @@
+require 'spec_helper'
+
+describe Gitlab::ExternalAuthorization, :request_store do
+ include ExternalAuthorizationServiceHelpers
+
+ let(:user) { build(:user) }
+ let(:label) { 'dummy_label' }
+
+ describe '#access_allowed?' do
+ it 'is always true when the feature is disabled' do
+ # Not using `stub_application_setting` because the method is prepended in
+ # `EE::ApplicationSetting` which breaks when using `any_instance`
+ # https://gitlab.com/gitlab-org/gitlab-ce/issues/33587
+ expect(::Gitlab::CurrentSettings.current_application_settings)
+ .to receive(:external_authorization_service_enabled) { false }
+
+ expect(described_class).not_to receive(:access_for_user_to_label)
+
+ expect(described_class.access_allowed?(user, label)).to be_truthy
+ end
+ end
+
+ describe '#rejection_reason' do
+ it 'is always nil when the feature is disabled' do
+ expect(::Gitlab::CurrentSettings.current_application_settings)
+ .to receive(:external_authorization_service_enabled) { false }
+
+ expect(described_class).not_to receive(:access_for_user_to_label)
+
+ expect(described_class.rejection_reason(user, label)).to be_nil
+ end
+ end
+
+ describe '#access_for_user_to_label' do
+ it 'only loads the access once per request' do
+ enable_external_authorization_service_check
+
+ expect(::Gitlab::ExternalAuthorization::Access)
+ .to receive(:new).with(user, label).once.and_call_original
+
+ 2.times { described_class.access_for_user_to_label(user, label, nil) }
+ end
+
+ it 'logs the access request once per request' do
+ expect(::Gitlab::ExternalAuthorization::Logger)
+ .to receive(:log_access)
+ .with(an_instance_of(::Gitlab::ExternalAuthorization::Access),
+ 'the/project/path')
+ .once
+
+ 2.times { described_class.access_for_user_to_label(user, label, 'the/project/path') }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 06995604a24..ebb62124cb1 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -496,6 +496,7 @@ Project:
- merge_requests_ff_only_enabled
- merge_requests_rebase_enabled
- jobs_cache_index
+- external_authorization_classification_label
- pages_https_only
Author:
- name