From 1ef777bffd5e64ea5764920a30998a4d7c5241e3 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 27 Oct 2021 10:18:40 +0000 Subject: Add latest changes from gitlab-org/security/gitlab@14-4-stable-ee --- spec/requests/api/applications_spec.rb | 62 ++++++++++++++++++++++++++------ spec/requests/api/project_import_spec.rb | 34 ++++++++++++++++-- 2 files changed, 83 insertions(+), 13 deletions(-) (limited to 'spec/requests') diff --git a/spec/requests/api/applications_spec.rb b/spec/requests/api/applications_spec.rb index 959e68e6a0d..022451553ee 100644 --- a/spec/requests/api/applications_spec.rb +++ b/spec/requests/api/applications_spec.rb @@ -5,13 +5,14 @@ require 'spec_helper' RSpec.describe API::Applications, :api do let(:admin_user) { create(:user, admin: true) } let(:user) { create(:user, admin: false) } - let!(:application) { create(:application, name: 'another_application', owner: nil, redirect_uri: 'http://other_application.url', scopes: '') } + let(:scopes) { 'api' } + let!(:application) { create(:application, name: 'another_application', owner: nil, redirect_uri: 'http://other_application.url', scopes: scopes) } describe 'POST /applications' do context 'authenticated and authorized user' do it 'creates and returns an OAuth application' do expect do - post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: '' } + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: scopes } end.to change { Doorkeeper::Application.count }.by 1 application = Doorkeeper::Application.find_by(name: 'application_name', redirect_uri: 'http://application.url') @@ -22,11 +23,12 @@ RSpec.describe API::Applications, :api do expect(json_response['secret']).to eq application.secret expect(json_response['callback_url']).to eq application.redirect_uri expect(json_response['confidential']).to eq application.confidential + expect(application.scopes.to_s).to eq('api') end it 'does not allow creating an application with the wrong redirect_uri format' do expect do - post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://', scopes: '' } + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://', scopes: scopes } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(:bad_request) @@ -36,7 +38,7 @@ RSpec.describe API::Applications, :api do it 'does not allow creating an application with a forbidden URI format' do expect do - post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'javascript://alert()', scopes: '' } + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'javascript://alert()', scopes: scopes } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(:bad_request) @@ -46,7 +48,7 @@ RSpec.describe API::Applications, :api do it 'does not allow creating an application without a name' do expect do - post api('/applications', admin_user), params: { redirect_uri: 'http://application.url', scopes: '' } + post api('/applications', admin_user), params: { redirect_uri: 'http://application.url', scopes: scopes } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(:bad_request) @@ -56,7 +58,7 @@ RSpec.describe API::Applications, :api do it 'does not allow creating an application without a redirect_uri' do expect do - post api('/applications', admin_user), params: { name: 'application_name', scopes: '' } + post api('/applications', admin_user), params: { name: 'application_name', scopes: scopes } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(:bad_request) @@ -64,19 +66,59 @@ RSpec.describe API::Applications, :api do expect(json_response['error']).to eq('redirect_uri is missing') end - it 'does not allow creating an application without scopes' do + it 'does not allow creating an application without specifying `scopes`' do expect do post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url' } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(:bad_request) expect(json_response).to be_a Hash - expect(json_response['error']).to eq('scopes is missing') + expect(json_response['error']).to eq('scopes is missing, scopes is empty') + end + + it 'does not allow creating an application with blank `scopes`' do + expect do + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: '' } + end.not_to change { Doorkeeper::Application.count } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['error']).to eq('scopes is empty') + end + + it 'does not allow creating an application with invalid `scopes`' do + expect do + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: 'non_existent_scope' } + end.not_to change { Doorkeeper::Application.count } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['message']['scopes'][0]).to eq('doesn\'t match configured on the server.') + end + + context 'multiple scopes' do + it 'creates an application with multiple `scopes` when each scope specified is seperated by a space' do + expect do + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: 'api read_user' } + end.to change { Doorkeeper::Application.count }.by 1 + + application = Doorkeeper::Application.last + + expect(response).to have_gitlab_http_status(:created) + expect(application.scopes.to_s).to eq('api read_user') + end + + it 'does not allow creating an application with multiple `scopes` when one of the scopes is invalid' do + expect do + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: 'api non_existent_scope' } + end.not_to change { Doorkeeper::Application.count } + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response['message']['scopes'][0]).to eq('doesn\'t match configured on the server.') + end end it 'defaults to creating an application with confidential' do expect do - post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: '', confidential: nil } + post api('/applications', admin_user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: scopes, confidential: nil } end.to change { Doorkeeper::Application.count }.by(1) expect(response).to have_gitlab_http_status(:created) @@ -89,7 +131,7 @@ RSpec.describe API::Applications, :api do context 'authorized user without authorization' do it 'does not create application' do expect do - post api('/applications', user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: '' } + post api('/applications', user), params: { name: 'application_name', redirect_uri: 'http://application.url', scopes: scopes } end.not_to change { Doorkeeper::Application.count } expect(response).to have_gitlab_http_status(:forbidden) diff --git a/spec/requests/api/project_import_spec.rb b/spec/requests/api/project_import_spec.rb index d3b24eb3832..0c9e125cc90 100644 --- a/spec/requests/api/project_import_spec.rb +++ b/spec/requests/api/project_import_spec.rb @@ -16,6 +16,16 @@ RSpec.describe API::ProjectImport do namespace.add_owner(user) end + shared_examples 'requires authentication' do + let(:user) { nil } + + it 'returns 401' do + subject + + expect(response).to have_gitlab_http_status(:unauthorized) + end + end + describe 'POST /projects/import' do subject { upload_archive(file_upload, workhorse_headers, params) } @@ -32,6 +42,8 @@ RSpec.describe API::ProjectImport do allow(ImportExportUploader).to receive(:workhorse_upload_path).and_return('/') end + it_behaves_like 'requires authentication' + it 'executes a limited number of queries' do control_count = ActiveRecord::QueryRecorder.new { subject }.count @@ -281,6 +293,10 @@ RSpec.describe API::ProjectImport do end describe 'POST /projects/remote-import' do + subject do + post api('/projects/remote-import', user), params: params + end + let(:params) do { path: 'test-import', @@ -288,10 +304,12 @@ RSpec.describe API::ProjectImport do } end + it_behaves_like 'requires authentication' + it 'returns NOT FOUND when the feature is disabled' do stub_feature_flags(import_project_from_remote_file: false) - post api('/projects/remote-import', user), params: params + subject expect(response).to have_gitlab_http_status(:not_found) end @@ -315,7 +333,7 @@ RSpec.describe API::ProjectImport do .to receive(:execute) .and_return(service_response) - post api('/projects/remote-import', user), params: params + subject expect(response).to have_gitlab_http_status(:created) expect(json_response).to include({ @@ -338,7 +356,7 @@ RSpec.describe API::ProjectImport do .to receive(:execute) .and_return(service_response) - post api('/projects/remote-import', user), params: params + subject expect(response).to have_gitlab_http_status(:bad_request) expect(json_response).to eq({ @@ -350,6 +368,14 @@ RSpec.describe API::ProjectImport do end describe 'GET /projects/:id/import' do + it 'public project accessible for an unauthenticated user' do + project = create(:project, :public) + + get api("/projects/#{project.id}/import", nil) + + expect(response).to have_gitlab_http_status(:ok) + end + it 'returns the import status' do project = create(:project, :import_started) project.add_maintainer(user) @@ -376,6 +402,8 @@ RSpec.describe API::ProjectImport do describe 'POST /projects/import/authorize' do subject { post api('/projects/import/authorize', user), headers: workhorse_headers } + it_behaves_like 'requires authentication' + it 'authorizes importing project with workhorse header' do subject -- cgit v1.2.3