diff options
Diffstat (limited to 'app/controllers/projects/jobs_controller.rb')
-rw-r--r-- | app/controllers/projects/jobs_controller.rb | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb index e0457925b34..e1f6cbe3dca 100644 --- a/app/controllers/projects/jobs_controller.rb +++ b/app/controllers/projects/jobs_controller.rb @@ -14,6 +14,8 @@ class Projects::JobsController < Projects::ApplicationController before_action only: [:show] do push_frontend_feature_flag(:job_log_json, project, default_enabled: true) end + before_action :authorize_create_proxy_build!, only: :proxy_websocket_authorize + before_action :verify_proxy_request!, only: :proxy_websocket_authorize layout 'project' @@ -151,6 +153,10 @@ class Projects::JobsController < Projects::ApplicationController render json: Gitlab::Workhorse.channel_websocket(@build.terminal_specification) end + def proxy_websocket_authorize + render json: proxy_websocket_service(build_service_specification) + end + private def authorize_update_build! @@ -165,10 +171,19 @@ class Projects::JobsController < Projects::ApplicationController return access_denied! unless can?(current_user, :create_build_terminal, build) end + def authorize_create_proxy_build! + return access_denied! unless can?(current_user, :create_build_service_proxy, build) + end + def verify_api_request! Gitlab::Workhorse.verify_api_request!(request.headers) end + def verify_proxy_request! + verify_api_request! + set_workhorse_internal_api_content_type + end + def raw_send_params { type: 'text/plain; charset=utf-8', disposition: 'inline' } end @@ -202,6 +217,27 @@ class Projects::JobsController < Projects::ApplicationController 'attachment' end -end -Projects::JobsController.prepend_if_ee('EE::Projects::JobsController') + def build_service_specification + build.service_specification(service: params['service'], + port: params['port'], + path: params['path'], + subprotocols: proxy_subprotocol) + end + + def proxy_subprotocol + # This will allow to reuse the same subprotocol set + # in the original websocket connection + request.headers['HTTP_SEC_WEBSOCKET_PROTOCOL'].presence || ::Ci::BuildRunnerSession::TERMINAL_SUBPROTOCOL + end + + # This method provides the information to Workhorse + # about the service we want to proxy to. + # For security reasons, in case this operation is started by JS, + # it's important to use only sourced GitLab JS code + def proxy_websocket_service(service) + service[:url] = ::Gitlab::UrlHelpers.as_wss(service[:url]) + + ::Gitlab::Workhorse.channel_websocket(service) + end +end |