Reland "[remoting host] Create SessionAuthz playground binary"
This is a reland of commit a803632d1b
Change since original CL:
Disable executable from unsupported platforms (e.g. Wayland &
Lacros).
Original change's description:
> [remoting host] Create SessionAuthz playground binary
>
> This CL creates a SessionAuthz playground binary. It allows for testing
> the SessionAuthz API with the host's robot account authority.
>
> Bug: b/323068262
> Change-Id: Idf4d6c4b7b82d1af55ee1aa15478ed35b0bb7394
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5263241
> Reviewed-by: Joe Downing <joedow@chromium.org>
> Commit-Queue: Yuwei Huang <yuweih@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1256878}
Bug: b/323068262
Change-Id: I0dcf12e9e5202f310268bb400980f37622877f98
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5274561
Commit-Queue: Joe Downing <joedow@chromium.org>
Reviewed-by: Joe Downing <joedow@chromium.org>
Auto-Submit: Yuwei Huang <yuweih@chromium.org>
Commit-Queue: Yuwei Huang <yuweih@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1257035}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
71348e844c
commit
921c76f82d
@ -219,3 +219,25 @@ executable("ftl_signaling_playground") {
|
||||
"//services/network:network_service",
|
||||
]
|
||||
}
|
||||
|
||||
if (enable_me2me_host && is_linux) {
|
||||
# A binary for testing and fiddling the SessionAuthz service.
|
||||
executable("session_authz_playground") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"session_authz_playground.cc",
|
||||
"session_authz_playground.h",
|
||||
"session_authz_playground_main.cc",
|
||||
]
|
||||
deps = [
|
||||
":test_support",
|
||||
"//mojo/core/embedder",
|
||||
"//remoting/base",
|
||||
"//remoting/base:authorization",
|
||||
"//remoting/base:logging",
|
||||
"//remoting/host",
|
||||
"//remoting/proto:internal_structs",
|
||||
"//services/network:network_service",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
197
remoting/test/session_authz_playground.cc
Normal file
197
remoting/test/session_authz_playground.cc
Normal file
@ -0,0 +1,197 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "remoting/test/session_authz_playground.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/task/bind_post_task.h"
|
||||
#include "base/task/single_thread_task_runner.h"
|
||||
#include "remoting/base/oauth_token_getter.h"
|
||||
#include "remoting/base/oauth_token_getter_impl.h"
|
||||
#include "remoting/base/url_request_context_getter.h"
|
||||
#include "remoting/host/host_config.h"
|
||||
#include "remoting/proto/session_authz_service.h"
|
||||
#include "remoting/test/cli_util.h"
|
||||
|
||||
namespace remoting {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kOAuthScope[] =
|
||||
"https://www.googleapis.com/auth/chromoting.me2me.host";
|
||||
|
||||
void PrintErrorAndExit(const std::string& api_name,
|
||||
const ProtobufHttpStatus& status) {
|
||||
fprintf(stderr, "Failed to call API: %s, error code: %d\n", api_name.data(),
|
||||
static_cast<int>(status.error_code()));
|
||||
fprintf(stderr, "%s\n", status.error_message().data());
|
||||
fprintf(stderr, "%s\n", status.response_body().data());
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SessionAuthzPlayground::SessionAuthzPlayground() {
|
||||
auto url_request_context_getter =
|
||||
base::MakeRefCounted<URLRequestContextGetter>(
|
||||
base::SingleThreadTaskRunner::GetCurrentDefault());
|
||||
url_loader_factory_owner_ =
|
||||
std::make_unique<network::TransitionalURLLoaderFactoryOwner>(
|
||||
url_request_context_getter, /* is_trusted= */ true);
|
||||
}
|
||||
|
||||
SessionAuthzPlayground::~SessionAuthzPlayground() = default;
|
||||
|
||||
void SessionAuthzPlayground::Start() {
|
||||
auto* cmd_line = base::CommandLine::ForCurrentProcess();
|
||||
base::CommandLine::StringVector args = cmd_line->GetArgs();
|
||||
base::FilePath host_config_file_path;
|
||||
if (args.size() == 1) {
|
||||
host_config_file_path = base::FilePath(args[0]);
|
||||
}
|
||||
if (host_config_file_path.empty()) {
|
||||
printf("Usage: %s <path-to-host-config-json>\n",
|
||||
cmd_line->GetProgram().MaybeAsASCII().c_str());
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
service_client_ = std::make_unique<CorpSessionAuthzServiceClient>(
|
||||
url_loader_factory_owner_->GetURLLoaderFactory(),
|
||||
CreateOAuthTokenGetter(host_config_file_path));
|
||||
|
||||
run_loop_ = std::make_unique<base::RunLoop>();
|
||||
GenerateHostToken();
|
||||
run_loop_->Run();
|
||||
}
|
||||
|
||||
void SessionAuthzPlayground::GenerateHostToken() {
|
||||
printf("Fetching host token...\n");
|
||||
service_client_->GenerateHostToken(
|
||||
base::BindOnce(
|
||||
[](const ProtobufHttpStatus& status,
|
||||
std::unique_ptr<internal::GenerateHostTokenResponseStruct>
|
||||
response) {
|
||||
if (!status.ok()) {
|
||||
PrintErrorAndExit("GenerateHostToken", status);
|
||||
}
|
||||
if (!response) {
|
||||
fprintf(stderr, "No response was received.\n");
|
||||
}
|
||||
printf("Host token: %s\n", response->host_token.data());
|
||||
printf("Session ID: %s\n", response->session_id.data());
|
||||
return response->session_id;
|
||||
})
|
||||
.Then(base::BindPostTaskToCurrentDefault(
|
||||
base::BindOnce(&SessionAuthzPlayground::VerifySessionToken,
|
||||
base::Unretained(this)))));
|
||||
}
|
||||
|
||||
void SessionAuthzPlayground::VerifySessionToken(const std::string& session_id) {
|
||||
printf("Enter session token generated by the client: ");
|
||||
std::string session_token = test::ReadString();
|
||||
internal::VerifySessionTokenRequestStruct request;
|
||||
request.session_token = session_token;
|
||||
service_client_->VerifySessionToken(
|
||||
request,
|
||||
base::BindOnce(
|
||||
[](const std::string& session_id, const ProtobufHttpStatus& status,
|
||||
std::unique_ptr<internal::VerifySessionTokenResponseStruct>
|
||||
response) {
|
||||
if (!status.ok()) {
|
||||
PrintErrorAndExit("VerifySessionToken", status);
|
||||
}
|
||||
if (!response) {
|
||||
fprintf(stderr, "No response was received.\n");
|
||||
}
|
||||
printf("Reauth token: %s\n", response->session_reauth_token.data());
|
||||
printf("Reauth token expires in: %fs\n",
|
||||
response->session_reauth_token_lifetime.InSecondsF());
|
||||
printf("Session ID: %s\n", response->session_id.data());
|
||||
printf("Shared secret: %s\n", response->shared_secret.data());
|
||||
if (session_id != response->session_id) {
|
||||
fprintf(stderr, "Unexpected session ID. Expected: %s\n",
|
||||
session_id.data());
|
||||
std::exit(1);
|
||||
}
|
||||
return response->session_reauth_token;
|
||||
},
|
||||
session_id)
|
||||
.Then(base::BindPostTaskToCurrentDefault(
|
||||
base::BindPostTaskToCurrentDefault(
|
||||
base::BindOnce(&SessionAuthzPlayground::ReauthorizeHost,
|
||||
base::Unretained(this), session_id)))));
|
||||
}
|
||||
|
||||
void SessionAuthzPlayground::ReauthorizeHost(const std::string& session_id,
|
||||
const std::string& reauth_token) {
|
||||
printf("Reauthorize host? [y/N]: ");
|
||||
bool shouldReauthorize = test::ReadYNBool();
|
||||
if (!shouldReauthorize) {
|
||||
run_loop_->Quit();
|
||||
}
|
||||
internal::ReauthorizeHostRequestStruct request;
|
||||
request.session_id = session_id;
|
||||
request.session_reauth_token = reauth_token;
|
||||
service_client_->ReauthorizeHost(
|
||||
request,
|
||||
base::BindOnce([](const ProtobufHttpStatus& status,
|
||||
std::unique_ptr<internal::ReauthorizeHostResponseStruct>
|
||||
response) {
|
||||
if (!status.ok()) {
|
||||
PrintErrorAndExit("ReauthorizeHost", status);
|
||||
}
|
||||
if (!response) {
|
||||
fprintf(stderr, "No response was received.\n");
|
||||
}
|
||||
printf("Reauth token: %s\n", response->session_reauth_token.data());
|
||||
printf("Reauth token expires in: %fs\n",
|
||||
response->session_reauth_token_lifetime.InSecondsF());
|
||||
return response->session_reauth_token;
|
||||
})
|
||||
.Then(base::BindPostTaskToCurrentDefault(
|
||||
base::BindOnce(&SessionAuthzPlayground::ReauthorizeHost,
|
||||
base::Unretained(this), session_id))));
|
||||
}
|
||||
|
||||
std::unique_ptr<OAuthTokenGetter>
|
||||
SessionAuthzPlayground::CreateOAuthTokenGetter(
|
||||
const base::FilePath& host_config_file_path) {
|
||||
auto host_config_dict = HostConfigFromJsonFile(host_config_file_path);
|
||||
if (!host_config_dict.has_value()) {
|
||||
fprintf(stderr, "Cannot read host config file: %s\n",
|
||||
host_config_file_path.MaybeAsASCII().data());
|
||||
std::exit(1);
|
||||
}
|
||||
const std::string* refresh_token =
|
||||
host_config_dict->FindString(kOAuthRefreshTokenConfigPath);
|
||||
if (!refresh_token) {
|
||||
fprintf(stderr, "Cannot find OAuth refresh token from host config file.\n");
|
||||
std::exit(1);
|
||||
}
|
||||
const std::string* service_account_email =
|
||||
host_config_dict->FindString(kServiceAccountConfigPath);
|
||||
if (!service_account_email) {
|
||||
fprintf(stderr, "Cannot find service account email.\n");
|
||||
std::exit(1);
|
||||
}
|
||||
auto oauth_credentials =
|
||||
std::make_unique<OAuthTokenGetter::OAuthAuthorizationCredentials>(
|
||||
*service_account_email, *refresh_token,
|
||||
/* is_service_account= */ true,
|
||||
std::vector<std::string>{kOAuthScope});
|
||||
return std::make_unique<OAuthTokenGetterImpl>(
|
||||
std::move(oauth_credentials),
|
||||
url_loader_factory_owner_->GetURLLoaderFactory(), false);
|
||||
}
|
||||
|
||||
} // namespace remoting
|
44
remoting/test/session_authz_playground.h
Normal file
44
remoting/test/session_authz_playground.h
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef REMOTING_TEST_SESSION_AUTHZ_PLAYGROUND_H_
|
||||
#define REMOTING_TEST_SESSION_AUTHZ_PLAYGROUND_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/run_loop.h"
|
||||
#include "remoting/base/corp_session_authz_service_client.h"
|
||||
#include "remoting/base/oauth_token_getter.h"
|
||||
#include "remoting/base/protobuf_http_status.h"
|
||||
#include "services/network/transitional_url_loader_factory_owner.h"
|
||||
|
||||
namespace remoting {
|
||||
|
||||
class SessionAuthzPlayground {
|
||||
public:
|
||||
SessionAuthzPlayground();
|
||||
~SessionAuthzPlayground();
|
||||
|
||||
SessionAuthzPlayground(const SessionAuthzPlayground&) = delete;
|
||||
SessionAuthzPlayground& operator=(const SessionAuthzPlayground&) = delete;
|
||||
|
||||
void Start();
|
||||
|
||||
private:
|
||||
void GenerateHostToken();
|
||||
void VerifySessionToken(const std::string& session_id);
|
||||
void ReauthorizeHost(const std::string& session_id,
|
||||
const std::string& reauth_token);
|
||||
std::unique_ptr<OAuthTokenGetter> CreateOAuthTokenGetter(
|
||||
const base::FilePath& host_config_file_path);
|
||||
|
||||
std::unique_ptr<network::TransitionalURLLoaderFactoryOwner>
|
||||
url_loader_factory_owner_;
|
||||
std::unique_ptr<base::RunLoop> run_loop_;
|
||||
std::unique_ptr<CorpSessionAuthzServiceClient> service_client_;
|
||||
};
|
||||
|
||||
} // namespace remoting
|
||||
|
||||
#endif // REMOTING_TEST_SESSION_AUTHZ_PLAYGROUND_H_
|
22
remoting/test/session_authz_playground_main.cc
Normal file
22
remoting/test/session_authz_playground_main.cc
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "base/at_exit.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/task/single_thread_task_executor.h"
|
||||
#include "base/task/thread_pool/thread_pool_instance.h"
|
||||
#include "mojo/core/embedder/embedder.h"
|
||||
#include "remoting/test/session_authz_playground.h"
|
||||
|
||||
int main(int argc, char const* argv[]) {
|
||||
base::AtExitManager exitManager;
|
||||
base::CommandLine::Init(argc, argv);
|
||||
base::SingleThreadTaskExecutor io_task_executor(base::MessagePumpType::IO);
|
||||
base::ThreadPoolInstance::CreateAndStartWithDefaultParams(
|
||||
"SessionAuthzPlayground");
|
||||
mojo::core::Init();
|
||||
|
||||
remoting::SessionAuthzPlayground().Start();
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user