OLD | NEW |
---|---|
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
13 #include "base/strings/string_split.h" | 13 #include "base/strings/string_split.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
16 #include "base/values.h" | 16 #include "base/values.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/browser/profiles/profile_manager.h" | 19 #include "chrome/browser/profiles/profile_manager.h" |
20 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | 20 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
21 #include "chrome/browser/signin/signin_manager_factory.h" | 21 #include "chrome/browser/signin/signin_manager_factory.h" |
22 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 22 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
23 #include "components/signin/core/browser/signin_manager.h" | 23 #include "components/signin/core/browser/signin_manager.h" |
24 #include "components/signin/core/common/profile_management_switches.h" | |
24 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
25 #include "google_apis/gaia/gaia_constants.h" | 26 #include "google_apis/gaia/gaia_constants.h" |
26 #include "google_apis/gaia/gaia_urls.h" | 27 #include "google_apis/gaia/gaia_urls.h" |
27 #include "net/base/load_flags.h" | 28 #include "net/base/load_flags.h" |
28 #include "net/url_request/url_fetcher.h" | 29 #include "net/url_request/url_fetcher.h" |
29 #include "net/url_request/url_request_status.h" | 30 #include "net/url_request/url_request_status.h" |
30 #include "skia/ext/image_operations.h" | 31 #include "skia/ext/image_operations.h" |
31 #include "url/gurl.h" | 32 #include "url/gurl.h" |
32 | 33 |
33 using content::BrowserThread; | 34 using content::BrowserThread; |
34 | 35 |
35 namespace { | 36 namespace { |
36 | 37 |
37 // Template for optional authorization header when using an OAuth access token. | 38 // Template for optional authorization header when using an OAuth access token. |
38 const char kAuthorizationHeader[] = | 39 const char kAuthorizationHeader[] = |
39 "Authorization: Bearer %s"; | 40 "Authorization: Bearer %s"; |
40 | 41 |
41 // URL requesting user info. | 42 // URL requesting user info. |
42 const char kUserEntryURL[] = | 43 const char kUserEntryURL[] = |
43 "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"; | 44 "https://www.googleapis.com/oauth2/v1/userinfo?alt=json"; |
44 | 45 |
45 // OAuth scope for the user info API. | 46 // OAuth scope for the user info API. |
46 // For more info, see https://developers.google.com/accounts/docs/OAuth2LoginV1. | 47 // For more info, see https://developers.google.com/accounts/docs/OAuth2LoginV1. |
47 const char kAPIScope[] = "https://www.googleapis.com/auth/userinfo.profile"; | 48 const char kAPIEmailScope[] = "https://www.googleapis.com/auth/userinfo.email"; |
49 const char kAPIProfileScope[] = | |
50 "https://www.googleapis.com/auth/userinfo.profile"; | |
48 | 51 |
49 // Path in JSON dictionary to user's photo thumbnail URL. | 52 // Path in JSON dictionary to user's photo thumbnail URL. |
50 const char kPhotoThumbnailURLPath[] = "picture"; | 53 const char kPhotoThumbnailURLPath[] = "picture"; |
51 | 54 |
55 // Path in JSON dictionary to user's hosted domain. | |
56 const char kHostedDomainPath[] = "hd"; | |
57 | |
52 // From the user info API, this field corresponds to the full name of the user. | 58 // From the user info API, this field corresponds to the full name of the user. |
53 const char kFullNamePath[] = "name"; | 59 const char kFullNamePath[] = "name"; |
54 | 60 |
55 const char kGivenNamePath[] = "given_name"; | 61 const char kGivenNamePath[] = "given_name"; |
56 | 62 |
57 // Path in JSON dictionary to user's preferred locale. | 63 // Path in JSON dictionary to user's preferred locale. |
58 const char kLocalePath[] = "locale"; | 64 const char kLocalePath[] = "locale"; |
59 | 65 |
60 // Path format for specifying thumbnail's size. | 66 // Path format for specifying thumbnail's size. |
61 const char kThumbnailSizeFormat[] = "s%d-c"; | 67 const char kThumbnailSizeFormat[] = "s%d-c"; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
131 } // namespace | 137 } // namespace |
132 | 138 |
133 // Parses the entry response and gets the name and profile image URL. | 139 // Parses the entry response and gets the name and profile image URL. |
134 // |data| should be the JSON formatted data return by the response. | 140 // |data| should be the JSON formatted data return by the response. |
135 // Returns false to indicate a parsing error. | 141 // Returns false to indicate a parsing error. |
136 bool ProfileDownloader::ParseProfileJSON(const std::string& data, | 142 bool ProfileDownloader::ParseProfileJSON(const std::string& data, |
137 base::string16* full_name, | 143 base::string16* full_name, |
138 base::string16* given_name, | 144 base::string16* given_name, |
139 std::string* url, | 145 std::string* url, |
140 int image_size, | 146 int image_size, |
141 std::string* profile_locale) { | 147 std::string* profile_locale, |
148 base::string16* hosted_domain) { | |
142 DCHECK(full_name); | 149 DCHECK(full_name); |
143 DCHECK(given_name); | 150 DCHECK(given_name); |
144 DCHECK(url); | 151 DCHECK(url); |
145 DCHECK(profile_locale); | 152 DCHECK(profile_locale); |
153 DCHECK(hosted_domain); | |
146 | 154 |
147 *full_name = base::string16(); | 155 *full_name = base::string16(); |
148 *given_name = base::string16(); | 156 *given_name = base::string16(); |
149 *url = std::string(); | 157 *url = std::string(); |
150 *profile_locale = std::string(); | 158 *profile_locale = std::string(); |
159 *hosted_domain = base::string16(); | |
151 | 160 |
152 int error_code = -1; | 161 int error_code = -1; |
153 std::string error_message; | 162 std::string error_message; |
154 scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError( | 163 scoped_ptr<base::Value> root_value(base::JSONReader::ReadAndReturnError( |
155 data, base::JSON_PARSE_RFC, &error_code, &error_message)); | 164 data, base::JSON_PARSE_RFC, &error_code, &error_message)); |
156 if (!root_value) { | 165 if (!root_value) { |
157 LOG(ERROR) << "Error while parsing user entry response: " | 166 LOG(ERROR) << "Error while parsing user entry response: " |
158 << error_message; | 167 << error_message; |
159 return false; | 168 return false; |
160 } | 169 } |
161 if (!root_value->IsType(base::Value::TYPE_DICTIONARY)) { | 170 if (!root_value->IsType(base::Value::TYPE_DICTIONARY)) { |
162 LOG(ERROR) << "JSON root is not a dictionary: " | 171 LOG(ERROR) << "JSON root is not a dictionary: " |
163 << root_value->GetType(); | 172 << root_value->GetType(); |
164 return false; | 173 return false; |
165 } | 174 } |
166 base::DictionaryValue* root_dictionary = | 175 base::DictionaryValue* root_dictionary = |
167 static_cast<base::DictionaryValue*>(root_value.get()); | 176 static_cast<base::DictionaryValue*>(root_value.get()); |
168 | 177 |
169 root_dictionary->GetString(kFullNamePath, full_name); | 178 root_dictionary->GetString(kFullNamePath, full_name); |
170 root_dictionary->GetString(kGivenNamePath, given_name); | 179 root_dictionary->GetString(kGivenNamePath, given_name); |
171 root_dictionary->GetString(kLocalePath, profile_locale); | 180 root_dictionary->GetString(kLocalePath, profile_locale); |
181 root_dictionary->GetString(kHostedDomainPath, hosted_domain); | |
172 | 182 |
173 std::string url_string; | 183 std::string url_string; |
174 if (root_dictionary->GetString(kPhotoThumbnailURLPath, &url_string)) { | 184 if (root_dictionary->GetString(kPhotoThumbnailURLPath, &url_string)) { |
175 GURL new_url; | 185 GURL new_url; |
176 if (!GetImageURLWithSize(GURL(url_string), image_size, &new_url)) { | 186 if (!GetImageURLWithSize(GURL(url_string), image_size, &new_url)) { |
177 LOG(ERROR) << "GetImageURLWithSize failed for url: " << url_string; | 187 LOG(ERROR) << "GetImageURLWithSize failed for url: " << url_string; |
178 return false; | 188 return false; |
179 } | 189 } |
180 *url = new_url.spec(); | 190 *url = new_url.spec(); |
181 } | 191 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 account_id_ = | 250 account_id_ = |
241 account_id.empty() ? | 251 account_id.empty() ? |
242 signin_manager->GetAuthenticatedAccountId() : account_id; | 252 signin_manager->GetAuthenticatedAccountId() : account_id; |
243 if (service->RefreshTokenIsAvailable(account_id_)) { | 253 if (service->RefreshTokenIsAvailable(account_id_)) { |
244 StartFetchingOAuth2AccessToken(); | 254 StartFetchingOAuth2AccessToken(); |
245 } else { | 255 } else { |
246 service->AddObserver(this); | 256 service->AddObserver(this); |
247 } | 257 } |
248 } | 258 } |
249 | 259 |
260 base::string16 ProfileDownloader::GetProfileHostedDomain() const { | |
261 return profile_hosted_domain_; | |
262 } | |
263 | |
250 base::string16 ProfileDownloader::GetProfileFullName() const { | 264 base::string16 ProfileDownloader::GetProfileFullName() const { |
251 return profile_full_name_; | 265 return profile_full_name_; |
252 } | 266 } |
253 | 267 |
254 base::string16 ProfileDownloader::GetProfileGivenName() const { | 268 base::string16 ProfileDownloader::GetProfileGivenName() const { |
255 return profile_given_name_; | 269 return profile_given_name_; |
256 } | 270 } |
257 | 271 |
258 std::string ProfileDownloader::GetProfileLocale() const { | 272 std::string ProfileDownloader::GetProfileLocale() const { |
259 return profile_locale_; | 273 return profile_locale_; |
260 } | 274 } |
261 | 275 |
262 SkBitmap ProfileDownloader::GetProfilePicture() const { | 276 SkBitmap ProfileDownloader::GetProfilePicture() const { |
263 return profile_picture_; | 277 return profile_picture_; |
264 } | 278 } |
265 | 279 |
266 ProfileDownloader::PictureStatus ProfileDownloader::GetProfilePictureStatus() | 280 ProfileDownloader::PictureStatus ProfileDownloader::GetProfilePictureStatus() |
267 const { | 281 const { |
268 return picture_status_; | 282 return picture_status_; |
269 } | 283 } |
270 | 284 |
271 std::string ProfileDownloader::GetProfilePictureURL() const { | 285 std::string ProfileDownloader::GetProfilePictureURL() const { |
272 return picture_url_; | 286 return picture_url_; |
273 } | 287 } |
274 | 288 |
275 void ProfileDownloader::StartFetchingImage() { | 289 void ProfileDownloader::StartFetchingImage() { |
276 VLOG(1) << "Fetching user entry with token: " << auth_token_; | 290 VLOG(1) << "Fetching user entry with token: " << auth_token_; |
277 user_entry_fetcher_.reset(net::URLFetcher::Create( | 291 user_entry_fetcher_.reset(net::URLFetcher::Create( |
278 GURL(kUserEntryURL), net::URLFetcher::GET, this)); | 292 GURL(kUserEntryURL), net::URLFetcher::GET, this)); |
Roger Tawa OOO till Jul 10th
2014/09/17 21:11:00
Please use gaia::GaiaOAuthClient to fetch user inf
Mike Lerman
2014/09/18 16:00:28
Done.
| |
279 user_entry_fetcher_->SetRequestContext( | 293 user_entry_fetcher_->SetRequestContext( |
280 delegate_->GetBrowserProfile()->GetRequestContext()); | 294 delegate_->GetBrowserProfile()->GetRequestContext()); |
281 user_entry_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 295 user_entry_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
282 net::LOAD_DO_NOT_SAVE_COOKIES); | 296 net::LOAD_DO_NOT_SAVE_COOKIES); |
283 if (!auth_token_.empty()) { | 297 if (!auth_token_.empty()) { |
284 user_entry_fetcher_->SetExtraRequestHeaders( | 298 user_entry_fetcher_->SetExtraRequestHeaders( |
285 base::StringPrintf(kAuthorizationHeader, auth_token_.c_str())); | 299 base::StringPrintf(kAuthorizationHeader, auth_token_.c_str())); |
286 } | 300 } |
287 user_entry_fetcher_->Start(); | 301 user_entry_fetcher_->Start(); |
288 } | 302 } |
289 | 303 |
290 void ProfileDownloader::StartFetchingOAuth2AccessToken() { | 304 void ProfileDownloader::StartFetchingOAuth2AccessToken() { |
291 Profile* profile = delegate_->GetBrowserProfile(); | 305 Profile* profile = delegate_->GetBrowserProfile(); |
292 OAuth2TokenService::ScopeSet scopes; | 306 OAuth2TokenService::ScopeSet scopes; |
293 scopes.insert(kAPIScope); | 307 scopes.insert(kAPIProfileScope); |
308 // Increase scope to get hd attribute to determine if lock should be enabled. | |
309 if (switches::IsNewProfileManagement()) | |
310 scopes.insert(kAPIEmailScope); | |
294 ProfileOAuth2TokenService* token_service = | 311 ProfileOAuth2TokenService* token_service = |
295 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); | 312 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); |
296 oauth2_access_token_request_ = token_service->StartRequest( | 313 oauth2_access_token_request_ = token_service->StartRequest( |
297 account_id_, scopes, this); | 314 account_id_, scopes, this); |
298 } | 315 } |
299 | 316 |
300 ProfileDownloader::~ProfileDownloader() { | 317 ProfileDownloader::~ProfileDownloader() { |
301 // Ensures PO2TS observation is cleared when ProfileDownloader is destructed | 318 // Ensures PO2TS observation is cleared when ProfileDownloader is destructed |
302 // before refresh token is available. | 319 // before refresh token is available. |
303 ProfileOAuth2TokenService* service = | 320 ProfileOAuth2TokenService* service = |
(...skipping 21 matching lines...) Expand all Loading... | |
325 return; | 342 return; |
326 } | 343 } |
327 | 344 |
328 if (source == user_entry_fetcher_.get()) { | 345 if (source == user_entry_fetcher_.get()) { |
329 std::string image_url; | 346 std::string image_url; |
330 if (!ParseProfileJSON(data, | 347 if (!ParseProfileJSON(data, |
331 &profile_full_name_, | 348 &profile_full_name_, |
332 &profile_given_name_, | 349 &profile_given_name_, |
333 &image_url, | 350 &image_url, |
334 delegate_->GetDesiredImageSideLength(), | 351 delegate_->GetDesiredImageSideLength(), |
335 &profile_locale_)) { | 352 &profile_locale_, |
353 &profile_hosted_domain_)) { | |
336 delegate_->OnProfileDownloadFailure( | 354 delegate_->OnProfileDownloadFailure( |
337 this, ProfileDownloaderDelegate::SERVICE_ERROR); | 355 this, ProfileDownloaderDelegate::SERVICE_ERROR); |
338 return; | 356 return; |
339 } | 357 } |
340 if (!delegate_->NeedsProfilePicture()) { | 358 if (!delegate_->NeedsProfilePicture()) { |
341 VLOG(1) << "Skipping profile picture download"; | 359 VLOG(1) << "Skipping profile picture download"; |
342 delegate_->OnProfileDownloadSuccess(this); | 360 delegate_->OnProfileDownloadSuccess(this); |
343 return; | 361 return; |
344 } | 362 } |
345 if (IsDefaultProfileImageURL(image_url)) { | 363 if (IsDefaultProfileImageURL(image_url)) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
423 void ProfileDownloader::OnGetTokenFailure( | 441 void ProfileDownloader::OnGetTokenFailure( |
424 const OAuth2TokenService::Request* request, | 442 const OAuth2TokenService::Request* request, |
425 const GoogleServiceAuthError& error) { | 443 const GoogleServiceAuthError& error) { |
426 DCHECK_EQ(request, oauth2_access_token_request_.get()); | 444 DCHECK_EQ(request, oauth2_access_token_request_.get()); |
427 oauth2_access_token_request_.reset(); | 445 oauth2_access_token_request_.reset(); |
428 LOG(WARNING) << "ProfileDownloader: token request using refresh token failed:" | 446 LOG(WARNING) << "ProfileDownloader: token request using refresh token failed:" |
429 << error.ToString(); | 447 << error.ToString(); |
430 delegate_->OnProfileDownloadFailure( | 448 delegate_->OnProfileDownloadFailure( |
431 this, ProfileDownloaderDelegate::TOKEN_ERROR); | 449 this, ProfileDownloaderDelegate::TOKEN_ERROR); |
432 } | 450 } |
OLD | NEW |