obfuscated_gaia_id_fetcher.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 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 "chrome/browser/extensions/api/push_messaging/obfuscated_gaia_id_fetcher.h" 6 7#include <vector> 8 9#include "base/json/json_reader.h" 10#include "base/values.h" 11#include "google_apis/gaia/google_service_auth_error.h" 12#include "net/url_request/url_fetcher.h" 13#include "net/url_request/url_request_status.h" 14 15using net::URLFetcher; 16using net::URLRequestContextGetter; 17using net::URLRequestStatus; 18 19namespace { 20 21// URL of the service to get obfuscated Gaia ID (here misnamed channel ID). 22static const char kCWSChannelServiceURL[] = 23 "https://www.googleapis.com/gcm_for_chrome/v1/channels/id"; 24 25GoogleServiceAuthError CreateAuthError(const URLFetcher* source) { 26 if (source->GetStatus().status() == URLRequestStatus::CANCELED) { 27 return GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED); 28 } else { 29 // TODO(munjal): Improve error handling. Currently we return connection 30 // error for even application level errors. We need to either expand the 31 // GoogleServiceAuthError enum or create a new one to report better 32 // errors. 33 if (source->GetStatus().is_success()) { 34 DLOG(WARNING) << "Remote server returned " << source->GetResponseCode(); 35 return GoogleServiceAuthError::FromConnectionError( 36 source->GetResponseCode()); 37 } else { 38 DLOG(WARNING) << "URLFetcher failed: " << source->GetStatus().error(); 39 return GoogleServiceAuthError::FromConnectionError( 40 source->GetStatus().error()); 41 } 42 } 43} 44 45// Returns a vector of scopes needed to call the API to get obfuscated Gaia ID. 46std::vector<std::string> GetScopes() { 47 std::vector<std::string> scopes; 48 scopes.push_back("https://www.googleapis.com/auth/gcm_for_chrome.readonly"); 49 return scopes; 50} 51 52} // namespace 53 54namespace extensions { 55 56ObfuscatedGaiaIdFetcher::ObfuscatedGaiaIdFetcher( 57 URLRequestContextGetter* context, 58 Delegate* delegate, 59 const std::string& refresh_token) 60 : OAuth2ApiCallFlow(context, refresh_token, std::string(), GetScopes()), 61 delegate_(delegate) { 62 DCHECK(delegate); 63} 64 65ObfuscatedGaiaIdFetcher::~ObfuscatedGaiaIdFetcher() { } 66 67void ObfuscatedGaiaIdFetcher::ReportSuccess(const std::string& obfuscated_id) { 68 if (delegate_) 69 delegate_->OnObfuscatedGaiaIdFetchSuccess(obfuscated_id); 70} 71 72void ObfuscatedGaiaIdFetcher::ReportFailure( 73 const GoogleServiceAuthError& error) { 74 if (delegate_) 75 delegate_->OnObfuscatedGaiaIdFetchFailure(error); 76} 77 78GURL ObfuscatedGaiaIdFetcher::CreateApiCallUrl() { 79 return GURL(kCWSChannelServiceURL); 80} 81 82std::string ObfuscatedGaiaIdFetcher::CreateApiCallBody() { 83 // Nothing to do here, we don't need a body for this request, the URL 84 // encodes all the proper arguments. 85 return std::string(); 86} 87 88void ObfuscatedGaiaIdFetcher::ProcessApiCallSuccess( 89 const net::URLFetcher* source) { 90 // TODO(munjal): Change error code paths in this method to report an 91 // internal error. 92 std::string response_body; 93 CHECK(source->GetResponseAsString(&response_body)); 94 95 std::string obfuscated_id; 96 if (ParseResponse(response_body, &obfuscated_id)) 97 ReportSuccess(obfuscated_id); 98 else 99 // we picked 101 arbitrarily to help us correlate the error with this code. 100 ReportFailure(GoogleServiceAuthError::FromConnectionError(101)); 101} 102 103void ObfuscatedGaiaIdFetcher::ProcessApiCallFailure( 104 const net::URLFetcher* source) { 105 ReportFailure(CreateAuthError(source)); 106} 107 108void ObfuscatedGaiaIdFetcher::ProcessNewAccessToken( 109 const std::string& obfuscated_id) { 110 // We generate a new access token every time instead of storing the access 111 // token since access tokens expire every hour and we expect to get 112 // obfuscated Gaia ID very infrequently. 113} 114 115void ObfuscatedGaiaIdFetcher::ProcessMintAccessTokenFailure( 116 const GoogleServiceAuthError& error) { 117 // We failed to generate the token needed to call the API to get 118 // the obfuscated Gaia ID, so report failure to the caller. 119 ReportFailure(error); 120} 121 122// static 123bool ObfuscatedGaiaIdFetcher::ParseResponse( 124 const std::string& data, std::string* result) { 125 scoped_ptr<base::Value> value(base::JSONReader::Read(data)); 126 127 if (!value.get()) 128 return false; 129 130 DictionaryValue* dict = NULL; 131 if (!value->GetAsDictionary(&dict)) 132 return false; 133 134 return dict->GetString("id", result); 135} 136 137} // namespace extensions 138