Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: chrome/browser/profiles/profile_downloader.cc

Issue 8746002: Use OAuth2 refresh token to download GAIA info (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: correct branch Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/profiles/profile_downloader.h" 5 #include "chrome/browser/profiles/profile_downloader.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/string_split.h" 13 #include "base/string_split.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/stringprintf.h" 15 #include "base/stringprintf.h"
16 #include "chrome/browser/net/gaia/token_service.h" 16 #include "chrome/browser/net/gaia/token_service.h"
17 #include "chrome/browser/profiles/profile.h" 17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/profiles/profile_downloader_delegate.h" 18 #include "chrome/browser/profiles/profile_downloader_delegate.h"
19 #include "chrome/common/chrome_notification_types.h" 19 #include "chrome/common/chrome_notification_types.h"
20 #include "chrome/common/net/gaia/gaia_constants.h" 20 #include "chrome/common/net/gaia/gaia_constants.h"
21 #include "chrome/common/net/gaia/gaia_urls.h"
22 #include "chrome/common/net/gaia/oauth2_access_token_fetcher.h"
21 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/notification_details.h" 24 #include "content/public/browser/notification_details.h"
23 #include "content/public/browser/notification_observer.h" 25 #include "content/public/browser/notification_observer.h"
24 #include "content/public/browser/notification_registrar.h" 26 #include "content/public/browser/notification_registrar.h"
25 #include "content/public/browser/notification_source.h" 27 #include "content/public/browser/notification_source.h"
26 #include "content/public/browser/notification_types.h" 28 #include "content/public/browser/notification_types.h"
27 #include "content/public/common/url_fetcher.h" 29 #include "content/public/common/url_fetcher.h"
28 #include "googleurl/src/gurl.h" 30 #include "googleurl/src/gurl.h"
29 #include "skia/ext/image_operations.h" 31 #include "skia/ext/image_operations.h"
30 32
31 using content::BrowserThread; 33 using content::BrowserThread;
32 34
33 namespace { 35 namespace {
34 36
35 // Template for optional authorization header. 37 // Template for optional authorization header when using client login access
Ivan Korotkov 2011/11/30 11:17:31 the ClientLogin
sail 2011/11/30 11:34:10 Done.
36 const char kAuthorizationHeader[] = "Authorization: GoogleLogin auth=%s"; 38 // token.
39 const char kClientAccessAuthorizationHeader[] =
40 "Authorization: GoogleLogin auth=%s";
41
42 // Template for optional authorization header when using an OAuth access token.
43 const char kOAuthAccessAuthorizationHeader[] =
44 "Authorization: Bearer %s";
37 45
38 // URL requesting Picasa API for user info. 46 // URL requesting Picasa API for user info.
39 const char kUserEntryURL[] = 47 const char kUserEntryURL[] =
40 "http://picasaweb.google.com/data/entry/api/user/default?alt=json"; 48 "http://picasaweb.google.com/data/entry/api/user/default?alt=json";
49
50 // OAuth scope for the Picasa API.
51 const char kPicasaScope[] = "http://picasaweb.google.com/data/";
52
41 // Path in JSON dictionary to user's photo thumbnail URL. 53 // Path in JSON dictionary to user's photo thumbnail URL.
42 const char kPhotoThumbnailURLPath[] = "entry.gphoto$thumbnail.$t"; 54 const char kPhotoThumbnailURLPath[] = "entry.gphoto$thumbnail.$t";
43 55
44 const char kNickNamePath[] = "entry.gphoto$nickname.$t"; 56 const char kNickNamePath[] = "entry.gphoto$nickname.$t";
45 57
46 // Path format for specifying thumbnail's size. 58 // Path format for specifying thumbnail's size.
47 const char kThumbnailSizeFormat[] = "s%d-c"; 59 const char kThumbnailSizeFormat[] = "s%d-c";
48 // Default Picasa thumbnail size. 60 // Default Picasa thumbnail size.
49 const int kDefaultThumbnailSize = 64; 61 const int kDefaultThumbnailSize = 64;
50 62
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 VLOG(1) << "Starting profile downloader..."; 192 VLOG(1) << "Starting profile downloader...";
181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
182 194
183 TokenService* service = delegate_->GetBrowserProfile()->GetTokenService(); 195 TokenService* service = delegate_->GetBrowserProfile()->GetTokenService();
184 if (!service) { 196 if (!service) {
185 // This can happen in some test paths. 197 // This can happen in some test paths.
186 LOG(WARNING) << "User has no token service"; 198 LOG(WARNING) << "User has no token service";
187 delegate_->OnDownloadComplete(this, false); 199 delegate_->OnDownloadComplete(this, false);
188 return; 200 return;
189 } 201 }
190 if (service->HasTokenForService(GaiaConstants::kPicasaService)) { 202
203 if (delegate_->GetShouldUseOAuthRefreshToken() &&
204 service->HasOAuthLoginToken()) {
205 std::vector<std::string> scopes;
206 scopes.push_back(kPicasaScope);
207 oauth2_access_token_fetcher_.reset(new OAuth2AccessTokenFetcher(
208 this, delegate_->GetBrowserProfile()->GetRequestContext()));
209 oauth2_access_token_fetcher_->Start(
210 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
211 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
212 service->GetOAuth2LoginRefreshToken(),
213 scopes);
214 } else if (!delegate_->GetShouldUseOAuthRefreshToken() &&
215 service->HasTokenForService(GaiaConstants::kPicasaService)) {
191 auth_token_ = 216 auth_token_ =
192 service->GetTokenForService(GaiaConstants::kPicasaService); 217 service->GetTokenForService(GaiaConstants::kPicasaService);
193 StartFetchingImage(); 218 StartFetchingImage();
194 } else { 219 } else {
195 registrar_.Add(this, 220 registrar_.Add(this,
Ivan Korotkov 2011/11/30 11:17:31 We subscribe for notifications for both methods (r
sail 2011/11/30 11:34:10 Yea, the same notification is sent for both.
196 chrome::NOTIFICATION_TOKEN_AVAILABLE, 221 chrome::NOTIFICATION_TOKEN_AVAILABLE,
197 content::Source<TokenService>(service)); 222 content::Source<TokenService>(service));
198 registrar_.Add(this, 223 registrar_.Add(this,
199 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, 224 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED,
200 content::Source<TokenService>(service)); 225 content::Source<TokenService>(service));
201 } 226 }
202 } 227 }
203 228
204 string16 ProfileDownloader::GetProfileFullName() const { 229 string16 ProfileDownloader::GetProfileFullName() const {
205 return profile_full_name_; 230 return profile_full_name_;
206 } 231 }
207 232
208 SkBitmap ProfileDownloader::GetProfilePicture() const { 233 SkBitmap ProfileDownloader::GetProfilePicture() const {
209 return profile_picture_; 234 return profile_picture_;
210 } 235 }
211 236
212 void ProfileDownloader::StartFetchingImage() { 237 void ProfileDownloader::StartFetchingImage() {
213 VLOG(1) << "Fetching user entry with token: " << auth_token_; 238 VLOG(1) << "Fetching user entry with token: " << auth_token_;
214 user_entry_fetcher_.reset(content::URLFetcher::Create( 239 user_entry_fetcher_.reset(content::URLFetcher::Create(
215 GURL(kUserEntryURL), content::URLFetcher::GET, this)); 240 GURL(kUserEntryURL), content::URLFetcher::GET, this));
216 user_entry_fetcher_->SetRequestContext( 241 user_entry_fetcher_->SetRequestContext(
217 delegate_->GetBrowserProfile()->GetRequestContext()); 242 delegate_->GetBrowserProfile()->GetRequestContext());
218 if (!auth_token_.empty()) { 243 if (!auth_token_.empty()) {
219 user_entry_fetcher_->SetExtraRequestHeaders( 244 user_entry_fetcher_->SetExtraRequestHeaders(
220 base::StringPrintf(kAuthorizationHeader, auth_token_.c_str())); 245 base::StringPrintf(GetAuthorizationHeader(), auth_token_.c_str()));
221 } 246 }
222 user_entry_fetcher_->Start(); 247 user_entry_fetcher_->Start();
223 } 248 }
224 249
250 const char* ProfileDownloader::GetAuthorizationHeader() const {
251 return delegate_->GetShouldUseOAuthRefreshToken() ?
252 kOAuthAccessAuthorizationHeader : kClientAccessAuthorizationHeader;
253 }
254
225 ProfileDownloader::~ProfileDownloader() {} 255 ProfileDownloader::~ProfileDownloader() {}
226 256
227 void ProfileDownloader::OnURLFetchComplete(const content::URLFetcher* source) { 257 void ProfileDownloader::OnURLFetchComplete(const content::URLFetcher* source) {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 258 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
229 std::string data; 259 std::string data;
230 source->GetResponseAsString(&data); 260 source->GetResponseAsString(&data);
231 if (source->GetResponseCode() != 200) { 261 if (source->GetResponseCode() != 200) {
232 LOG(ERROR) << "Response code is " << source->GetResponseCode(); 262 LOG(ERROR) << "Response code is " << source->GetResponseCode();
233 LOG(ERROR) << "Url is " << source->GetURL().spec(); 263 LOG(ERROR) << "Url is " << source->GetURL().spec();
234 LOG(ERROR) << "Data is " << data; 264 LOG(ERROR) << "Data is " << data;
(...skipping 11 matching lines...) Expand all
246 delegate_->OnDownloadComplete(this, true); 276 delegate_->OnDownloadComplete(this, true);
247 return; 277 return;
248 } 278 }
249 VLOG(1) << "Fetching profile image from " << image_url; 279 VLOG(1) << "Fetching profile image from " << image_url;
250 profile_image_fetcher_.reset(content::URLFetcher::Create( 280 profile_image_fetcher_.reset(content::URLFetcher::Create(
251 GURL(image_url), content::URLFetcher::GET, this)); 281 GURL(image_url), content::URLFetcher::GET, this));
252 profile_image_fetcher_->SetRequestContext( 282 profile_image_fetcher_->SetRequestContext(
253 delegate_->GetBrowserProfile()->GetRequestContext()); 283 delegate_->GetBrowserProfile()->GetRequestContext());
254 if (!auth_token_.empty()) { 284 if (!auth_token_.empty()) {
255 profile_image_fetcher_->SetExtraRequestHeaders( 285 profile_image_fetcher_->SetExtraRequestHeaders(
256 base::StringPrintf(kAuthorizationHeader, auth_token_.c_str())); 286 base::StringPrintf(GetAuthorizationHeader(), auth_token_.c_str()));
257 } 287 }
258 profile_image_fetcher_->Start(); 288 profile_image_fetcher_->Start();
259 } else if (source == profile_image_fetcher_.get()) { 289 } else if (source == profile_image_fetcher_.get()) {
260 VLOG(1) << "Decoding the image..."; 290 VLOG(1) << "Decoding the image...";
261 scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder( 291 scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder(
262 this, data); 292 this, data);
263 image_decoder->Start(); 293 image_decoder->Start();
264 } 294 }
265 } 295 }
266 296
(...skipping 16 matching lines...) Expand all
283 313
284 void ProfileDownloader::Observe( 314 void ProfileDownloader::Observe(
285 int type, 315 int type,
286 const content::NotificationSource& source, 316 const content::NotificationSource& source,
287 const content::NotificationDetails& details) { 317 const content::NotificationDetails& details) {
288 DCHECK(type == chrome::NOTIFICATION_TOKEN_AVAILABLE || 318 DCHECK(type == chrome::NOTIFICATION_TOKEN_AVAILABLE ||
289 type == chrome::NOTIFICATION_TOKEN_REQUEST_FAILED); 319 type == chrome::NOTIFICATION_TOKEN_REQUEST_FAILED);
290 320
291 TokenService::TokenAvailableDetails* token_details = 321 TokenService::TokenAvailableDetails* token_details =
292 content::Details<TokenService::TokenAvailableDetails>(details).ptr(); 322 content::Details<TokenService::TokenAvailableDetails>(details).ptr();
323 std::string service = delegate_->GetShouldUseOAuthRefreshToken() ?
324 GaiaConstants::kGaiaOAuth2LoginRefreshToken :
325 GaiaConstants::kPicasaService;
326
293 if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) { 327 if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) {
294 if (token_details->service() == GaiaConstants::kPicasaService) { 328 if (token_details->service() == service) {
295 registrar_.RemoveAll(); 329 registrar_.RemoveAll();
296 auth_token_ = token_details->token(); 330 auth_token_ = token_details->token();
297 StartFetchingImage(); 331 StartFetchingImage();
298 } 332 }
299 } else { 333 } else {
300 if (token_details->service() == GaiaConstants::kPicasaService) { 334 if (token_details->service() == service) {
301 LOG(WARNING) << "ProfileDownloader: token request failed"; 335 LOG(WARNING) << "ProfileDownloader: token request failed";
302 delegate_->OnDownloadComplete(this, false); 336 delegate_->OnDownloadComplete(this, false);
303 } 337 }
304 } 338 }
305 } 339 }
340
341 void ProfileDownloader::OnGetTokenSuccess(const std::string& access_token) {
Ivan Korotkov 2011/11/30 11:17:31 I'm kinda puzzled, when does this get called? When
sail 2011/11/30 11:34:10 This is a callback for the oauth2_access_token_fet
342 auth_token_ = access_token;
343 StartFetchingImage();
344 }
345
346 void ProfileDownloader::OnGetTokenFailure(const GoogleServiceAuthError& error) {
347 LOG(WARNING) << "ProfileDownloader: token request using refresh token failed";
348 delegate_->OnDownloadComplete(this, false);
349 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698