OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "remoting/test/access_token_fetcher.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/logging.h" | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "base/thread_task_runner_handle.h" | |
11 #include "google_apis/gaia/gaia_constants.h" | |
12 #include "google_apis/google_api_keys.h" | |
13 #include "net/url_request/url_fetcher.h" | |
14 #include "remoting/base/url_request_context_getter.h" | |
15 | |
16 namespace { | |
17 const int kMaxGetTokensRetries = 3; | |
18 const char kOauthRedirectUrl[] = "https://chromoting-oauth.talkgadget." | |
19 "google.com/talkgadget/oauth/chrome-remote-desktop/dev"; | |
20 } | |
21 | |
22 namespace remoting { | |
23 namespace test { | |
24 | |
25 using net::URLRequestContextGetter; | |
Wez
2015/02/13 03:01:50
nit: We rarely use using, and it seems strange to
joedow
2015/02/14 02:31:25
Done.
| |
26 | |
27 GaiaOAuthClientAdapter::GaiaOAuthClientAdapter( | |
28 URLRequestContextGetter* context_getter) { | |
29 auth_client_.reset(new gaia::GaiaOAuthClient(context_getter)); | |
30 } | |
31 | |
32 GaiaOAuthClientAdapter::~GaiaOAuthClientAdapter() { | |
33 } | |
Wez
2015/02/13 03:01:50
nit: Run git cl format on this; I think it'll put
joedow
2015/02/14 02:31:25
Done.
| |
34 | |
35 void GaiaOAuthClientAdapter::GetTokensFromAuthCode( | |
36 const gaia::OAuthClientInfo& oauth_client_info, | |
37 const std::string& auth_code, | |
38 int max_retries, | |
39 gaia::GaiaOAuthClient::Delegate* delegate) { | |
40 DCHECK(auth_client_.get()); | |
Wez
2015/02/13 03:01:50
You create |auth_client_| in the ctor, so no need
joedow
2015/02/14 02:31:25
Done.
| |
41 auth_client_->GetTokensFromAuthCode( | |
42 oauth_client_info, | |
43 auth_code, | |
44 max_retries, | |
45 delegate); | |
46 } | |
47 | |
48 void GaiaOAuthClientAdapter::RefreshToken( | |
49 const gaia::OAuthClientInfo& oauth_client_info, | |
50 const std::string& refresh_token, | |
51 const std::vector<std::string>& scopes, | |
52 int max_retries, | |
53 gaia::GaiaOAuthClient::Delegate* delegate) { | |
54 DCHECK(auth_client_.get()); | |
Wez
2015/02/13 03:01:50
As above
joedow
2015/02/14 02:31:25
Done.
joedow
2015/02/14 02:31:25
Done.
| |
55 auth_client_->RefreshToken( | |
56 oauth_client_info, | |
57 refresh_token, | |
58 scopes, | |
59 max_retries, | |
60 delegate); | |
61 } | |
62 | |
63 void GaiaOAuthClientAdapter::GetTokenInfo( | |
64 const std::string& oauth_access_token, | |
65 int max_retries, | |
66 gaia::GaiaOAuthClient::Delegate* delegate) { | |
67 DCHECK(auth_client_.get()); | |
Wez
2015/02/13 03:01:50
As above
joedow
2015/02/14 02:31:25
Done.
| |
68 auth_client_->GetTokenInfo( | |
69 oauth_access_token, | |
70 max_retries, | |
71 delegate); | |
72 } | |
73 | |
74 AccessTokenFetcher::AccessTokenFetcher() { | |
75 oauth_client_info_ = { | |
76 google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING), | |
77 google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING), | |
78 kOauthRedirectUrl | |
79 }; | |
80 } | |
81 | |
82 AccessTokenFetcher::~AccessTokenFetcher() { | |
83 } | |
84 | |
85 void AccessTokenFetcher::GetAccessTokenFromAuthCode( | |
86 const std::string& auth_code, | |
87 const AccessTokenCallback& callback) { | |
88 DVLOG(2) << "Calling GetTokensFromAuthCode to exchange auth_code for token"; | |
Wez
2015/02/13 03:01:50
You're logging this log before actually making the
joedow
2015/02/14 02:31:25
Done.
| |
89 | |
90 if (!access_token_callback_.is_null()) { | |
91 LOG(ERROR) << "Access token request is already in progress"; | |
92 return; | |
93 } | |
94 | |
95 DCHECK(access_token_.empty()); | |
Wez
2015/02/13 03:01:50
You DCHECK that |access_token_| is empty here but
joedow
2015/02/14 02:31:24
I had assumed that this function would only be cal
| |
96 DCHECK(refresh_token_.empty()); | |
97 access_token_callback_ = callback; | |
98 | |
99 // Every call which uses a GaiaOAuthClient requires a new object. | |
Wez
2015/02/13 03:01:50
Not sure what this means; are you saying that you
joedow
2015/02/14 02:31:24
Updated the comment to be more clear. I don't wan
| |
100 RefreshGaiaOAuthClientInstance(); | |
101 auth_client_->GetTokensFromAuthCode( | |
102 oauth_client_info_, | |
103 auth_code, | |
104 kMaxGetTokensRetries, | |
105 this); // GaiaOAuthClient::Delegate* delegate | |
106 } | |
107 | |
108 void AccessTokenFetcher::GetAccessTokenFromRefreshToken( | |
109 const std::string& refresh_token, | |
110 const AccessTokenCallback& callback) { | |
111 DVLOG(2) << "Calling RefreshToken to generate a new access token"; | |
112 | |
113 if (!access_token_callback_.is_null()) { | |
114 LOG(ERROR) << "Access token request is already in progress"; | |
115 return; | |
116 } | |
117 | |
118 access_token_.clear(); | |
Wez
2015/02/13 03:01:50
See comments above re DCHECKing vs clear()ing.
joedow
2015/02/14 02:31:25
Done.
| |
119 refresh_token_ = refresh_token; | |
120 access_token_callback_ = callback; | |
121 | |
122 // Populate a vector with the required permissions for app remoting. | |
123 std::vector<std::string> scopes; | |
124 scopes.push_back( | |
125 "https://www.googleapis.com/auth/appremoting.runapplication"); | |
126 scopes.push_back("https://www.googleapis.com/auth/googletalk"); | |
127 scopes.push_back("https://www.googleapis.com/auth/userinfo.email"); | |
128 scopes.push_back("https://docs.google.com/feeds"); | |
129 scopes.push_back("https://www.googleapis.com/auth/drive"); | |
Wez
2015/02/13 03:01:50
Is there a way that you can initialize the vector<
joedow
2015/02/14 02:31:25
Done.
| |
130 | |
131 // Every call which uses a GaiaOAuthClient requires a new object. | |
132 RefreshGaiaOAuthClientInstance(); | |
133 auth_client_->RefreshToken( | |
134 oauth_client_info_, | |
135 refresh_token_, | |
136 scopes, | |
137 kMaxGetTokensRetries, | |
138 this); // GaiaOAuthClient::Delegate* delegate | |
139 } | |
140 | |
141 void AccessTokenFetcher::RefreshGaiaOAuthClientInstance() { | |
142 scoped_refptr<remoting::URLRequestContextGetter> request_context_getter; | |
143 request_context_getter = new remoting::URLRequestContextGetter( | |
144 base::ThreadTaskRunnerHandle::Get(), // network_runner | |
145 base::ThreadTaskRunnerHandle::Get()); // file_runner | |
146 | |
147 auth_client_.reset(new GaiaOAuthClientAdapter(request_context_getter.get())); | |
148 } | |
149 | |
150 void AccessTokenFetcher::OnGetTokensResponse( | |
151 const std::string& refresh_token, | |
152 const std::string& access_token, | |
153 int expires_in_seconds) { | |
154 DVLOG(1) << "AccessTokenFetcher::OnGetTokensResponse() Called"; | |
155 DVLOG(1) << "--refresh_token: " << refresh_token; | |
156 DVLOG(1) << "--access_token: " << access_token; | |
157 DVLOG(1) << "--expires_in_seconds: " << expires_in_seconds; | |
158 | |
159 refresh_token_ = refresh_token; | |
160 access_token_ = access_token; | |
161 | |
162 ValidateAccessToken(); | |
163 } | |
164 | |
165 void AccessTokenFetcher::OnRefreshTokenResponse( | |
166 const std::string& access_token, | |
167 int expires_in_seconds) { | |
168 DVLOG(1) << "AccessTokenFetcher::OnRefreshTokenResponse() Called"; | |
169 DVLOG(1) << "--access_token: " << access_token; | |
170 DVLOG(1) << "--expires_in_seconds: " << expires_in_seconds; | |
171 | |
172 access_token_ = access_token; | |
173 | |
174 ValidateAccessToken(); | |
175 } | |
176 | |
177 void AccessTokenFetcher::OnGetUserEmailResponse( | |
178 const std::string& user_email) { | |
179 // This callback should not be called as we do not request the user's email. | |
180 NOTREACHED(); | |
181 } | |
182 | |
183 void AccessTokenFetcher::OnGetUserIdResponse( | |
184 const std::string& user_id) { | |
185 // This callback should not be called as we do not request the user's id. | |
186 NOTREACHED(); | |
187 } | |
188 | |
189 void AccessTokenFetcher::OnGetUserInfoResponse( | |
190 scoped_ptr<base::DictionaryValue> user_info) { | |
191 // This callback should not be called as we do not request user info. | |
192 NOTREACHED(); | |
193 } | |
194 | |
195 void AccessTokenFetcher::OnGetTokenInfoResponse( | |
196 scoped_ptr<base::DictionaryValue> token_info) { | |
197 DVLOG(1) << "AccessTokenFetcher::OnGetTokenInfoResponse() Called"; | |
198 | |
199 std::string error_string; | |
200 std::string error_description; | |
201 | |
202 // Check to see if the token_info we received had any errors, | |
203 // otherwise we will assume that it is valid for our purposes. | |
204 if (token_info->HasKey("error")) { | |
205 token_info->GetString("error", &error_string); | |
206 token_info->GetString("error_description", &error_description); | |
207 | |
208 LOG(ERROR) << "OnGetTokenInfoResponse returned an error. " << ", " | |
209 << "error: " << error_string << ", " | |
210 << "description: " << error_description; | |
211 access_token_.clear(); | |
212 refresh_token_.clear(); | |
213 } else { | |
214 DVLOG(1) << "Access Token has been validated"; | |
215 } | |
216 | |
217 DCHECK(!access_token_callback_.is_null()); | |
Wez
2015/02/13 03:01:50
There's no point DCHECKing this here; the Run() wo
joedow
2015/02/14 02:31:25
Done.
| |
218 access_token_callback_.Run(access_token_, refresh_token_); | |
219 access_token_callback_.Reset(); | |
220 } | |
221 | |
222 void AccessTokenFetcher::OnOAuthError() { | |
223 LOG(ERROR) << "AccessTokenFetcher::OnOAuthError() Called"; | |
224 | |
225 access_token_.clear(); | |
226 refresh_token_.clear(); | |
227 | |
228 DCHECK(!access_token_callback_.is_null()); | |
229 access_token_callback_.Run(access_token_, refresh_token_); | |
230 access_token_callback_.Reset(); | |
231 } | |
232 | |
233 void AccessTokenFetcher::OnNetworkError(int response_code) { | |
234 LOG(ERROR) << "AccessTokenFetcher::OnNetworkError() Called"; | |
235 LOG(ERROR) << "response code: " << response_code; | |
236 | |
237 access_token_.clear(); | |
238 refresh_token_.clear(); | |
239 | |
240 DCHECK(!access_token_callback_.is_null()); | |
Wez
2015/02/13 03:01:50
See above re DCHECK
joedow
2015/02/14 02:31:25
Done.
| |
241 access_token_callback_.Run(access_token_, refresh_token_); | |
242 access_token_callback_.Reset(); | |
243 } | |
244 | |
245 void AccessTokenFetcher::ValidateAccessToken() { | |
246 DVLOG(2) << "Calling GetTokenInfo to validate access token"; | |
247 | |
248 RefreshGaiaOAuthClientInstance(); | |
249 auth_client_->GetTokenInfo( | |
250 access_token_, | |
251 kMaxGetTokensRetries, | |
252 this); // GaiaOAuthClient::Delegate* delegate | |
253 } | |
254 | |
255 } // namespace test | |
256 } // namespace remoting | |
OLD | NEW |