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

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: fix observer 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 the ClientLogin access
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_->ShouldUseOAuthRefreshToken() &&
204 service->HasOAuthLoginToken()) {
205 StartFetchingOAuth2AccessToken();
206 } else if (!delegate_->ShouldUseOAuthRefreshToken() &&
207 service->HasTokenForService(GaiaConstants::kPicasaService)) {
191 auth_token_ = 208 auth_token_ =
192 service->GetTokenForService(GaiaConstants::kPicasaService); 209 service->GetTokenForService(GaiaConstants::kPicasaService);
193 StartFetchingImage(); 210 StartFetchingImage();
194 } else { 211 } else {
195 registrar_.Add(this, 212 registrar_.Add(this,
196 chrome::NOTIFICATION_TOKEN_AVAILABLE, 213 chrome::NOTIFICATION_TOKEN_AVAILABLE,
197 content::Source<TokenService>(service)); 214 content::Source<TokenService>(service));
198 registrar_.Add(this, 215 registrar_.Add(this,
199 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, 216 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED,
200 content::Source<TokenService>(service)); 217 content::Source<TokenService>(service));
201 } 218 }
202 } 219 }
203 220
204 string16 ProfileDownloader::GetProfileFullName() const { 221 string16 ProfileDownloader::GetProfileFullName() const {
205 return profile_full_name_; 222 return profile_full_name_;
206 } 223 }
207 224
208 SkBitmap ProfileDownloader::GetProfilePicture() const { 225 SkBitmap ProfileDownloader::GetProfilePicture() const {
209 return profile_picture_; 226 return profile_picture_;
210 } 227 }
211 228
212 void ProfileDownloader::StartFetchingImage() { 229 void ProfileDownloader::StartFetchingImage() {
213 VLOG(1) << "Fetching user entry with token: " << auth_token_; 230 VLOG(1) << "Fetching user entry with token: " << auth_token_;
214 user_entry_fetcher_.reset(content::URLFetcher::Create( 231 user_entry_fetcher_.reset(content::URLFetcher::Create(
215 GURL(kUserEntryURL), content::URLFetcher::GET, this)); 232 GURL(kUserEntryURL), content::URLFetcher::GET, this));
216 user_entry_fetcher_->SetRequestContext( 233 user_entry_fetcher_->SetRequestContext(
217 delegate_->GetBrowserProfile()->GetRequestContext()); 234 delegate_->GetBrowserProfile()->GetRequestContext());
218 if (!auth_token_.empty()) { 235 if (!auth_token_.empty()) {
219 user_entry_fetcher_->SetExtraRequestHeaders( 236 user_entry_fetcher_->SetExtraRequestHeaders(
220 base::StringPrintf(kAuthorizationHeader, auth_token_.c_str())); 237 base::StringPrintf(GetAuthorizationHeader(), auth_token_.c_str()));
221 } 238 }
222 user_entry_fetcher_->Start(); 239 user_entry_fetcher_->Start();
223 } 240 }
224 241
242 const char* ProfileDownloader::GetAuthorizationHeader() const {
243 return delegate_->ShouldUseOAuthRefreshToken() ?
244 kOAuthAccessAuthorizationHeader : kClientAccessAuthorizationHeader;
245 }
246
247 void ProfileDownloader::StartFetchingOAuth2AccessToken() {
248 TokenService* service = delegate_->GetBrowserProfile()->GetTokenService();
249 DCHECK(!service->GetOAuth2LoginRefreshToken().empty());
250
251 std::vector<std::string> scopes;
252 scopes.push_back(kPicasaScope);
253 oauth2_access_token_fetcher_.reset(new OAuth2AccessTokenFetcher(
254 this, delegate_->GetBrowserProfile()->GetRequestContext()));
255 oauth2_access_token_fetcher_->Start(
256 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
257 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
258 service->GetOAuth2LoginRefreshToken(),
259 scopes);
260 }
261
225 ProfileDownloader::~ProfileDownloader() {} 262 ProfileDownloader::~ProfileDownloader() {}
226 263
227 void ProfileDownloader::OnURLFetchComplete(const content::URLFetcher* source) { 264 void ProfileDownloader::OnURLFetchComplete(const content::URLFetcher* source) {
228 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
229 std::string data; 266 std::string data;
230 source->GetResponseAsString(&data); 267 source->GetResponseAsString(&data);
231 if (source->GetResponseCode() != 200) { 268 if (source->GetResponseCode() != 200) {
232 LOG(ERROR) << "Response code is " << source->GetResponseCode(); 269 LOG(ERROR) << "Response code is " << source->GetResponseCode();
233 LOG(ERROR) << "Url is " << source->GetURL().spec(); 270 LOG(ERROR) << "Url is " << source->GetURL().spec();
234 LOG(ERROR) << "Data is " << data; 271 LOG(ERROR) << "Data is " << data;
(...skipping 11 matching lines...) Expand all
246 delegate_->OnDownloadComplete(this, true); 283 delegate_->OnDownloadComplete(this, true);
247 return; 284 return;
248 } 285 }
249 VLOG(1) << "Fetching profile image from " << image_url; 286 VLOG(1) << "Fetching profile image from " << image_url;
250 profile_image_fetcher_.reset(content::URLFetcher::Create( 287 profile_image_fetcher_.reset(content::URLFetcher::Create(
251 GURL(image_url), content::URLFetcher::GET, this)); 288 GURL(image_url), content::URLFetcher::GET, this));
252 profile_image_fetcher_->SetRequestContext( 289 profile_image_fetcher_->SetRequestContext(
253 delegate_->GetBrowserProfile()->GetRequestContext()); 290 delegate_->GetBrowserProfile()->GetRequestContext());
254 if (!auth_token_.empty()) { 291 if (!auth_token_.empty()) {
255 profile_image_fetcher_->SetExtraRequestHeaders( 292 profile_image_fetcher_->SetExtraRequestHeaders(
256 base::StringPrintf(kAuthorizationHeader, auth_token_.c_str())); 293 base::StringPrintf(GetAuthorizationHeader(), auth_token_.c_str()));
257 } 294 }
258 profile_image_fetcher_->Start(); 295 profile_image_fetcher_->Start();
259 } else if (source == profile_image_fetcher_.get()) { 296 } else if (source == profile_image_fetcher_.get()) {
260 VLOG(1) << "Decoding the image..."; 297 VLOG(1) << "Decoding the image...";
261 scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder( 298 scoped_refptr<ImageDecoder> image_decoder = new ImageDecoder(
262 this, data); 299 this, data);
263 image_decoder->Start(); 300 image_decoder->Start();
264 } 301 }
265 } 302 }
266 303
(...skipping 16 matching lines...) Expand all
283 320
284 void ProfileDownloader::Observe( 321 void ProfileDownloader::Observe(
285 int type, 322 int type,
286 const content::NotificationSource& source, 323 const content::NotificationSource& source,
287 const content::NotificationDetails& details) { 324 const content::NotificationDetails& details) {
288 DCHECK(type == chrome::NOTIFICATION_TOKEN_AVAILABLE || 325 DCHECK(type == chrome::NOTIFICATION_TOKEN_AVAILABLE ||
289 type == chrome::NOTIFICATION_TOKEN_REQUEST_FAILED); 326 type == chrome::NOTIFICATION_TOKEN_REQUEST_FAILED);
290 327
291 TokenService::TokenAvailableDetails* token_details = 328 TokenService::TokenAvailableDetails* token_details =
292 content::Details<TokenService::TokenAvailableDetails>(details).ptr(); 329 content::Details<TokenService::TokenAvailableDetails>(details).ptr();
330 std::string service = delegate_->ShouldUseOAuthRefreshToken() ?
331 GaiaConstants::kGaiaOAuth2LoginRefreshToken :
332 GaiaConstants::kPicasaService;
333
293 if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) { 334 if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) {
294 if (token_details->service() == GaiaConstants::kPicasaService) { 335 if (token_details->service() == service) {
295 registrar_.RemoveAll(); 336 registrar_.RemoveAll();
296 auth_token_ = token_details->token(); 337 if (delegate_->ShouldUseOAuthRefreshToken()) {
297 StartFetchingImage(); 338 StartFetchingOAuth2AccessToken();
339 } else {
340 auth_token_ = token_details->token();
341 StartFetchingImage();
342 }
298 } 343 }
299 } else { 344 } else {
300 if (token_details->service() == GaiaConstants::kPicasaService) { 345 if (token_details->service() == service) {
301 LOG(WARNING) << "ProfileDownloader: token request failed"; 346 LOG(WARNING) << "ProfileDownloader: token request failed";
302 delegate_->OnDownloadComplete(this, false); 347 delegate_->OnDownloadComplete(this, false);
303 } 348 }
304 } 349 }
305 } 350 }
351
352 // Callback for OAuth2AccessTokenFetcher on success. |access_token| is the token
353 // used to start fetching user data.
354 void ProfileDownloader::OnGetTokenSuccess(const std::string& access_token) {
355 auth_token_ = access_token;
356 StartFetchingImage();
357 }
358
359 // Callback for OAuth2AccessTokenFetcher on failure.
360 void ProfileDownloader::OnGetTokenFailure(const GoogleServiceAuthError& error) {
361 LOG(WARNING) << "ProfileDownloader: token request using refresh token failed";
362 delegate_->OnDownloadComplete(this, false);
363 }
OLDNEW
« no previous file with comments | « chrome/browser/profiles/profile_downloader.h ('k') | chrome/browser/profiles/profile_downloader_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698