53 lines
1.6 KiB
Ruby
53 lines
1.6 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'uri'
|
|
|
|
module WebIde
|
|
class RemoteIdeController < ApplicationController
|
|
include VSCodeCDNCSP
|
|
|
|
rescue_from URI::InvalidComponentError, with: :render_404
|
|
|
|
before_action :allow_remote_ide_content_security_policy
|
|
|
|
feature_category :remote_development
|
|
|
|
urgency :low
|
|
|
|
def index
|
|
return render_404 unless Feature.enabled?(:vscode_web_ide, current_user)
|
|
|
|
render layout: 'fullscreen', locals: { minimal: true, data: root_element_data }
|
|
end
|
|
|
|
private
|
|
|
|
def allow_remote_ide_content_security_policy
|
|
return if request.content_security_policy.directives.blank?
|
|
|
|
default_src = Array(request.content_security_policy.directives['default-src'] || [])
|
|
|
|
request.content_security_policy.directives['connect-src'] ||= default_src
|
|
request.content_security_policy.directives['connect-src'].concat(connect_src_urls)
|
|
end
|
|
|
|
def connect_src_urls
|
|
# It's okay if "port" is null
|
|
host, port = params.require(:remote_host).split(':')
|
|
|
|
# This could throw URI::InvalidComponentError. We go ahead and let it throw
|
|
# and let the controller recover with a bad_request response
|
|
%w[ws wss http https].map { |scheme| URI::Generic.build(scheme: scheme, host: host, port: port).to_s }
|
|
end
|
|
|
|
def root_element_data
|
|
{
|
|
connection_token: params.fetch(:connection_token, ''),
|
|
remote_host: params.require(:remote_host),
|
|
remote_path: params.fetch(:remote_path, ''),
|
|
return_url: params.fetch(:return_url, ''),
|
|
csp_nonce: content_security_policy_nonce
|
|
}
|
|
end
|
|
end
|
|
end
|