1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/cloud_policy_client_registration_helper.h"
6eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/bind.h"
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/bind_helpers.h"
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/logging.h"
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/values.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "google_apis/gaia/gaia_constants.h"
13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "google_apis/gaia/gaia_urls.h"
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "google_apis/gaia/google_service_auth_error.h"
15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "google_apis/gaia/oauth2_token_service.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#if !defined(OS_ANDROID)
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "google_apis/gaia/oauth2_access_token_consumer.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace policy {
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// The key under which the hosted-domain value is stored in the UserInfo
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// response.
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst char kGetHostedDomainKey[] = "hd";
28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochtypedef base::Callback<void(const std::string&)> StringCallback;
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// This class fetches an OAuth2 token scoped for the userinfo and DM services.
323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// On Android, we use a special API to allow us to fetch a token for an account
333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// that is not yet logged in to allow fetching the token before the sign-in
343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// process is finished.
353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class CloudPolicyClientRegistrationHelper::TokenServiceHelper
367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : public OAuth2TokenService::Consumer {
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  TokenServiceHelper();
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  void FetchAccessToken(
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      OAuth2TokenService* token_service,
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const std::string& username,
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      const StringCallback& callback);
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // OAuth2TokenService::Consumer implementation:
477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 const std::string& access_token,
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 const base::Time& expiration_time) OVERRIDE;
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 const GoogleServiceAuthError& error) OVERRIDE;
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StringCallback callback_;
547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<OAuth2TokenService::Request> token_request_;
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CloudPolicyClientRegistrationHelper::TokenServiceHelper::TokenServiceHelper()
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : OAuth2TokenService::Consumer("cloud_policy") {}
597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CloudPolicyClientRegistrationHelper::TokenServiceHelper::FetchAccessToken(
613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    OAuth2TokenService* token_service,
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& account_id,
637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StringCallback& callback) {
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!token_request_);
653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Either the caller must supply a username, or the user must be signed in
663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // already.
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!account_id.empty());
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(token_service->RefreshTokenIsAvailable(account_id));
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback_ = callback;
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  OAuth2TokenService::ScopeSet scopes;
737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scopes.insert(GaiaConstants::kDeviceManagementServiceOAuth);
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scopes.insert(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  token_request_ = token_service->StartRequest(account_id, scopes, this);
767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CloudPolicyClientRegistrationHelper::TokenServiceHelper::OnGetTokenSuccess(
797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const OAuth2TokenService::Request* request,
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& access_token,
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Time& expiration_time) {
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_EQ(token_request_.get(), request);
837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback_.Run(access_token);
847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CloudPolicyClientRegistrationHelper::TokenServiceHelper::OnGetTokenFailure(
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const OAuth2TokenService::Request* request,
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const GoogleServiceAuthError& error) {
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DCHECK_EQ(token_request_.get(), request);
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback_.Run("");
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_ANDROID)
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// This class fetches the OAuth2 token scoped for the userinfo and DM services.
957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// It uses an OAuth2AccessTokenFetcher to fetch it, given a login refresh token
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// that can be used to authorize that request. This class is not needed on
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Android because we can use OAuth2TokenService to fetch tokens for accounts
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// even before they are signed in.
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)class CloudPolicyClientRegistrationHelper::LoginTokenHelper
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : public OAuth2AccessTokenConsumer {
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch public:
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  LoginTokenHelper();
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  void FetchAccessToken(const std::string& login_refresh_token,
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                        net::URLRequestContextGetter* context,
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                        const StringCallback& callback);
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch private:
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // OAuth2AccessTokenConsumer implementation:
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnGetTokenSuccess(const std::string& access_token,
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                 const base::Time& expiration_time) OVERRIDE;
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  virtual void OnGetTokenFailure(
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      const GoogleServiceAuthError& error) OVERRIDE;
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  StringCallback callback_;
1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<OAuth2AccessTokenFetcher> oauth2_access_token_fetcher_;
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch};
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)CloudPolicyClientRegistrationHelper::LoginTokenHelper::LoginTokenHelper() {}
1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CloudPolicyClientRegistrationHelper::LoginTokenHelper::FetchAccessToken(
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& login_refresh_token,
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    net::URLRequestContextGetter* context,
1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const StringCallback& callback) {
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(!oauth2_access_token_fetcher_);
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback_ = callback;
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Start fetching an OAuth2 access token for the device management and
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // userinfo services.
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  oauth2_access_token_fetcher_.reset(
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      new OAuth2AccessTokenFetcherImpl(this, context, login_refresh_token));
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  oauth2_access_token_fetcher_->Start(
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      gaia_urls->oauth2_chrome_client_id(),
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      gaia_urls->oauth2_chrome_client_secret(),
1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      GetScopes());
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CloudPolicyClientRegistrationHelper::LoginTokenHelper::OnGetTokenSuccess(
1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& access_token,
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::Time& expiration_time) {
1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback_.Run(access_token);
1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void CloudPolicyClientRegistrationHelper::LoginTokenHelper::OnGetTokenFailure(
1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const GoogleServiceAuthError& error) {
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  callback_.Run("");
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochCloudPolicyClientRegistrationHelper::CloudPolicyClientRegistrationHelper(
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CloudPolicyClient* client,
154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    enterprise_management::DeviceRegisterRequest::Type registration_type)
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : context_(client->GetRequestContext()),
156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      client_(client),
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      registration_type_(registration_type) {
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(context_.get());
159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(client_);
160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochCloudPolicyClientRegistrationHelper::~CloudPolicyClientRegistrationHelper() {
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Clean up any pending observers in case the browser is shutdown while
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // trying to register for policy.
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (client_)
166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    client_->RemoveObserver(this);
167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid CloudPolicyClientRegistrationHelper::StartRegistration(
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    OAuth2TokenService* token_service,
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& account_id,
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::Closure& callback) {
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DVLOG(1) << "Starting registration process with username";
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!client_->is_registered());
176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  callback_ = callback;
177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  client_->AddObserver(this);
178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  token_service_helper_.reset(new TokenServiceHelper());
1803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  token_service_helper_->FetchAccessToken(
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      token_service,
18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      account_id,
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&CloudPolicyClientRegistrationHelper::OnTokenFetched,
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Unretained(this)));
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_ANDROID)
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid CloudPolicyClientRegistrationHelper::StartRegistrationWithLoginToken(
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& login_refresh_token,
190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::Closure& callback) {
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  DVLOG(1) << "Starting registration process with login token";
192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(!client_->is_registered());
193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  callback_ = callback;
194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  client_->AddObserver(this);
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  login_token_helper_.reset(
1973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new CloudPolicyClientRegistrationHelper::LoginTokenHelper());
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  login_token_helper_->FetchAccessToken(
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      login_refresh_token,
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      context_.get(),
2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      base::Bind(&CloudPolicyClientRegistrationHelper::OnTokenFetched,
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                 base::Unretained(this)));
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
2045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid CloudPolicyClientRegistrationHelper::StartRegistrationWithAccessToken(
2065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const std::string& access_token,
2075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const base::Closure& callback) {
2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  DCHECK(!client_->is_registered());
2095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  callback_ = callback;
2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  client_->AddObserver(this);
2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  OnTokenFetched(access_token);
2125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// static
2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustd::vector<std::string>
2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuCloudPolicyClientRegistrationHelper::GetScopes() {
2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::vector<std::string> scopes;
2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scopes.push_back(GaiaConstants::kDeviceManagementServiceOAuth);
2195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  scopes.push_back(GaiaConstants::kOAuthWrapBridgeUserInfoScope);
2205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return scopes;
2215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#endif
223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid CloudPolicyClientRegistrationHelper::OnTokenFetched(
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const std::string& access_token) {
2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(OS_ANDROID)
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  login_token_helper_.reset();
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  token_service_helper_.reset();
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (access_token.empty()) {
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    DLOG(WARNING) << "Could not fetch access token for "
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  << GaiaConstants::kDeviceManagementServiceOAuth;
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    RequestCompleted();
2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Cache the access token to be used after the GetUserInfo call.
239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  oauth_access_token_ = access_token;
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DVLOG(1) << "Fetched new scoped OAuth token:" << oauth_access_token_;
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Now we've gotten our access token - contact GAIA to see if this is a
242eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // hosted domain.
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  user_info_fetcher_.reset(new UserInfoFetcher(this, context_.get()));
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  user_info_fetcher_->Start(oauth_access_token_);
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid CloudPolicyClientRegistrationHelper::OnGetUserInfoFailure(
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const GoogleServiceAuthError& error) {
249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DVLOG(1) << "Failed to fetch user info from GAIA: " << error.state();
250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  user_info_fetcher_.reset();
251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RequestCompleted();
252eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
253eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid CloudPolicyClientRegistrationHelper::OnGetUserInfoSuccess(
255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::DictionaryValue* data) {
256eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  user_info_fetcher_.reset();
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!data->HasKey(kGetHostedDomainKey)) {
258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    DVLOG(1) << "User not from a hosted domain - skipping registration";
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    RequestCompleted();
260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DVLOG(1) << "Registering CloudPolicyClient for user from hosted domain";
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The user is from a hosted domain, so it's OK to register the
264eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // CloudPolicyClient and make requests to DMServer.
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (client_->is_registered()) {
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // Client should not be registered yet.
267eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    NOTREACHED();
268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    RequestCompleted();
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Kick off registration of the CloudPolicyClient with our newly minted
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // oauth_access_token_.
274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  client_->Register(registration_type_, oauth_access_token_,
275effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                    std::string(), false, std::string(), std::string());
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid CloudPolicyClientRegistrationHelper::OnPolicyFetched(
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CloudPolicyClient* client) {
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Ignored.
281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid CloudPolicyClientRegistrationHelper::OnRegistrationStateChanged(
284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CloudPolicyClient* client) {
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DVLOG(1) << "Client registration succeeded";
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_EQ(client, client_);
287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK(client->is_registered());
288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RequestCompleted();
289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid CloudPolicyClientRegistrationHelper::OnClientError(
292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    CloudPolicyClient* client) {
293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DVLOG(1) << "Client registration failed";
294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  DCHECK_EQ(client, client_);
295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  RequestCompleted();
296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid CloudPolicyClientRegistrationHelper::RequestCompleted() {
299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (client_) {
300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    client_->RemoveObserver(this);
301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    // |client_| may be freed by the callback so clear it now.
302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    client_ = NULL;
303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    callback_.Run();
304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace policy
308