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 "remoting/test/access_token_fetcher.h"
10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "google_apis/gaia/gaia_constants.h"
15 #include "google_apis/google_api_keys.h"
16 #include "net/url_request/url_fetcher.h"
17 #include "remoting/base/url_request_context_getter.h"
20 const int kMaxGetTokensRetries
= 3;
21 const char kOauthRedirectUrl
[] =
22 "https://chromoting-oauth.talkgadget."
23 "google.com/talkgadget/oauth/chrome-remote-desktop/dev";
29 AccessTokenFetcher::AccessTokenFetcher() {
30 oauth_client_info_
= {
31 google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING
),
32 google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING
),
36 AccessTokenFetcher::~AccessTokenFetcher() {}
38 void AccessTokenFetcher::GetAccessTokenFromAuthCode(
39 const std::string
& auth_code
,
40 const AccessTokenCallback
& callback
) {
41 DCHECK(!auth_code
.empty());
42 DCHECK(!callback
.is_null());
43 DCHECK(access_token_callback_
.is_null());
45 DVLOG(2) << "Calling GetTokensFromAuthCode to exchange auth_code for token";
47 access_token_
.clear();
48 refresh_token_
.clear();
49 access_token_callback_
= callback
;
51 // Create a new GaiaOAuthClient for each request to GAIA.
52 CreateNewGaiaOAuthClientInstance();
53 auth_client_
->GetTokensFromAuthCode(
54 oauth_client_info_
, auth_code
, kMaxGetTokensRetries
,
55 this); // GaiaOAuthClient::Delegate* delegate
58 void AccessTokenFetcher::GetAccessTokenFromRefreshToken(
59 const std::string
& refresh_token
,
60 const AccessTokenCallback
& callback
) {
61 DCHECK(!refresh_token
.empty());
62 DCHECK(!callback
.is_null());
63 DCHECK(access_token_callback_
.is_null());
65 DVLOG(2) << "Calling RefreshToken to generate a new access token";
67 access_token_
.clear();
68 refresh_token_
= refresh_token
;
69 access_token_callback_
= callback
;
71 // Create a new GaiaOAuthClient for each request to GAIA.
72 CreateNewGaiaOAuthClientInstance();
73 auth_client_
->RefreshToken(
76 std::vector
<std::string
>(), // scopes
78 this); // GaiaOAuthClient::Delegate* delegate
81 void AccessTokenFetcher::CreateNewGaiaOAuthClientInstance() {
82 scoped_refptr
<remoting::URLRequestContextGetter
> request_context_getter
;
83 request_context_getter
= new remoting::URLRequestContextGetter(
84 base::ThreadTaskRunnerHandle::Get(), // network_runner
85 base::ThreadTaskRunnerHandle::Get()); // file_runner
87 auth_client_
.reset(new gaia::GaiaOAuthClient(request_context_getter
.get()));
90 void AccessTokenFetcher::OnGetTokensResponse(const std::string
& refresh_token
,
91 const std::string
& access_token
,
92 int expires_in_seconds
) {
93 DVLOG(1) << "AccessTokenFetcher::OnGetTokensResponse() Called";
94 DVLOG(1) << "--refresh_token: " << refresh_token
;
95 DVLOG(1) << "--access_token: " << access_token
;
96 DVLOG(1) << "--expires_in_seconds: " << expires_in_seconds
;
98 refresh_token_
= refresh_token
;
99 access_token_
= access_token
;
101 ValidateAccessToken();
104 void AccessTokenFetcher::OnRefreshTokenResponse(const std::string
& access_token
,
105 int expires_in_seconds
) {
106 DVLOG(1) << "AccessTokenFetcher::OnRefreshTokenResponse() Called";
107 DVLOG(1) << "--access_token: " << access_token
;
108 DVLOG(1) << "--expires_in_seconds: " << expires_in_seconds
;
110 access_token_
= access_token
;
112 ValidateAccessToken();
115 void AccessTokenFetcher::OnGetUserEmailResponse(const std::string
& user_email
) {
116 // This callback should not be called as we do not request the user's email.
120 void AccessTokenFetcher::OnGetUserIdResponse(const std::string
& user_id
) {
121 // This callback should not be called as we do not request the user's id.
125 void AccessTokenFetcher::OnGetUserInfoResponse(
126 scoped_ptr
<base::DictionaryValue
> user_info
) {
127 // This callback should not be called as we do not request user info.
131 void AccessTokenFetcher::OnGetTokenInfoResponse(
132 scoped_ptr
<base::DictionaryValue
> token_info
) {
133 DVLOG(1) << "AccessTokenFetcher::OnGetTokenInfoResponse() Called";
135 std::string error_string
;
136 std::string error_description
;
138 // Check to see if the token_info we received had any errors,
139 // otherwise we will assume that it is valid for our purposes.
140 if (token_info
->HasKey("error")) {
141 token_info
->GetString("error", &error_string
);
142 token_info
->GetString("error_description", &error_description
);
144 LOG(ERROR
) << "OnGetTokenInfoResponse returned an error. "
145 << "error: " << error_string
<< ", "
146 << "description: " << error_description
;
147 access_token_
.clear();
148 refresh_token_
.clear();
150 DVLOG(1) << "Access Token has been validated";
153 access_token_callback_
.Run(access_token_
, refresh_token_
);
154 access_token_callback_
.Reset();
157 void AccessTokenFetcher::OnOAuthError() {
158 LOG(ERROR
) << "AccessTokenFetcher::OnOAuthError() Called";
160 access_token_
.clear();
161 refresh_token_
.clear();
163 access_token_callback_
.Run(access_token_
, refresh_token_
);
164 access_token_callback_
.Reset();
167 void AccessTokenFetcher::OnNetworkError(int response_code
) {
168 LOG(ERROR
) << "AccessTokenFetcher::OnNetworkError() Called";
169 LOG(ERROR
) << "response code: " << response_code
;
171 access_token_
.clear();
172 refresh_token_
.clear();
174 access_token_callback_
.Run(access_token_
, refresh_token_
);
175 access_token_callback_
.Reset();
178 void AccessTokenFetcher::ValidateAccessToken() {
179 DVLOG(2) << "Calling GetTokenInfo to validate access token";
181 // Create a new GaiaOAuthClient for each request to GAIA.
182 CreateNewGaiaOAuthClientInstance();
183 auth_client_
->GetTokenInfo(
185 kMaxGetTokensRetries
,
186 this); // GaiaOAuthClient::Delegate* delegate
190 } // namespace remoting