summaryrefslogtreecommitdiff
path: root/app/controllers/projects/jobs_controller.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/projects/jobs_controller.rb')
-rw-r--r--app/controllers/projects/jobs_controller.rb40
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