Commit accb9e4e authored by Denis Kuznetsov's avatar Denis Kuznetsov Committed by Commit Bot

[CRD for Kiosk] Fetch OAuth token, ICE config

Bug: 864455
Change-Id: Ic3396019ae040845ff8938a894828e56db7db55f
Reviewed-on: https://chromium-review.googlesource.com/1156511
Commit-Queue: Denis Kuznetsov <antrim@chromium.org>
Reviewed-by: default avatarPavol Marko <pmarko@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580543}
parent 3d470614
...@@ -4,18 +4,82 @@ ...@@ -4,18 +4,82 @@
#include "chrome/browser/chromeos/policy/remote_commands/crd_host_delegate.h" #include "chrome/browser/chromeos/policy/remote_commands/crd_host_delegate.h"
#include "base/json/json_reader.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "content/public/browser/storage_partition.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/oauth2_token_service.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "ui/base/user_activity/user_activity_detector.h" #include "ui/base/user_activity/user_activity_detector.h"
namespace policy { namespace policy {
CRDHostDelegate::CRDHostDelegate() {} namespace {
const char kICEConfigURL[] =
"https://www.googleapis.com/chromoting/v1/@me/iceconfig";
// OAuth2 Token scopes
constexpr char kCloudDevicesOAuth2Scope[] =
"https://www.googleapis.com/auth/clouddevices";
constexpr char kChromotingOAuth2Scope[] =
"https://www.googleapis.com/auth/chromoting";
net::NetworkTrafficAnnotationTag CreateIceConfigRequestAnnotation() {
return net::DefineNetworkTrafficAnnotation("CRD_ice_config_request", R"(
semantics {
sender: "Chrome Remote Desktop"
description:
"Request is used by Chrome Remote Desktop to fetch ICE "
"configuration which contains list of STUN & TURN servers and TURN "
"credentials."
trigger:
"When a Chrome Remote Desktop session is being connected and "
"periodically while a session is active, as necessary. Currently "
"the API issues credentials that expire every 24 hours, so this "
"request will only be sent again while session is active more than "
"24 hours and it needs to renegotiate the ICE connection. The 24 "
"hour period is controlled by the server and may change. In some "
"cases, e.g. if direct connection is used, it will not trigger "
"periodically."
data: "None."
destination: GOOGLE_OWNED_SERVICE
}
policy {
cookies_allowed: NO
setting:
"This feature cannot be disabled by settings. You can block Chrome "
"Remote Desktop as specified here: "
"https://support.google.com/chrome/?p=remote_desktop"
chrome_policy {
RemoteAccessHostFirewallTraversal {
policy_options {mode: MANDATORY}
RemoteAccessHostFirewallTraversal: false
}
}
}
comments:
"Above specified policy is only applicable on the host side and "
"doesn't have effect in Android and iOS client apps. The product "
"is shipped separately from Chromium, except on Chrome OS."
)");
}
} // namespace
CRDHostDelegate::CRDHostDelegate()
: OAuth2TokenService::Consumer("crd_host_delegate"), weak_factory_(this) {}
CRDHostDelegate::~CRDHostDelegate() { CRDHostDelegate::~CRDHostDelegate() {
// TODO(antrim): shutdown host somewhat correctly. // TODO(antrim): shutdown host somewhat correctly.
} }
bool CRDHostDelegate::HasActiveSession() { bool CRDHostDelegate::HasActiveSession() const {
return false; return false;
} }
...@@ -23,19 +87,21 @@ void CRDHostDelegate::TerminateSession(base::OnceClosure callback) { ...@@ -23,19 +87,21 @@ void CRDHostDelegate::TerminateSession(base::OnceClosure callback) {
std::move(callback).Run(); std::move(callback).Run();
} }
bool CRDHostDelegate::AreServicesReady() { bool CRDHostDelegate::AreServicesReady() const {
return user_manager::UserManager::IsInitialized() && return user_manager::UserManager::IsInitialized() &&
ui::UserActivityDetector::Get() != nullptr; ui::UserActivityDetector::Get() != nullptr &&
chromeos::ProfileHelper::Get() != nullptr &&
chromeos::DeviceOAuth2TokenServiceFactory::Get() != nullptr;
} }
bool CRDHostDelegate::IsRunningKiosk() { bool CRDHostDelegate::IsRunningKiosk() const {
auto* user_manager = user_manager::UserManager::Get(); auto* user_manager = user_manager::UserManager::Get();
// TODO(antrim): find out if Arc Kiosk is also eligible. // TODO(antrim): find out if Arc Kiosk is also eligible.
// TODO(antrim): find out if only auto-started Kiosks are elidgible. // TODO(antrim): find out if only auto-started Kiosks are elidgible.
return user_manager->IsLoggedInAsKioskApp(); return user_manager->IsLoggedInAsKioskApp() && GetKioskProfile() != nullptr;
} }
base::TimeDelta CRDHostDelegate::GetIdlenessPeriod() { base::TimeDelta CRDHostDelegate::GetIdlenessPeriod() const {
return base::TimeTicks::Now() - return base::TimeTicks::Now() -
ui::UserActivityDetector::Get()->last_activity_time(); ui::UserActivityDetector::Get()->last_activity_time();
} }
...@@ -43,17 +109,93 @@ base::TimeDelta CRDHostDelegate::GetIdlenessPeriod() { ...@@ -43,17 +109,93 @@ base::TimeDelta CRDHostDelegate::GetIdlenessPeriod() {
void CRDHostDelegate::FetchOAuthToken( void CRDHostDelegate::FetchOAuthToken(
DeviceCommandStartCRDSessionJob::OAuthTokenCallback success_callback, DeviceCommandStartCRDSessionJob::OAuthTokenCallback success_callback,
DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) { DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) {
// TODO(antrim): implement DCHECK(!oauth_success_callback_);
std::move(success_callback).Run(std::string("OAuth token")); DCHECK(!error_callback_);
chromeos::DeviceOAuth2TokenService* oauth_service =
chromeos::DeviceOAuth2TokenServiceFactory::Get();
OAuth2TokenService::ScopeSet scopes;
scopes.insert(GaiaConstants::kGoogleUserInfoEmail);
scopes.insert(GaiaConstants::kGoogleTalkOAuth2Scope);
scopes.insert(kCloudDevicesOAuth2Scope);
scopes.insert(kChromotingOAuth2Scope);
oauth_success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
oauth_request_ = oauth_service->StartRequest(
oauth_service->GetRobotAccountId(), scopes, this);
}
void CRDHostDelegate::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
oauth_request_.reset();
error_callback_.Reset();
std::move(oauth_success_callback_).Run(access_token);
}
void CRDHostDelegate::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
oauth_request_.reset();
oauth_success_callback_.Reset();
std::move(error_callback_)
.Run(DeviceCommandStartCRDSessionJob::FAILURE_NO_OAUTH_TOKEN,
error.ToString());
} }
void CRDHostDelegate::FetchICEConfig( void CRDHostDelegate::FetchICEConfig(
const std::string& oauth_token, const std::string& oauth_token,
DeviceCommandStartCRDSessionJob::ICEConfigCallback success_callback, DeviceCommandStartCRDSessionJob::ICEConfigCallback success_callback,
DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) { DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) {
base::Value configuration(base::Value::Type::DICTIONARY); DCHECK(!ice_success_callback_);
// TODO(antrim): implement DCHECK(!error_callback_);
std::move(success_callback).Run(std::move(configuration));
ice_success_callback_ = std::move(success_callback);
error_callback_ = std::move(error_callback);
auto ice_request = std::make_unique<network::ResourceRequest>();
ice_request->url = GURL(kICEConfigURL);
ice_request->load_flags =
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
ice_request->headers.SetHeader(net::HttpRequestHeaders::kAuthorization,
"Bearer " + oauth_token);
auto loader_factory =
content::BrowserContext::GetDefaultStoragePartition(GetKioskProfile())
->GetURLLoaderFactoryForBrowserProcess();
ice_config_loader_ = network::SimpleURLLoader::Create(
std::move(ice_request), CreateIceConfigRequestAnnotation());
ice_config_loader_->DownloadToString(
loader_factory.get(),
base::BindOnce(&CRDHostDelegate::OnICEConfigurationLoaded,
weak_factory_.GetWeakPtr()),
network::SimpleURLLoader::kMaxBoundedStringDownloadSize);
}
void CRDHostDelegate::OnICEConfigurationLoaded(
std::unique_ptr<std::string> response_body) {
ice_config_loader_.reset();
if (response_body) {
std::unique_ptr<base::Value> value = base::JSONReader::Read(*response_body);
if (!value || !value->is_dict()) {
ice_success_callback_.Reset();
std::move(error_callback_)
.Run(DeviceCommandStartCRDSessionJob::FAILURE_NO_ICE_CONFIG,
"Could not parse config");
return;
}
error_callback_.Reset();
std::move(ice_success_callback_).Run(std::move(*value));
} else {
ice_success_callback_.Reset();
std::move(error_callback_)
.Run(DeviceCommandStartCRDSessionJob::FAILURE_NO_ICE_CONFIG,
std::string());
}
} }
void CRDHostDelegate::StartCRDHostAndGetCode( void CRDHostDelegate::StartCRDHostAndGetCode(
...@@ -62,8 +204,14 @@ void CRDHostDelegate::StartCRDHostAndGetCode( ...@@ -62,8 +204,14 @@ void CRDHostDelegate::StartCRDHostAndGetCode(
base::Value ice_config, base::Value ice_config,
DeviceCommandStartCRDSessionJob::AuthCodeCallback success_callback, DeviceCommandStartCRDSessionJob::AuthCodeCallback success_callback,
DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) { DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) {
// TODO(antrim): implement // TODO(antrim): actual implementation
std::move(success_callback).Run(std::string("Auth Code")); std::move(success_callback).Run(std::string("TODO: Auth Code"));
}
Profile* CRDHostDelegate::GetKioskProfile() const {
auto* user_manager = user_manager::UserManager::Get();
return chromeos::ProfileHelper::Get()->GetProfileByUser(
user_manager->GetActiveUser());
} }
} // namespace policy } // namespace policy
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_CHROMEOS_POLICY_REMOTE_COMMANDS_CRD_HOST_DELEGATE_H_ #ifndef CHROME_BROWSER_CHROMEOS_POLICY_REMOTE_COMMANDS_CRD_HOST_DELEGATE_H_
#define CHROME_BROWSER_CHROMEOS_POLICY_REMOTE_COMMANDS_CRD_HOST_DELEGATE_H_ #define CHROME_BROWSER_CHROMEOS_POLICY_REMOTE_COMMANDS_CRD_HOST_DELEGATE_H_
#include <memory>
#include <string> #include <string>
#include "base/callback_forward.h" #include "base/callback_forward.h"
...@@ -12,22 +13,30 @@ ...@@ -12,22 +13,30 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "base/values.h" #include "base/values.h"
#include "chrome/browser/chromeos/policy/remote_commands/device_command_start_crd_session_job.h" #include "chrome/browser/chromeos/policy/remote_commands/device_command_start_crd_session_job.h"
#include "google_apis/gaia/oauth2_token_service.h"
namespace network {
class SimpleURLLoader;
}
class Profile;
namespace policy { namespace policy {
// An implementation of the |DeviceCommandStartCRDSessionJob::Delegate|. // An implementation of the |DeviceCommandStartCRDSessionJob::Delegate|.
class CRDHostDelegate : public DeviceCommandStartCRDSessionJob::Delegate { class CRDHostDelegate : public DeviceCommandStartCRDSessionJob::Delegate,
public OAuth2TokenService::Consumer {
public: public:
CRDHostDelegate(); CRDHostDelegate();
~CRDHostDelegate() override; ~CRDHostDelegate() override;
private: private:
// DeviceCommandScreenshotJob::Delegate: // DeviceCommandScreenshotJob::Delegate:
bool HasActiveSession() override; bool HasActiveSession() const override;
void TerminateSession(base::OnceClosure callback) override; void TerminateSession(base::OnceClosure callback) override;
bool AreServicesReady() override; bool AreServicesReady() const override;
bool IsRunningKiosk() override; bool IsRunningKiosk() const override;
base::TimeDelta GetIdlenessPeriod() override; base::TimeDelta GetIdlenessPeriod() const override;
void FetchOAuthToken( void FetchOAuthToken(
DeviceCommandStartCRDSessionJob::OAuthTokenCallback success_callback, DeviceCommandStartCRDSessionJob::OAuthTokenCallback success_callback,
DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) override; DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) override;
...@@ -42,6 +51,26 @@ class CRDHostDelegate : public DeviceCommandStartCRDSessionJob::Delegate { ...@@ -42,6 +51,26 @@ class CRDHostDelegate : public DeviceCommandStartCRDSessionJob::Delegate {
DeviceCommandStartCRDSessionJob::AuthCodeCallback success_callback, DeviceCommandStartCRDSessionJob::AuthCodeCallback success_callback,
DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) override; DeviceCommandStartCRDSessionJob::ErrorCallback error_callback) override;
// OAuth2TokenService::Consumer:
void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) override;
void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) override;
void OnICEConfigurationLoaded(std::unique_ptr<std::string> response_body);
Profile* GetKioskProfile() const;
DeviceCommandStartCRDSessionJob::OAuthTokenCallback oauth_success_callback_;
DeviceCommandStartCRDSessionJob::ICEConfigCallback ice_success_callback_;
DeviceCommandStartCRDSessionJob::ErrorCallback error_callback_;
std::unique_ptr<OAuth2TokenService::Request> oauth_request_;
std::unique_ptr<network::SimpleURLLoader> ice_config_loader_;
base::WeakPtrFactory<CRDHostDelegate> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(CRDHostDelegate); DISALLOW_COPY_AND_ASSIGN(CRDHostDelegate);
}; };
......
...@@ -56,19 +56,19 @@ class DeviceCommandStartCRDSessionJob : public RemoteCommandJob { ...@@ -56,19 +56,19 @@ class DeviceCommandStartCRDSessionJob : public RemoteCommandJob {
virtual ~Delegate() {} virtual ~Delegate() {}
// Check if there exists an active CRD session. // Check if there exists an active CRD session.
virtual bool HasActiveSession() = 0; virtual bool HasActiveSession() const = 0;
// Run |callback| once active CRD session is terminated. // Run |callback| once active CRD session is terminated.
virtual void TerminateSession(base::OnceClosure callback) = 0; virtual void TerminateSession(base::OnceClosure callback) = 0;
// Check if required system services are ready. // Check if required system services are ready.
virtual bool AreServicesReady() = 0; virtual bool AreServicesReady() const = 0;
// Check if device is running in Kiosk mode. // Check if device is running in Kiosk mode.
virtual bool IsRunningKiosk() = 0; virtual bool IsRunningKiosk() const = 0;
// Return current user idleness period. // Return current user idleness period.
virtual base::TimeDelta GetIdlenessPeriod() = 0; virtual base::TimeDelta GetIdlenessPeriod() const = 0;
// Attempts to get OAuth token for CRD Host. // Attempts to get OAuth token for CRD Host.
virtual void FetchOAuthToken(OAuthTokenCallback success_callback, virtual void FetchOAuthToken(OAuthTokenCallback success_callback,
......
...@@ -76,12 +76,12 @@ class StubCRDHostDelegate : public DeviceCommandStartCRDSessionJob::Delegate { ...@@ -76,12 +76,12 @@ class StubCRDHostDelegate : public DeviceCommandStartCRDSessionJob::Delegate {
bool auth_code_success); bool auth_code_success);
~StubCRDHostDelegate() override; ~StubCRDHostDelegate() override;
bool HasActiveSession() override; bool HasActiveSession() const override;
void TerminateSession(base::OnceClosure callback) override; void TerminateSession(base::OnceClosure callback) override;
bool AreServicesReady() override; bool AreServicesReady() const override;
bool IsRunningKiosk() override; bool IsRunningKiosk() const override;
base::TimeDelta GetIdlenessPeriod() override; base::TimeDelta GetIdlenessPeriod() const override;
void FetchOAuthToken( void FetchOAuthToken(
DeviceCommandStartCRDSessionJob::OAuthTokenCallback success_callback, DeviceCommandStartCRDSessionJob::OAuthTokenCallback success_callback,
...@@ -128,7 +128,7 @@ StubCRDHostDelegate::StubCRDHostDelegate(bool has_active_session, ...@@ -128,7 +128,7 @@ StubCRDHostDelegate::StubCRDHostDelegate(bool has_active_session,
StubCRDHostDelegate::~StubCRDHostDelegate() {} StubCRDHostDelegate::~StubCRDHostDelegate() {}
bool StubCRDHostDelegate::HasActiveSession() { bool StubCRDHostDelegate::HasActiveSession() const {
return has_active_session_; return has_active_session_;
} }
...@@ -137,15 +137,15 @@ void StubCRDHostDelegate::TerminateSession(base::OnceClosure callback) { ...@@ -137,15 +137,15 @@ void StubCRDHostDelegate::TerminateSession(base::OnceClosure callback) {
std::move(callback).Run(); std::move(callback).Run();
} }
bool StubCRDHostDelegate::AreServicesReady() { bool StubCRDHostDelegate::AreServicesReady() const {
return are_services_ready_; return are_services_ready_;
} }
bool StubCRDHostDelegate::IsRunningKiosk() { bool StubCRDHostDelegate::IsRunningKiosk() const {
return is_running_kiosk_; return is_running_kiosk_;
} }
base::TimeDelta StubCRDHostDelegate::GetIdlenessPeriod() { base::TimeDelta StubCRDHostDelegate::GetIdlenessPeriod() const {
return idleness_period_; return idleness_period_;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment