Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / identity / gaia_web_auth_flow.cc
index 2d7bac1..54c2922 100644 (file)
@@ -4,10 +4,18 @@
 
 #include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h"
 
+#include "base/debug/trace_event.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/signin/chrome_signin_client_factory.h"
+#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
+#include "components/signin/core/browser/profile_oauth2_token_service.h"
+#include "components/signin/core/browser/signin_manager.h"
+#include "google_apis/gaia/gaia_constants.h"
 #include "google_apis/gaia/gaia_urls.h"
 #include "net/base/escape.h"
 
@@ -15,11 +23,20 @@ namespace extensions {
 
 GaiaWebAuthFlow::GaiaWebAuthFlow(Delegate* delegate,
                                  Profile* profile,
-                                 const std::string& extension_id,
-                                 const OAuth2Info& oauth2_info,
+                                 const ExtensionTokenKey* token_key,
+                                 const std::string& oauth2_client_id,
                                  const std::string& locale)
     : delegate_(delegate),
-      profile_(profile) {
+      profile_(profile),
+      account_id_(token_key->account_id) {
+  TRACE_EVENT_ASYNC_BEGIN2("identity",
+                           "GaiaWebAuthFlow",
+                           this,
+                           "extension_id",
+                           token_key->extension_id,
+                           "account_id",
+                           token_key->account_id);
+
   const char kOAuth2RedirectPathFormat[] = "/%s#";
   const char kOAuth2AuthorizeFormat[] =
       "?response_type=token&approval_prompt=force&authuser=0&"
@@ -28,37 +45,65 @@ GaiaWebAuthFlow::GaiaWebAuthFlow(Delegate* delegate,
       "origin=chrome-extension://%s/&"
       "redirect_uri=%s:/%s&"
       "hl=%s";
+  // Additional parameters to pass if device_id is enabled.
+  const char kOAuth2AuthorizeFormatDeviceIdAddendum[] =
+      "&device_id=%s&"
+      "device_type=chrome";
 
+  std::vector<std::string> scopes(token_key->scopes.begin(),
+                                  token_key->scopes.end());
   std::vector<std::string> client_id_parts;
-  base::SplitString(oauth2_info.client_id, '.', &client_id_parts);
+  base::SplitString(oauth2_client_id, '.', &client_id_parts);
   std::reverse(client_id_parts.begin(), client_id_parts.end());
   redirect_scheme_ = JoinString(client_id_parts, '.');
-
-  redirect_path_prefix_ =
-      base::StringPrintf(kOAuth2RedirectPathFormat, extension_id.c_str());
-
+  std::string signin_scoped_device_id;
+  // profile_ can be nullptr in unittests.
+  SigninClient* signin_client =
+      profile_ ? ChromeSigninClientFactory::GetForProfile(profile_) : nullptr;
+  if (signin_client)
+    signin_scoped_device_id = signin_client->GetSigninScopedDeviceId();
+
+  redirect_path_prefix_ = base::StringPrintf(kOAuth2RedirectPathFormat,
+                                             token_key->extension_id.c_str());
+
+  std::string oauth2_authorize_params = base::StringPrintf(
+      kOAuth2AuthorizeFormat,
+      oauth2_client_id.c_str(),
+      net::EscapeUrlEncodedData(JoinString(scopes, ' '), true).c_str(),
+      token_key->extension_id.c_str(),
+      redirect_scheme_.c_str(),
+      token_key->extension_id.c_str(),
+      locale.c_str());
+  if (!signin_scoped_device_id.empty()) {
+    oauth2_authorize_params += base::StringPrintf(
+        kOAuth2AuthorizeFormatDeviceIdAddendum,
+        net::EscapeUrlEncodedData(signin_scoped_device_id, true).c_str());
+  }
   auth_url_ = GaiaUrls::GetInstance()->oauth2_auth_url().Resolve(
-      base::StringPrintf(kOAuth2AuthorizeFormat,
-                         oauth2_info.client_id.c_str(),
-                         net::EscapeUrlEncodedData(
-                             JoinString(oauth2_info.scopes, ' '), true).c_str(),
-                         extension_id.c_str(),
-                         redirect_scheme_.c_str(),
-                         extension_id.c_str(),
-                         locale.c_str()));
+      oauth2_authorize_params);
 }
 
 GaiaWebAuthFlow::~GaiaWebAuthFlow() {
+  TRACE_EVENT_ASYNC_END0("identity", "GaiaWebAuthFlow", this);
+
   if (web_flow_)
     web_flow_.release()->DetachDelegateAndDelete();
 }
 
 void GaiaWebAuthFlow::Start() {
-  ubertoken_fetcher_.reset(new UbertokenFetcher(profile_, this));
-  ubertoken_fetcher_->StartFetchingToken();
+  ProfileOAuth2TokenService* token_service =
+      ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
+  ubertoken_fetcher_.reset(new UbertokenFetcher(token_service,
+                                                this,
+                                                GaiaConstants::kChromeSource,
+                                                profile_->GetRequestContext()));
+  ubertoken_fetcher_->StartFetchingToken(account_id_);
 }
 
 void GaiaWebAuthFlow::OnUbertokenSuccess(const std::string& token) {
+  TRACE_EVENT_ASYNC_STEP_PAST0(
+      "identity", "GaiaWebAuthFlow", this, "OnUbertokenSuccess");
+
   const char kMergeSessionQueryFormat[] = "?uberauth=%s&"
                                           "continue=%s&"
                                           "source=appsv2";
@@ -75,6 +120,14 @@ void GaiaWebAuthFlow::OnUbertokenSuccess(const std::string& token) {
 }
 
 void GaiaWebAuthFlow::OnUbertokenFailure(const GoogleServiceAuthError& error) {
+  TRACE_EVENT_ASYNC_STEP_PAST1("identity",
+                               "GaiaWebAuthFlow",
+                               this,
+                               "OnUbertokenSuccess",
+                               "error",
+                               error.ToString());
+
+  DVLOG(1) << "OnUbertokenFailure: " << error.error_message();
   delegate_->OnGaiaFlowFailure(
       GaiaWebAuthFlow::SERVICE_AUTH_ERROR, error, std::string());
 }
@@ -87,6 +140,7 @@ void GaiaWebAuthFlow::OnAuthFlowFailure(WebAuthFlow::Failure failure) {
       gaia_failure = GaiaWebAuthFlow::WINDOW_CLOSED;
       break;
     case WebAuthFlow::LOAD_FAILED:
+      DVLOG(1) << "OnAuthFlowFailure LOAD_FAILED";
       gaia_failure = GaiaWebAuthFlow::LOAD_FAILED;
       break;
     default:
@@ -95,6 +149,13 @@ void GaiaWebAuthFlow::OnAuthFlowFailure(WebAuthFlow::Failure failure) {
       break;
   }
 
+  TRACE_EVENT_ASYNC_STEP_PAST1("identity",
+                               "GaiaWebAuthFlow",
+                               this,
+                               "OnAuthFlowFailure",
+                               "error",
+                               gaia_failure);
+
   delegate_->OnGaiaFlowFailure(
       gaia_failure,
       GoogleServiceAuthError(GoogleServiceAuthError::NONE),
@@ -102,6 +163,11 @@ void GaiaWebAuthFlow::OnAuthFlowFailure(WebAuthFlow::Failure failure) {
 }
 
 void GaiaWebAuthFlow::OnAuthFlowURLChange(const GURL& url) {
+  TRACE_EVENT_ASYNC_STEP_PAST0("identity",
+                               "GaiaWebAuthFlow",
+                               this,
+                               "OnAuthFlowURLChange");
+
   const char kOAuth2RedirectAccessTokenKey[] = "access_token";
   const char kOAuth2RedirectErrorKey[] = "error";
   const char kOAuth2ExpiresInKey[] = "expires_in";
@@ -118,14 +184,13 @@ void GaiaWebAuthFlow::OnAuthFlowURLChange(const GURL& url) {
 
     std::string fragment = url.GetContent().substr(
         redirect_path_prefix_.length(), std::string::npos);
-    std::vector<std::pair<std::string, std::string> > pairs;
+    base::StringPairs pairs;
     base::SplitStringIntoKeyValuePairs(fragment, '=', '&', &pairs);
     std::string access_token;
     std::string error;
     std::string expiration;
 
-    for (std::vector<std::pair<std::string, std::string> >::iterator
-             it = pairs.begin();
+    for (base::StringPairs::iterator it = pairs.begin();
          it != pairs.end();
          ++it) {
       if (it->first == kOAuth2RedirectAccessTokenKey)