1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/login/signin/token_handle_fetcher.h"
7 #include "base/metrics/histogram_macros.h"
8 #include "chrome/browser/chromeos/login/signin/token_handle_util.h"
9 #include "chrome/browser/chromeos/profiles/profile_helper.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
12 #include "chrome/browser/signin/signin_manager_factory.h"
13 #include "chrome/browser/signin/signin_manager_factory.h"
14 #include "components/signin/core/browser/profile_oauth2_token_service.h"
15 #include "components/signin/core/browser/signin_manager.h"
16 #include "google_apis/gaia/gaia_constants.h"
19 const int kMaxRetries
= 3;
22 TokenHandleFetcher::TokenHandleFetcher(TokenHandleUtil
* util
,
23 const user_manager::UserID
& user_id
)
24 : OAuth2TokenService::Consumer("user_session_manager"),
25 token_handle_util_(util
),
27 token_service_(nullptr),
28 waiting_for_refresh_token_(false),
30 tokeninfo_response_start_time_(base::TimeTicks()) {
33 TokenHandleFetcher::~TokenHandleFetcher() {
34 if (waiting_for_refresh_token_
)
35 token_service_
->RemoveObserver(this);
38 void TokenHandleFetcher::BackfillToken(Profile
* profile
,
39 const TokenFetchingCallback
& callback
) {
43 token_service_
= ProfileOAuth2TokenServiceFactory::GetForProfile(profile
);
44 SigninManagerBase
* signin_manager
=
45 SigninManagerFactory::GetForProfile(profile
);
46 std::string account_id
= signin_manager
->GetAuthenticatedAccountId();
47 if (!token_service_
->RefreshTokenIsAvailable(account_id
)) {
48 account_without_token_
= account_id
;
49 token_service_
->AddObserver(this);
50 waiting_for_refresh_token_
= true;
53 RequestAccessToken(account_id
);
56 void TokenHandleFetcher::OnRefreshTokenAvailable(
57 const std::string
& account_id
) {
58 if (account_without_token_
!= account_id
)
60 waiting_for_refresh_token_
= false;
61 token_service_
->RemoveObserver(this);
62 RequestAccessToken(account_id
);
65 void TokenHandleFetcher::RequestAccessToken(const std::string
& account_id
) {
66 OAuth2TokenService::ScopeSet scopes
;
67 scopes
.insert(GaiaConstants::kOAuth1LoginScope
);
68 oauth2_access_token_request_
=
69 token_service_
->StartRequest(account_id
, scopes
, this);
72 void TokenHandleFetcher::OnGetTokenSuccess(
73 const OAuth2TokenService::Request
* request
,
74 const std::string
& access_token
,
75 const base::Time
& expiration_time
) {
76 oauth2_access_token_request_
.reset();
77 FillForAccessToken(access_token
);
80 void TokenHandleFetcher::OnGetTokenFailure(
81 const OAuth2TokenService::Request
* request
,
82 const GoogleServiceAuthError
& error
) {
83 oauth2_access_token_request_
.reset();
84 LOG(ERROR
) << "Could not get access token to backfill token handler"
86 callback_
.Run(user_id_
, false);
89 void TokenHandleFetcher::FillForNewUser(const std::string
& access_token
,
90 const TokenFetchingCallback
& callback
) {
91 profile_
= chromeos::ProfileHelper::Get()->GetSigninProfile();
93 FillForAccessToken(access_token
);
96 void TokenHandleFetcher::FillForAccessToken(const std::string
& access_token
) {
97 if (!gaia_client_
.get())
99 new gaia::GaiaOAuthClient(profile_
->GetRequestContext()));
100 tokeninfo_response_start_time_
= base::TimeTicks::Now();
101 gaia_client_
->GetTokenInfo(access_token
, kMaxRetries
, this);
104 void TokenHandleFetcher::OnOAuthError() {
105 callback_
.Run(user_id_
, false);
108 void TokenHandleFetcher::OnNetworkError(int response_code
) {
109 callback_
.Run(user_id_
, false);
112 void TokenHandleFetcher::OnGetTokenInfoResponse(
113 scoped_ptr
<base::DictionaryValue
> token_info
) {
114 bool success
= false;
115 if (!token_info
->HasKey("error")) {
117 if (token_info
->GetString("token_handle", &handle
)) {
119 token_handle_util_
->StoreTokenHandle(user_id_
, handle
);
122 const base::TimeDelta duration
=
123 base::TimeTicks::Now() - tokeninfo_response_start_time_
;
124 UMA_HISTOGRAM_TIMES("Login.TokenObtainResponseTime", duration
);
125 callback_
.Run(user_id_
, success
);