Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / oauth2_login_verifier.cc
index 60c31ca..9976734 100644 (file)
@@ -14,6 +14,8 @@
 #include "chrome/browser/chromeos/net/network_portal_detector.h"
 #include "chrome/browser/signin/profile_oauth2_token_service.h"
 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
+#include "chrome/browser/signin/signin_manager.h"
+#include "chrome/browser/signin/signin_manager_factory.h"
 #include "chromeos/network/network_handler.h"
 #include "chromeos/network/network_state.h"
 #include "chromeos/network/network_state_handler.h"
@@ -28,9 +30,17 @@ namespace {
 
 // OAuth token request max retry count.
 const int kMaxRequestAttemptCount = 5;
+
 // OAuth token request retry delay in milliseconds.
 const int kRequestRestartDelay = 3000;
 
+// Post merge session verification delay.
+#ifndef NDEBUG
+const int kPostResoreVerificationDelay = 1000;
+#else
+const int kPostResoreVerificationDelay = 1000*60*3;
+#endif
+
 bool IsConnectionOrServiceError(const GoogleServiceAuthError& error) {
   return error.state() == GoogleServiceAuthError::CONNECTION_FAILED ||
          error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE ||
@@ -44,10 +54,13 @@ namespace chromeos {
 OAuth2LoginVerifier::OAuth2LoginVerifier(
     OAuth2LoginVerifier::Delegate* delegate,
     net::URLRequestContextGetter* system_request_context,
-    net::URLRequestContextGetter* user_request_context)
-    : delegate_(delegate),
+    net::URLRequestContextGetter* user_request_context,
+    const std::string& oauthlogin_access_token)
+    : OAuth2TokenService::Consumer("cros_login_verifier"),
+      delegate_(delegate),
       system_request_context_(system_request_context),
       user_request_context_(user_request_context),
+      access_token_(oauthlogin_access_token),
       retry_count_(0) {
   DCHECK(delegate);
 }
@@ -55,32 +68,36 @@ OAuth2LoginVerifier::OAuth2LoginVerifier(
 OAuth2LoginVerifier::~OAuth2LoginVerifier() {
 }
 
+void OAuth2LoginVerifier::VerifyUserCookies(Profile* profile) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+  if (DelayNetworkCall(base::Bind(&OAuth2LoginVerifier::VerifyUserCookies,
+                                  AsWeakPtr(),
+                                  profile))) {
+    return;
+  }
+
+  StartAuthCookiesVerification();
+}
+
 void OAuth2LoginVerifier::VerifyProfileTokens(Profile* profile) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
 
-  // Delay the verification if the network is not connected or on a captive
-  // portal.
-  const NetworkState* default_network =
-      NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
-  NetworkPortalDetector* detector = NetworkPortalDetector::Get();
-  if (!default_network ||
-      default_network->connection_state() == shill::kStatePortal ||
-      (detector && detector->GetCaptivePortalState(default_network).status !=
-           NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE)) {
-    // If network is offline, defer the token fetching until online.
-    VLOG(1) << "Network is offline.  Deferring OAuth2 access token fetch.";
-    BrowserThread::PostDelayedTask(
-        BrowserThread::UI,
-        FROM_HERE,
-        base::Bind(
-            &OAuth2LoginVerifier::VerifyProfileTokens, AsWeakPtr(), profile),
-        base::TimeDelta::FromMilliseconds(kRequestRestartDelay));
+  if (DelayNetworkCall(base::Bind(&OAuth2LoginVerifier::VerifyProfileTokens,
+                                  AsWeakPtr(),
+                                  profile))) {
     return;
   }
 
-  access_token_.clear();
   gaia_token_.clear();
-  StartFetchingOAuthLoginAccessToken(profile);
+  if (access_token_.empty()) {
+    // Fetch /OAuthLogin scoped access token.
+    StartFetchingOAuthLoginAccessToken(profile);
+  } else {
+    // If OAuthLogin-scoped access token already exists (if it's generated
+    // together with freshly minted refresh token), then fetch GAIA uber token.
+    StartOAuthLoginForUberToken();
+  }
 }
 
 void OAuth2LoginVerifier::StartFetchingOAuthLoginAccessToken(Profile* profile) {
@@ -88,8 +105,10 @@ void OAuth2LoginVerifier::StartFetchingOAuthLoginAccessToken(Profile* profile) {
   scopes.insert(GaiaUrls::GetInstance()->oauth1_login_scope());
   ProfileOAuth2TokenService* token_service =
       ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
+  SigninManagerBase* signin_manager =
+      SigninManagerFactory::GetForProfile(profile);
   login_token_request_ = token_service->StartRequestWithContext(
-      token_service->GetPrimaryAccountId(),
+      signin_manager->GetAuthenticatedAccountId(),
       system_request_context_.get(),
       scopes,
       this);
@@ -97,17 +116,17 @@ void OAuth2LoginVerifier::StartFetchingOAuthLoginAccessToken(Profile* profile) {
 
 void OAuth2LoginVerifier::StartOAuthLoginForUberToken() {
   // No service will fetch us uber auth token.
-  gaia_system_fetcher_.reset(
+  gaia_fetcher_.reset(
       new GaiaAuthFetcher(this,
                           std::string(GaiaConstants::kChromeOSSource),
-                          system_request_context_.get()));
-  gaia_system_fetcher_->StartTokenFetchForUberAuthExchange(access_token_);
+                          user_request_context_.get()));
+  gaia_fetcher_->StartTokenFetchForUberAuthExchange(access_token_);
 }
 
 
 void OAuth2LoginVerifier::OnUberAuthTokenSuccess(
     const std::string& uber_token) {
-  LOG(INFO) << "OAuthLogin(uber_token) successful!";
+  VLOG(1) << "OAuthLogin(uber_token) successful!";
   retry_count_ = 0;
   gaia_token_ = uber_token;
   StartMergeSession();
@@ -117,43 +136,14 @@ void OAuth2LoginVerifier::OnUberAuthTokenFailure(
     const GoogleServiceAuthError& error) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
   LOG(WARNING) << "OAuthLogin(uber_token) failed,"
-             << " error: " << error.state();
+               << " error: " << error.state();
   RetryOnError("OAuthLoginUberToken", error,
                base::Bind(&OAuth2LoginVerifier::StartOAuthLoginForUberToken,
                           AsWeakPtr()),
-               base::Bind(&Delegate::OnOAuthLoginFailure,
+               base::Bind(&Delegate::OnSessionMergeFailure,
                           base::Unretained(delegate_)));
 }
 
-void OAuth2LoginVerifier::StartOAuthLoginForGaiaCredentials() {
-  // No service will fetch us uber auth token.
-  gaia_system_fetcher_.reset(
-      new GaiaAuthFetcher(this,
-                          std::string(GaiaConstants::kChromeOSSource),
-                          system_request_context_.get()));
-  gaia_system_fetcher_->StartOAuthLogin(access_token_, EmptyString());
-}
-
-void OAuth2LoginVerifier::OnClientLoginSuccess(
-    const ClientLoginResult& gaia_credentials) {
-  LOG(INFO) << "OAuthLogin(SID+LSID) successful!";
-  retry_count_ = 0;
-  delegate_->OnOAuthLoginSuccess(gaia_credentials);
-}
-
-void OAuth2LoginVerifier::OnClientLoginFailure(
-    const GoogleServiceAuthError& error) {
-  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  LOG(WARNING) << "OAuthLogin(SID+LSID failed),"
-             << " error: " << error.state();
-  RetryOnError(
-      "OAuthLoginGaiaCred", error,
-      base::Bind(&OAuth2LoginVerifier::StartOAuthLoginForGaiaCredentials,
-                 AsWeakPtr()),
-      base::Bind(&Delegate::OnOAuthLoginFailure,
-                 base::Unretained(delegate_)));
-}
-
 void OAuth2LoginVerifier::StartMergeSession() {
   DCHECK(!gaia_token_.empty());
   gaia_fetcher_.reset(
@@ -165,16 +155,33 @@ void OAuth2LoginVerifier::StartMergeSession() {
 
 void OAuth2LoginVerifier::OnMergeSessionSuccess(const std::string& data) {
   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-  LOG(INFO) << "MergeSession successful.";
+  VLOG(1) << "MergeSession successful.";
   delegate_->OnSessionMergeSuccess();
-  // Get GAIA credentials needed to kick off TokenService and friends.
-  StartOAuthLoginForGaiaCredentials();
+  // Schedule post-merge verification to analyze how many LSID/SID overruns
+  // were created by the session restore.
+  SchedulePostMergeVerification();
+}
+
+void OAuth2LoginVerifier::SchedulePostMergeVerification() {
+  BrowserThread::PostDelayedTask(
+      BrowserThread::UI,
+      FROM_HERE,
+      base::Bind(
+          &OAuth2LoginVerifier::StartAuthCookiesVerification, AsWeakPtr()),
+      base::TimeDelta::FromMilliseconds(kPostResoreVerificationDelay));
+}
+
+void OAuth2LoginVerifier::StartAuthCookiesVerification() {
+  gaia_fetcher_.reset(
+      new GaiaAuthFetcher(this,
+                          std::string(GaiaConstants::kChromeOSSource),
+                          user_request_context_.get()));
+  gaia_fetcher_->StartListAccounts();
 }
 
 void OAuth2LoginVerifier::OnMergeSessionFailure(
     const GoogleServiceAuthError& error) {
-  LOG(WARNING) << "Failed MergeSession request,"
-             << " error: " << error.state();
+  LOG(WARNING) << "Failed MergeSession request," << " error: " << error.state();
   // If MergeSession from GAIA service token fails, retry the session restore
   // from OAuth2 refresh token. If that failed too, signal the delegate.
   RetryOnError(
@@ -193,7 +200,7 @@ void OAuth2LoginVerifier::OnGetTokenSuccess(
   DCHECK_EQ(login_token_request_.get(), request);
   login_token_request_.reset();
 
-  LOG(INFO) << "Got OAuth2 access token!";
+  VLOG(1) << "Got OAuth2 access token!";
   retry_count_ = 0;
   access_token_ = access_token;
   StartOAuthLoginForUberToken();
@@ -207,12 +214,33 @@ void OAuth2LoginVerifier::OnGetTokenFailure(
   login_token_request_.reset();
 
   LOG(WARNING) << "Failed to get OAuth2 access token, "
-             << " error: " << error.state();
+               << " error: " << error.state();
   UMA_HISTOGRAM_ENUMERATION(
       base::StringPrintf("OAuth2Login.%sFailure", "GetOAuth2AccessToken"),
       error.state(),
       GoogleServiceAuthError::NUM_STATES);
-  delegate_->OnOAuthLoginFailure(IsConnectionOrServiceError(error));
+  delegate_->OnSessionMergeFailure(IsConnectionOrServiceError(error));
+}
+
+void OAuth2LoginVerifier::OnListAccountsSuccess(
+    const std::string& data) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  VLOG(1) << "ListAccounts successful.";
+  delegate_->OnListAccountsSuccess(data);
+}
+
+void OAuth2LoginVerifier::OnListAccountsFailure(
+    const GoogleServiceAuthError& error) {
+  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+  LOG(WARNING) << "Failed to get list of session accounts, "
+               << " error: " << error.state();
+  RetryOnError(
+      "ListAccounts",
+      error,
+      base::Bind(&OAuth2LoginVerifier::StartAuthCookiesVerification,
+                 AsWeakPtr()),
+      base::Bind(&Delegate::OnListAccountsFailure,
+                 base::Unretained(delegate_)));
 }
 
 void OAuth2LoginVerifier::RetryOnError(const char* operation_id,
@@ -233,7 +261,7 @@ void OAuth2LoginVerifier::RetryOnError(const char* operation_id,
   }
 
   LOG(WARNING) << "Unrecoverable error or retry count max reached for "
-             << operation_id;
+               << operation_id;
   UMA_HISTOGRAM_ENUMERATION(
       base::StringPrintf("OAuth2Login.%sFailure", operation_id),
       error.state(),
@@ -242,4 +270,27 @@ void OAuth2LoginVerifier::RetryOnError(const char* operation_id,
   error_handler.Run(IsConnectionOrServiceError(error));
 }
 
+bool OAuth2LoginVerifier::DelayNetworkCall(const base::Closure& callback) {
+  // Delay the verification if the network is not connected or on a captive
+  // portal.
+  const NetworkState* default_network =
+      NetworkHandler::Get()->network_state_handler()->DefaultNetwork();
+  NetworkPortalDetector* detector = NetworkPortalDetector::Get();
+  if (!default_network ||
+      default_network->connection_state() == shill::kStatePortal ||
+      (detector && detector->GetCaptivePortalState(default_network).status !=
+           NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE)) {
+    // If network is offline, defer the token fetching until online.
+    LOG(WARNING) << "Network is offline. Deferring call.";
+    BrowserThread::PostDelayedTask(
+        BrowserThread::UI,
+        FROM_HERE,
+        callback,
+        base::TimeDelta::FromMilliseconds(kRequestRestartDelay));
+    return true;
+  }
+
+  return false;
+}
+
 }  // namespace chromeos