diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-04 12:08:21 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-08-04 12:08:21 +0300 |
commit | eada495948d07e4a1affffa1fa77bfd9730be1af (patch) | |
tree | 12473ea37a4602e06e54289711b8eb089efbf821 /spec/controllers | |
parent | b41e09c9ce655d61557a3513508952240506b161 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/controllers')
-rw-r--r-- | spec/controllers/groups/dependency_proxy_auth_controller_spec.rb | 57 | ||||
-rw-r--r-- | spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb | 269 |
2 files changed, 275 insertions, 51 deletions
diff --git a/spec/controllers/groups/dependency_proxy_auth_controller_spec.rb b/spec/controllers/groups/dependency_proxy_auth_controller_spec.rb index f67b2022219..50e19d5b482 100644 --- a/spec/controllers/groups/dependency_proxy_auth_controller_spec.rb +++ b/spec/controllers/groups/dependency_proxy_auth_controller_spec.rb @@ -30,16 +30,31 @@ RSpec.describe Groups::DependencyProxyAuthController do end context 'with valid JWT' do - let_it_be(:user) { create(:user) } + context 'user' do + let_it_be(:user) { create(:user) } - let(:jwt) { build_jwt(user) } - let(:token_header) { "Bearer #{jwt.encoded}" } + let(:jwt) { build_jwt(user) } + let(:token_header) { "Bearer #{jwt.encoded}" } - before do - request.headers['HTTP_AUTHORIZATION'] = token_header + before do + request.headers['HTTP_AUTHORIZATION'] = token_header + end + + it { is_expected.to have_gitlab_http_status(:success) } end - it { is_expected.to have_gitlab_http_status(:success) } + context 'deploy token' do + let_it_be(:user) { create(:deploy_token) } + + let(:jwt) { build_jwt(user) } + let(:token_header) { "Bearer #{jwt.encoded}" } + + before do + request.headers['HTTP_AUTHORIZATION'] = token_header + end + + it { is_expected.to have_gitlab_http_status(:success) } + end end context 'with invalid JWT' do @@ -51,7 +66,7 @@ RSpec.describe Groups::DependencyProxyAuthController do request.headers['HTTP_AUTHORIZATION'] = token_header end - it { is_expected.to have_gitlab_http_status(:not_found) } + it { is_expected.to have_gitlab_http_status(:unauthorized) } end context 'token with no user id' do @@ -61,7 +76,7 @@ RSpec.describe Groups::DependencyProxyAuthController do request.headers['HTTP_AUTHORIZATION'] = token_header end - it { is_expected.to have_gitlab_http_status(:not_found) } + it { is_expected.to have_gitlab_http_status(:unauthorized) } end context 'expired token' do @@ -76,6 +91,32 @@ RSpec.describe Groups::DependencyProxyAuthController do it { is_expected.to have_gitlab_http_status(:unauthorized) } end + + context 'expired deploy token' do + let_it_be(:user) { create(:deploy_token, :expired) } + + let(:jwt) { build_jwt(user) } + let(:token_header) { "Bearer #{jwt.encoded}" } + + before do + request.headers['HTTP_AUTHORIZATION'] = token_header + end + + it { is_expected.to have_gitlab_http_status(:unauthorized) } + end + + context 'revoked deploy token' do + let_it_be(:user) { create(:deploy_token, :revoked) } + + let(:jwt) { build_jwt(user) } + let(:token_header) { "Bearer #{jwt.encoded}" } + + before do + request.headers['HTTP_AUTHORIZATION'] = token_header + end + + it { is_expected.to have_gitlab_http_status(:unauthorized) } + end end end end diff --git a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb index 6417da34161..0f0fb781512 100644 --- a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb +++ b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb @@ -7,8 +7,8 @@ RSpec.describe Groups::DependencyProxyForContainersController do include DependencyProxyHelpers let_it_be(:user) { create(:user) } + let_it_be_with_reload(:group) { create(:group, :private) } - let(:group) { create(:group) } let(:token_response) { { status: :success, token: 'abcd1234' } } let(:jwt) { build_jwt(user) } let(:token_header) { "Bearer #{jwt.encoded}" } @@ -20,6 +20,8 @@ RSpec.describe Groups::DependencyProxyForContainersController do end context 'feature flag disabled' do + let_it_be(:group) { create(:group) } + before do stub_feature_flags(dependency_proxy_for_private_groups: false) end @@ -35,13 +37,12 @@ RSpec.describe Groups::DependencyProxyForContainersController do stub_feature_flags(dependency_proxy_for_private_groups: false) end - it 'redirects', :aggregate_failures do + it 'returns not found' do group.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) subject - expect(response).to have_gitlab_http_status(:redirect) - expect(response.location).to end_with(new_user_session_path) + expect(response).to have_gitlab_http_status(:not_found) end end @@ -53,21 +54,95 @@ RSpec.describe Groups::DependencyProxyForContainersController do request.headers['HTTP_AUTHORIZATION'] = token_header end - it { is_expected.to have_gitlab_http_status(:not_found) } + it { is_expected.to have_gitlab_http_status(:unauthorized) } end context 'with valid user that does not have access' do - let(:group) { create(:group, :private) } - before do - user = double('bad_user', id: 999) - token_header = "Bearer #{build_jwt(user).encoded}" request.headers['HTTP_AUTHORIZATION'] = token_header end it { is_expected.to have_gitlab_http_status(:not_found) } end + context 'deploy tokens with dependency_proxy_deploy_tokens disabled' do + before do + stub_feature_flags(dependency_proxy_deploy_tokens: false) + end + + context 'with deploy token from a different group,' do + let_it_be(:user) { create(:deploy_token, :group, :dependency_proxy_scopes) } + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + + context 'with revoked deploy token' do + let_it_be(:user) { create(:deploy_token, :revoked, :group, :dependency_proxy_scopes) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + + context 'with expired deploy token' do + let_it_be(:user) { create(:deploy_token, :expired, :group, :dependency_proxy_scopes) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + + context 'with deploy token with insufficient scopes' do + let_it_be(:user) { create(:deploy_token, :group) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + + context 'when a group is not found' do + before do + expect(Group).to receive(:find_by_full_path).and_return(nil) + end + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + end + + context 'deploy tokens with dependency_proxy_deploy_tokens enabled' do + context 'with deploy token from a different group,' do + let_it_be(:user) { create(:deploy_token, :group, :dependency_proxy_scopes) } + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + + context 'with revoked deploy token' do + let_it_be(:user) { create(:deploy_token, :revoked, :group, :dependency_proxy_scopes) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } + + it { is_expected.to have_gitlab_http_status(:unauthorized) } + end + + context 'with expired deploy token' do + let_it_be(:user) { create(:deploy_token, :expired, :group, :dependency_proxy_scopes) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } + + it { is_expected.to have_gitlab_http_status(:unauthorized) } + end + + context 'with deploy token with insufficient scopes' do + let_it_be(:user) { create(:deploy_token, :group) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + + context 'when a group is not found' do + before do + expect(Group).to receive(:find_by_full_path).and_return(nil) + end + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + end + context 'when user is not found' do before do allow(User).to receive(:find).and_return(nil) @@ -115,6 +190,25 @@ RSpec.describe Groups::DependencyProxyForContainersController do subject { get_manifest } + shared_examples 'a successful manifest pull' do + it 'sends a file' do + expect(controller).to receive(:send_file).with(manifest.file.path, type: manifest.content_type) + + subject + end + + it 'returns Content-Disposition: attachment', :aggregate_failures do + subject + + expect(response).to have_gitlab_http_status(:ok) + expect(response.headers['Docker-Content-Digest']).to eq(manifest.digest) + expect(response.headers['Content-Length']).to eq(manifest.size) + expect(response.headers['Docker-Distribution-Api-Version']).to eq(DependencyProxy::DISTRIBUTION_API_VERSION) + expect(response.headers['Etag']).to eq("\"#{manifest.digest}\"") + expect(response.headers['Content-Disposition']).to match(/^attachment/) + end + end + context 'feature enabled' do before do enable_dependency_proxy @@ -123,14 +217,6 @@ RSpec.describe Groups::DependencyProxyForContainersController do it_behaves_like 'without a token' it_behaves_like 'without permission' it_behaves_like 'feature flag disabled with private group' - it_behaves_like 'a package tracking event', described_class.name, 'pull_manifest' - - context 'with a cache entry' do - let(:pull_response) { { status: :success, manifest: manifest, from_cache: true } } - - it_behaves_like 'returning response status', :success - it_behaves_like 'a package tracking event', described_class.name, 'pull_manifest_from_cache' - end context 'remote token request fails' do let(:token_response) do @@ -141,6 +227,10 @@ RSpec.describe Groups::DependencyProxyForContainersController do } end + before do + group.add_reporter(user) + end + it 'proxies status from the remote token request', :aggregate_failures do subject @@ -158,6 +248,10 @@ RSpec.describe Groups::DependencyProxyForContainersController do } end + before do + group.add_reporter(user) + end + it 'proxies status from the remote manifest request', :aggregate_failures do subject @@ -166,21 +260,58 @@ RSpec.describe Groups::DependencyProxyForContainersController do end end - it 'sends a file' do - expect(controller).to receive(:send_file).with(manifest.file.path, type: manifest.content_type) + context 'a valid user' do + before do + group.add_reporter(user) + end - subject + it_behaves_like 'a successful manifest pull' + it_behaves_like 'a package tracking event', described_class.name, 'pull_manifest' + + context 'with a cache entry' do + let(:pull_response) { { status: :success, manifest: manifest, from_cache: true } } + + it_behaves_like 'returning response status', :success + it_behaves_like 'a package tracking event', described_class.name, 'pull_manifest_from_cache' + end + + context 'with dependency_proxy_deploy_tokens feature flag disabled' do + before do + stub_feature_flags(dependency_proxy_deploy_tokens: false) + end + + it_behaves_like 'a successful manifest pull' + end end - it 'returns Content-Disposition: attachment' do - subject + context 'a valid deploy token with dependency_proxy_deploy_tokens feature flag disabled' do + let_it_be(:user) { create(:deploy_token, :dependency_proxy_scopes, :group) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } - expect(response).to have_gitlab_http_status(:ok) - expect(response.headers['Docker-Content-Digest']).to eq(manifest.digest) - expect(response.headers['Content-Length']).to eq(manifest.size) - expect(response.headers['Docker-Distribution-Api-Version']).to eq(DependencyProxy::DISTRIBUTION_API_VERSION) - expect(response.headers['Etag']).to eq("\"#{manifest.digest}\"") - expect(response.headers['Content-Disposition']).to match(/^attachment/) + before do + stub_feature_flags(dependency_proxy_deploy_tokens: false) + end + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + + context 'a valid deploy token' do + let_it_be(:user) { create(:deploy_token, :dependency_proxy_scopes, :group) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } + + it_behaves_like 'a successful manifest pull' + + context 'pulling from a subgroup' do + let_it_be_with_reload(:parent_group) { create(:group) } + let_it_be_with_reload(:group) { create(:group, parent: parent_group) } + + before do + parent_group.create_dependency_proxy_setting!(enabled: true) + group_deploy_token.update_column(:group_id, parent_group.id) + end + + it_behaves_like 'a successful manifest pull' + end end end @@ -203,6 +334,21 @@ RSpec.describe Groups::DependencyProxyForContainersController do end end + shared_examples 'a successful blob pull' do + it 'sends a file' do + expect(controller).to receive(:send_file).with(blob.file.path, {}) + + subject + end + + it 'returns Content-Disposition: attachment', :aggregate_failures do + subject + + expect(response).to have_gitlab_http_status(:ok) + expect(response.headers['Content-Disposition']).to match(/^attachment/) + end + end + subject { get_blob } context 'feature enabled' do @@ -213,14 +359,6 @@ RSpec.describe Groups::DependencyProxyForContainersController do it_behaves_like 'without a token' it_behaves_like 'without permission' it_behaves_like 'feature flag disabled with private group' - it_behaves_like 'a package tracking event', described_class.name, 'pull_blob' - - context 'with a cache entry' do - let(:blob_response) { { status: :success, blob: blob, from_cache: true } } - - it_behaves_like 'returning response status', :success - it_behaves_like 'a package tracking event', described_class.name, 'pull_blob_from_cache' - end context 'remote blob request fails' do let(:blob_response) do @@ -231,6 +369,10 @@ RSpec.describe Groups::DependencyProxyForContainersController do } end + before do + group.add_reporter(user) + end + it 'proxies status from the remote blob request', :aggregate_failures do subject @@ -239,17 +381,58 @@ RSpec.describe Groups::DependencyProxyForContainersController do end end - it 'sends a file' do - expect(controller).to receive(:send_file).with(blob.file.path, {}) + context 'a valid user' do + before do + group.add_reporter(user) + end - subject + it_behaves_like 'a successful blob pull' + it_behaves_like 'a package tracking event', described_class.name, 'pull_blob' + + context 'with a cache entry' do + let(:blob_response) { { status: :success, blob: blob, from_cache: true } } + + it_behaves_like 'returning response status', :success + it_behaves_like 'a package tracking event', described_class.name, 'pull_blob_from_cache' + end + + context 'with dependency_proxy_deploy_tokens feature flag disabled' do + before do + stub_feature_flags(dependency_proxy_deploy_tokens: false) + end + + it_behaves_like 'a successful blob pull' + end end - it 'returns Content-Disposition: attachment', :aggregate_failures do - subject + context 'a valid deploy token with dependency_proxy_deploy_tokens feature flag disabled' do + let_it_be(:user) { create(:deploy_token, :group, :dependency_proxy_scopes) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } - expect(response).to have_gitlab_http_status(:ok) - expect(response.headers['Content-Disposition']).to match(/^attachment/) + before do + stub_feature_flags(dependency_proxy_deploy_tokens: false) + end + + it { is_expected.to have_gitlab_http_status(:not_found) } + end + + context 'a valid deploy token' do + let_it_be(:user) { create(:deploy_token, :group, :dependency_proxy_scopes) } + let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: user, group: group) } + + it_behaves_like 'a successful blob pull' + + context 'pulling from a subgroup' do + let_it_be_with_reload(:parent_group) { create(:group) } + let_it_be_with_reload(:group) { create(:group, parent: parent_group) } + + before do + parent_group.create_dependency_proxy_setting!(enabled: true) + group_deploy_token.update_column(:group_id, parent_group.id) + end + + it_behaves_like 'a successful blob pull' + end end end |