Web shell allows access to the ubi command line program without installing it. All features of ubi are available in the web shell, except for the program execution features. To avoid the need to create a personal access token to use the web shell, the internal cli request sets clover.web_cli_session_id in the request environment, and the internal request uses that as the session id if that exists. So web cli requests are only checked against the account's permissions, they are not checked against a token's permissions. I think this approach is better than forcing a user to create a personal access token to use the web shell. For ease of use, this uses the autofocus attribute, so add that as a boolean attribute.
80 lines
2.4 KiB
Ruby
80 lines
2.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Clover
|
|
ubi_version = File.read(File.expand_path("../../../cli/version.txt", __FILE__)).chomp.freeze
|
|
|
|
hash_branch(:project_prefix, "cli") do |r|
|
|
r.web do
|
|
r.is do
|
|
no_authorization_needed
|
|
|
|
r.get do
|
|
view "cli"
|
|
end
|
|
|
|
r.post do
|
|
no_audit_log
|
|
|
|
if (multi_cli = typecast_body_params.nonempty_str("multi-cli"))
|
|
multi_cli = multi_cli.split(/\r?\n/)
|
|
multi_cli.reject!(&:empty?)
|
|
@last_cli, @cli, *@clis = multi_cli
|
|
else
|
|
@last_cli = typecast_body_params.str!("cli")
|
|
r.POST.delete("cli")
|
|
|
|
if (@clis = typecast_body_params.array(:nonempty_str, "clis"))
|
|
@cli = @clis.shift
|
|
end
|
|
|
|
if (confirm = typecast_body_params.nonempty_str("confirm"))
|
|
@last_cli = "--confirm #{confirm.inspect} #{@last_cli}"
|
|
end
|
|
end
|
|
|
|
@last_cli = @last_cli.sub(/\A\s*ubi\s+/, "")
|
|
argv = @last_cli.shellsplit
|
|
|
|
env["clover.project_id"] = @project.id
|
|
env["clover.project_ubid"] = @project.ubid
|
|
env["clover.web_cli_session_id"] = rodauth.session_value
|
|
env["HTTP_X_UBI_VERSION"] = ubi_version
|
|
env["CONTENT_TYPE"] = "application/json"
|
|
|
|
# Need to save the host and restore it afterward for rack-test to work correctly
|
|
host = env["HTTP_HOST"]
|
|
env["HTTP_HOST"] = "api.ubicloud.com"
|
|
_, headers, body = UbiCli.process(argv, env)
|
|
env["HTTP_HOST"] = host
|
|
|
|
body = body.join
|
|
@output = if (@ubi_command_execute = headers["ubi-command-execute"])
|
|
h("$ #{body.split("\0").prepend(@ubi_command_execute).shelljoin}")
|
|
else
|
|
ubids = {}
|
|
body.scan(UbiCli::OBJECT_INFO_REGEXP) { ubids[UBID.to_uuid(it[0])] ||= nil }
|
|
UBID.resolve_map(ubids)
|
|
h(body).gsub(UbiCli::OBJECT_INFO_REGEXP) do
|
|
if (obj = ubids[UBID.to_uuid(it)]) && obj.respond_to?(:path)
|
|
"<a class=\"text-orange-600\" href=\"#{@project.path}#{obj.path}\">#{it}</a>"
|
|
else
|
|
it
|
|
end
|
|
end
|
|
end
|
|
|
|
if (@ubi_confirm = headers["ubi-confirm"])
|
|
if @cli
|
|
@clis ||= []
|
|
@clis.prepend(@cli)
|
|
end
|
|
@cli = @last_cli
|
|
end
|
|
|
|
view "cli"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|