From 8c7f4e9d5f36cff46365a7f8c4b9c21578c1e781 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 18 Jun 2020 11:18:50 +0000 Subject: Add latest changes from gitlab-org/gitlab@13-1-stable-ee --- spec/controllers/projects/jobs_controller_spec.rb | 196 +++++++++++++++++++++- 1 file changed, 195 insertions(+), 1 deletion(-) (limited to 'spec/controllers/projects/jobs_controller_spec.rb') diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb index ef1253edda5..44dcb0caab2 100644 --- a/spec/controllers/projects/jobs_controller_spec.rb +++ b/spec/controllers/projects/jobs_controller_spec.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'spec_helper' -describe Projects::JobsController, :clean_gitlab_redis_shared_state do +RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do include ApiHelpers include HttpIOHelpers @@ -1225,4 +1225,198 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do get :terminal_websocket_authorize, params: params.merge(extra_params) end end + + describe 'GET #proxy_websocket_authorize' do + let_it_be(:owner) { create(:owner) } + let_it_be(:admin) { create(:admin) } + let_it_be(:maintainer) { create(:user) } + let_it_be(:developer) { create(:user) } + let_it_be(:reporter) { create(:user) } + let_it_be(:guest) { create(:user) } + let_it_be(:project) { create(:project, :private, :repository, namespace: owner.namespace) } + let(:user) { maintainer } + let(:pipeline) { create(:ci_pipeline, project: project, source: :webide, config_source: :webide_source, user: user) } + let(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) } + let(:extra_params) { { id: job.id } } + let(:path) { :proxy_websocket_authorize } + let(:render_method) { :channel_websocket } + let(:expected_data) do + { + 'Channel' => { + 'Subprotocols' => ["terminal.gitlab.com"], + 'Url' => 'wss://localhost/proxy/build/default_port/', + 'Header' => { + 'Authorization' => [nil] + }, + 'MaxSessionTime' => nil, + 'CAPem' => nil + } + }.to_json + end + + before do + stub_feature_flags(build_service_proxy: true) + allow(job).to receive(:has_terminal?).and_return(true) + + project.add_maintainer(maintainer) + project.add_developer(developer) + project.add_reporter(reporter) + project.add_guest(guest) + + sign_in(user) + end + + context 'access rights' do + before do + allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil) + + make_request + end + + context 'with admin' do + let(:user) { admin } + + context 'when admin mode is enabled', :enable_admin_mode do + it 'returns 200' do + expect(response).to have_gitlab_http_status(:ok) + end + end + + context 'when admin mode is disabled' do + it 'returns 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'with owner' do + let(:user) { owner } + + it 'returns 200' do + expect(response).to have_gitlab_http_status(:ok) + end + end + + context 'with maintainer' do + let(:user) { maintainer } + + it 'returns 200' do + expect(response).to have_gitlab_http_status(:ok) + end + end + + context 'with developer' do + let(:user) { developer } + + it 'returns 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'with reporter' do + let(:user) { reporter } + + it 'returns 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'with guest' do + let(:user) { guest } + + it 'returns 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'with non member' do + let(:user) { create(:user) } + + it 'returns 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'when pipeline is not from a webide source' do + context 'with admin' do + let(:user) { admin } + let(:pipeline) { create(:ci_pipeline, project: project, source: :chat, user: user) } + + before do + allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil) + make_request + end + + it 'returns 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'when workhorse signature is valid' do + before do + allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil) + end + + context 'and the id is valid' do + it 'returns the proxy data for the service running in the job' do + make_request + + expect(response).to have_gitlab_http_status(:ok) + expect(response.headers["Content-Type"]).to eq(Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE) + expect(response.body).to eq(expected_data) + end + end + + context 'and the id is invalid' do + let(:extra_params) { { id: non_existing_record_id } } + + it 'returns 404' do + make_request + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'with invalid workhorse signature' do + it 'aborts with an exception' do + allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_raise(JWT::DecodeError) + + expect { make_request }.to raise_error(JWT::DecodeError) + end + end + + context 'when feature flag :build_service_proxy is disabled' do + let(:user) { admin } + + it 'returns 404' do + allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil) + stub_feature_flags(build_service_proxy: false) + + make_request + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + it 'converts the url scheme into wss' do + allow(Gitlab::Workhorse).to receive(:verify_api_request!).and_return(nil) + + expect(job.runner_session_url).to start_with('https://') + expect(Gitlab::Workhorse).to receive(:channel_websocket).with(a_hash_including(url: "wss://localhost/proxy/build/default_port/")) + + make_request + end + + def make_request + params = { + namespace_id: project.namespace.to_param, + project_id: project + } + + get path, params: params.merge(extra_params) + end + end end -- cgit v1.2.1