190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)// found in the LICENSE file. 490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h" 690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/trace_event.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string_split.h" 105e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h" 115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 135b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#include "chrome/browser/signin/chrome_signin_client_factory.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h" 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h" 17e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h" 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "google_apis/gaia/gaia_urls.h" 1990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "net/base/escape.h" 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)namespace extensions { 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)GaiaWebAuthFlow::GaiaWebAuthFlow(Delegate* delegate, 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) Profile* profile, 25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const ExtensionTokenKey* token_key, 26f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& oauth2_client_id, 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& locale) 28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : delegate_(delegate), 29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) profile_(profile), 30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) account_id_(token_key->account_id) { 315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_BEGIN2("identity", 325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "GaiaWebAuthFlow", 335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "extension_id", 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) token_key->extension_id, 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "account_id", 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) token_key->account_id); 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kOAuth2RedirectPathFormat[] = "/%s#"; 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kOAuth2AuthorizeFormat[] = 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) "?response_type=token&approval_prompt=force&authuser=0&" 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "client_id=%s&" 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "scope=%s&" 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "origin=chrome-extension://%s/&" 45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "redirect_uri=%s:/%s&" 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "hl=%s"; 475b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // Additional parameters to pass if device_id is enabled. 485b892326406927b709cdaf6c384d4ababf456332Ben Murdoch const char kOAuth2AuthorizeFormatDeviceIdAddendum[] = 495b892326406927b709cdaf6c384d4ababf456332Ben Murdoch "&device_id=%s&" 505b892326406927b709cdaf6c384d4ababf456332Ben Murdoch "device_type=chrome"; 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<std::string> scopes(token_key->scopes.begin(), 53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) token_key->scopes.end()); 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::vector<std::string> client_id_parts; 55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::SplitString(oauth2_client_id, '.', &client_id_parts); 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::reverse(client_id_parts.begin(), client_id_parts.end()); 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) redirect_scheme_ = JoinString(client_id_parts, '.'); 585b892326406927b709cdaf6c384d4ababf456332Ben Murdoch std::string signin_scoped_device_id; 595b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // profile_ can be nullptr in unittests. 605b892326406927b709cdaf6c384d4ababf456332Ben Murdoch SigninClient* signin_client = 615b892326406927b709cdaf6c384d4ababf456332Ben Murdoch profile_ ? ChromeSigninClientFactory::GetForProfile(profile_) : nullptr; 625b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (signin_client) 635b892326406927b709cdaf6c384d4ababf456332Ben Murdoch signin_scoped_device_id = signin_client->GetSigninScopedDeviceId(); 6490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) redirect_path_prefix_ = base::StringPrintf(kOAuth2RedirectPathFormat, 66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) token_key->extension_id.c_str()); 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 685b892326406927b709cdaf6c384d4ababf456332Ben Murdoch std::string oauth2_authorize_params = base::StringPrintf( 695b892326406927b709cdaf6c384d4ababf456332Ben Murdoch kOAuth2AuthorizeFormat, 705b892326406927b709cdaf6c384d4ababf456332Ben Murdoch oauth2_client_id.c_str(), 715b892326406927b709cdaf6c384d4ababf456332Ben Murdoch net::EscapeUrlEncodedData(JoinString(scopes, ' '), true).c_str(), 725b892326406927b709cdaf6c384d4ababf456332Ben Murdoch token_key->extension_id.c_str(), 735b892326406927b709cdaf6c384d4ababf456332Ben Murdoch redirect_scheme_.c_str(), 745b892326406927b709cdaf6c384d4ababf456332Ben Murdoch token_key->extension_id.c_str(), 755b892326406927b709cdaf6c384d4ababf456332Ben Murdoch locale.c_str()); 765b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (!signin_scoped_device_id.empty()) { 775b892326406927b709cdaf6c384d4ababf456332Ben Murdoch oauth2_authorize_params += base::StringPrintf( 785b892326406927b709cdaf6c384d4ababf456332Ben Murdoch kOAuth2AuthorizeFormatDeviceIdAddendum, 795b892326406927b709cdaf6c384d4ababf456332Ben Murdoch net::EscapeUrlEncodedData(signin_scoped_device_id, true).c_str()); 805b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 815b892326406927b709cdaf6c384d4ababf456332Ben Murdoch auth_url_ = GaiaUrls::GetInstance()->oauth2_auth_url().Resolve( 825b892326406927b709cdaf6c384d4ababf456332Ben Murdoch oauth2_authorize_params); 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)GaiaWebAuthFlow::~GaiaWebAuthFlow() { 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_END0("identity", "GaiaWebAuthFlow", this); 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (web_flow_) 8990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) web_flow_.release()->DetachDelegateAndDelete(); 9090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GaiaWebAuthFlow::Start() { 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProfileOAuth2TokenService* token_service = 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ubertoken_fetcher_.reset(new UbertokenFetcher(token_service, 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_->GetRequestContext())); 9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) ubertoken_fetcher_->StartFetchingToken(account_id_); 9990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GaiaWebAuthFlow::OnUbertokenSuccess(const std::string& token) { 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST0( 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "identity", "GaiaWebAuthFlow", this, "OnUbertokenSuccess"); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kMergeSessionQueryFormat[] = "?uberauth=%s&" 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "continue=%s&" 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) "source=appsv2"; 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 10990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string merge_query = base::StringPrintf( 11090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) kMergeSessionQueryFormat, 11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::EscapeUrlEncodedData(token, true).c_str(), 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) net::EscapeUrlEncodedData(auth_url_.spec(), true).c_str()); 113d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) GURL merge_url( 114d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) GaiaUrls::GetInstance()->merge_session_url().Resolve(merge_query)); 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) web_flow_ = CreateWebAuthFlow(merge_url); 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) web_flow_->Start(); 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GaiaWebAuthFlow::OnUbertokenFailure(const GoogleServiceAuthError& error) { 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST1("identity", 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "GaiaWebAuthFlow", 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "OnUbertokenSuccess", 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "error", 1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error.ToString()); 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DVLOG(1) << "OnUbertokenFailure: " << error.error_message(); 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnGaiaFlowFailure( 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GaiaWebAuthFlow::SERVICE_AUTH_ERROR, error, std::string()); 13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GaiaWebAuthFlow::OnAuthFlowFailure(WebAuthFlow::Failure failure) { 134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) GaiaWebAuthFlow::Failure gaia_failure; 135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) switch (failure) { 137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case WebAuthFlow::WINDOW_CLOSED: 138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gaia_failure = GaiaWebAuthFlow::WINDOW_CLOSED; 139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case WebAuthFlow::LOAD_FAILED: 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DVLOG(1) << "OnAuthFlowFailure LOAD_FAILED"; 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gaia_failure = GaiaWebAuthFlow::LOAD_FAILED; 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) default: 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NOTREACHED() << "Unexpected error from web auth flow: " << failure; 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gaia_failure = GaiaWebAuthFlow::LOAD_FAILED; 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST1("identity", 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "GaiaWebAuthFlow", 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "OnAuthFlowFailure", 1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "error", 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gaia_failure); 1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnGaiaFlowFailure( 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) gaia_failure, 15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GoogleServiceAuthError(GoogleServiceAuthError::NONE), 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string()); 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GaiaWebAuthFlow::OnAuthFlowURLChange(const GURL& url) { 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST0("identity", 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "GaiaWebAuthFlow", 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "OnAuthFlowURLChange"); 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kOAuth2RedirectAccessTokenKey[] = "access_token"; 17090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kOAuth2RedirectErrorKey[] = "error"; 17190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kOAuth2ExpiresInKey[] = "expires_in"; 17290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // The format of the target URL is: 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // reversed.oauth.client.id:/extensionid#access_token=TOKEN 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Because there is no double slash, everything after the scheme is 17790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // interpreted as a path, including the fragment. 17890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 17990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (url.scheme() == redirect_scheme_ && !url.has_host() && !url.has_port() && 1801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) StartsWithASCII(url.GetContent(), redirect_path_prefix_, true)) { 18190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) web_flow_.release()->DetachDelegateAndDelete(); 18290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) std::string fragment = url.GetContent().substr( 1841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) redirect_path_prefix_.length(), std::string::npos); 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::StringPairs pairs; 18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::SplitStringIntoKeyValuePairs(fragment, '=', '&', &pairs); 18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string access_token; 18890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string error; 18990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string expiration; 19090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (base::StringPairs::iterator it = pairs.begin(); 19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) it != pairs.end(); 19390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ++it) { 19490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (it->first == kOAuth2RedirectAccessTokenKey) 19590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) access_token = it->second; 19690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else if (it->first == kOAuth2RedirectErrorKey) 19790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = it->second; 19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else if (it->first == kOAuth2ExpiresInKey) 19990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) expiration = it->second; 20090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 20190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 20290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (access_token.empty() && error.empty()) { 20390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnGaiaFlowFailure( 20490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GaiaWebAuthFlow::INVALID_REDIRECT, 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GoogleServiceAuthError(GoogleServiceAuthError::NONE), 20690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string()); 20790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else if (!error.empty()) { 20890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnGaiaFlowFailure( 20990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GaiaWebAuthFlow::OAUTH_ERROR, 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GoogleServiceAuthError(GoogleServiceAuthError::NONE), 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error); 21290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } else { 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) delegate_->OnGaiaFlowCompleted(access_token, expiration); 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 21590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 21790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 21890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void GaiaWebAuthFlow::OnAuthFlowTitleChange(const std::string& title) { 21990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // On the final page the title will be "Loading <redirect-url>". 22090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Treat it as though we'd really been redirected to <redirect-url>. 22190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kRedirectPrefix[] = "Loading "; 22290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string prefix(kRedirectPrefix); 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 22490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (StartsWithASCII(title, prefix, true)) { 22590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GURL url(title.substr(prefix.length(), std::string::npos)); 22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (url.is_valid()) 22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) OnAuthFlowURLChange(url); 22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 22990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 23090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)scoped_ptr<WebAuthFlow> GaiaWebAuthFlow::CreateWebAuthFlow(GURL url) { 23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return scoped_ptr<WebAuthFlow>(new WebAuthFlow(this, 23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) profile_, 23490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) url, 235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) WebAuthFlow::INTERACTIVE)); 23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 238d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} // namespace extensions 239