identity_api.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_api.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <set> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <utility> 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/trace_event.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/lazy_instance.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/prefs/pref_service.h" 1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 165e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/stringprintf.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/app_mode/app_mode_utils.h" 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/browser_process.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h" 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/api/identity.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/identity/oauth2_manifest_handler.h" 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/common/pref_names.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "components/signin/core/browser/profile_oauth2_token_service.h" 31e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h" 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/signin/core/common/profile_management_switches.h" 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h" 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/extension_function_dispatcher.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/extension_l10n_util.h" 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/permissions/permission_set.h" 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/permissions/permissions_data.h" 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "google_apis/gaia/gaia_urls.h" 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_CHROMEOS) 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/chromeos/login/session/user_session_manager.h" 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" 476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h" 488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "google_apis/gaia/gaia_constants.h" 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace identity_constants { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidClientId[] = "Invalid OAuth2 Client ID."; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidScopes[] = "Invalid OAuth2 scopes."; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAuthFailure[] = "OAuth2 request failed: "; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNoGrant[] = "OAuth2 not granted or revoked."; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserRejected[] = "The user did not approve access."; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUserNotSignedIn[] = "The user is not signed in."; 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kInteractionRequired[] = "User interaction required."; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInvalidRedirect[] = "Did not redirect to the right URL."; 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const char kOffTheRecord[] = "Identity API is disabled in incognito windows."; 63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kPageLoadFailure[] = "Authorization page could not be loaded."; 64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst char kCanceled[] = "canceled"; 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kCachedIssueAdviceTTLSeconds = 1; 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace identity_constants 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)static const char kChromiumDomainRedirectUrlPattern[] = 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "https://%s.chromiumapp.org/"; 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)std::string GetPrimaryAccountId(content::BrowserContext* context) { 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SigninManagerBase* signin_manager = 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) SigninManagerFactory::GetForProfile(Profile::FromBrowserContext(context)); 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return signin_manager->GetAuthenticatedAccountId(); 785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace identity = api::identity; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIdentityTokenCacheValue::IdentityTokenCacheValue() 85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch : status_(CACHE_STATUS_NOTFOUND) {} 86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIdentityTokenCacheValue::IdentityTokenCacheValue( 88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const IssueAdviceInfo& issue_advice) 89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch : status_(CACHE_STATUS_ADVICE), issue_advice_(issue_advice) { 90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch expiration_time_ = 91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::Time::Now() + base::TimeDelta::FromSeconds( 92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch identity_constants::kCachedIssueAdviceTTLSeconds); 93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIdentityTokenCacheValue::IdentityTokenCacheValue(const std::string& token, 96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::TimeDelta time_to_live) 97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch : status_(CACHE_STATUS_TOKEN), token_(token) { 98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Remove 20 minutes from the ttl so cached tokens will have some time 99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // to live any time they are returned. 100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch time_to_live -= base::TimeDelta::FromMinutes(20); 101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::TimeDelta zero_delta; 103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (time_to_live < zero_delta) 104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch time_to_live = zero_delta; 105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch expiration_time_ = base::Time::Now() + time_to_live; 107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIdentityTokenCacheValue::~IdentityTokenCacheValue() {} 110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 111e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIdentityTokenCacheValue::CacheValueStatus IdentityTokenCacheValue::status() 112e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const { 113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (is_expired()) 114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND; 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch else 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return status_; 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 119e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst IssueAdviceInfo& IdentityTokenCacheValue::issue_advice() const { 120e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return issue_advice_; 121e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 122e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst std::string& IdentityTokenCacheValue::token() const { return token_; } 124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochbool IdentityTokenCacheValue::is_expired() const { 126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return status_ == CACHE_STATUS_NOTFOUND || 127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch expiration_time_ < base::Time::Now(); 128e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 129e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst base::Time& IdentityTokenCacheValue::expiration_time() const { 131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return expiration_time_; 132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIdentityAPI::IdentityAPI(content::BrowserContext* context) 135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch : browser_context_(context), 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch profile_identity_provider_( 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SigninManagerFactory::GetForProfile( 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Profile::FromBrowserContext(context)), 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ProfileOAuth2TokenServiceFactory::GetForProfile( 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Profile::FromBrowserContext(context)), 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch LoginUIServiceFactory::GetForProfile( 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Profile::FromBrowserContext(context))), 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch account_tracker_(&profile_identity_provider_, 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch g_browser_process->system_request_context()) { 145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch account_tracker_.AddObserver(this); 146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIdentityAPI::~IdentityAPI() {} 149e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 150e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochIdentityMintRequestQueue* IdentityAPI::mint_queue() { return &mint_queue_; } 151e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid IdentityAPI::SetCachedToken(const ExtensionTokenKey& key, 153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const IdentityTokenCacheValue& token_data) { 154e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CachedTokens::iterator it = token_cache_.find(key); 155e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (it != token_cache_.end() && it->second.status() <= token_data.status()) 156e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch token_cache_.erase(it); 157e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 158e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch token_cache_.insert(std::make_pair(key, token_data)); 159e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 160e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 161e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid IdentityAPI::EraseCachedToken(const std::string& extension_id, 162e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const std::string& token) { 163e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CachedTokens::iterator it; 164e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch for (it = token_cache_.begin(); it != token_cache_.end(); ++it) { 165e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (it->first.extension_id == extension_id && 166e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch it->second.status() == IdentityTokenCacheValue::CACHE_STATUS_TOKEN && 167e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch it->second.token() == token) { 168e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch token_cache_.erase(it); 169e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch break; 170e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 171e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 172e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 173e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 174e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid IdentityAPI::EraseAllCachedTokens() { token_cache_.clear(); } 175e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 176e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst IdentityTokenCacheValue& IdentityAPI::GetCachedToken( 177e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const ExtensionTokenKey& key) { 178e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return token_cache_[key]; 179e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 180e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 181e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochconst IdentityAPI::CachedTokens& IdentityAPI::GetAllCachedTokens() { 182e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return token_cache_; 183e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 184e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)std::vector<std::string> IdentityAPI::GetAccounts() const { 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string primary_account_id = GetPrimaryAccountId(browser_context_); 187116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::vector<gaia::AccountIds> ids = account_tracker_.GetAccounts(); 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> gaia_ids; 189cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 190cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (switches::IsExtensionsMultiAccount()) { 191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch for (std::vector<gaia::AccountIds>::const_iterator it = ids.begin(); 192cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != ids.end(); 193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 194cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gaia_ids.push_back(it->gaia); 195cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 196cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (ids.size() >= 1) { 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) gaia_ids.push_back(ids[0].gaia); 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return gaia_ids; 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::string IdentityAPI::FindAccountKeyByGaiaId(const std::string& gaia_id) { 204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return account_tracker_.FindAccountIdsByGaiaId(gaia_id).account_key; 205e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 206e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 207e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid IdentityAPI::Shutdown() { 208e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch FOR_EACH_OBSERVER(ShutdownObserver, shutdown_observer_list_, OnShutdown()); 209e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch account_tracker_.RemoveObserver(this); 210e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch account_tracker_.Shutdown(); 211e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 212e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 213e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochstatic base::LazyInstance<BrowserContextKeyedAPIFactory<IdentityAPI> > 214e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch g_factory = LAZY_INSTANCE_INITIALIZER; 215e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 216e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch// static 217e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochBrowserContextKeyedAPIFactory<IdentityAPI>* IdentityAPI::GetFactoryInstance() { 218e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return g_factory.Pointer(); 219e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 220e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid IdentityAPI::OnAccountAdded(const gaia::AccountIds& ids) { 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 223e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid IdentityAPI::OnAccountRemoved(const gaia::AccountIds& ids) { 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 226e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid IdentityAPI::OnAccountSignInChanged(const gaia::AccountIds& ids, 228e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool is_signed_in) { 229e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch api::identity::AccountInfo account_info; 230e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch account_info.id = ids.gaia; 231e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 232e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch scoped_ptr<base::ListValue> args = 233e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch api::identity::OnSignInChanged::Create(account_info, is_signed_in); 234e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch scoped_ptr<Event> event(new Event(api::identity::OnSignInChanged::kEventName, 235e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch args.Pass(), 236e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch browser_context_)); 237e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch EventRouter::Get(browser_context_)->BroadcastEvent(event.Pass()); 239e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 240e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 241e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid IdentityAPI::AddShutdownObserver(ShutdownObserver* observer) { 242e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shutdown_observer_list_.AddObserver(observer); 243e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 244e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 245e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid IdentityAPI::RemoveShutdownObserver(ShutdownObserver* observer) { 246e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch shutdown_observer_list_.RemoveObserver(observer); 247e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 248e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 249116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid IdentityAPI::SetAccountStateForTest(gaia::AccountIds ids, 250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool is_signed_in) { 251cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) account_tracker_.SetAccountStateForTest(ids, is_signed_in); 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 253cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 254e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochtemplate <> 255e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid BrowserContextKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies() { 256e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); 257e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); 258e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 259e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 260cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IdentityGetAccountsFunction::IdentityGetAccountsFunction() { 261cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 262cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)IdentityGetAccountsFunction::~IdentityGetAccountsFunction() { 264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 265cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 266cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)ExtensionFunction::ResponseAction IdentityGetAccountsFunction::Run() { 267cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (GetProfile()->IsOffTheRecord()) { 268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return RespondNow(Error(identity_constants::kOffTheRecord)); 269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 270cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 271cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> gaia_ids = 272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IdentityAPI::GetFactoryInstance()->Get(GetProfile())->GetAccounts(); 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(gaia_ids.size() < 2 || switches::IsExtensionsMultiAccount()); 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::ListValue* infos = new base::ListValue(); 276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (std::vector<std::string>::const_iterator it = gaia_ids.begin(); 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != gaia_ids.end(); 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) api::identity::AccountInfo account_info; 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) account_info.id = *it; 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) infos->Append(account_info.ToValue().release()); 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return RespondNow(OneArgument(infos)); 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityGetAuthTokenFunction::IdentityGetAuthTokenFunction() 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : OAuth2TokenService::Consumer("extensions_identity_api"), 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) should_prompt_for_scopes_(false), 2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) should_prompt_for_signin_(false) { 2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)IdentityGetAuthTokenFunction::~IdentityGetAuthTokenFunction() { 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_END0("identity", "IdentityGetAuthTokenFunction", this); 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool IdentityGetAuthTokenFunction::RunAsync() { 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci TRACE_EVENT_ASYNC_BEGIN1("identity", 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "IdentityGetAuthTokenFunction", 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this, 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "extension", 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci extension()->id()); 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (GetProfile()->IsOffTheRecord()) { 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kOffTheRecord; 307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<identity::GetAuthToken::Params> params( 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) identity::GetAuthToken::Params::Create(*args_)); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool interactive = params->details.get() && 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params->details->interactive.get() && 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *params->details->interactive; 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_scopes_ = interactive; 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_signin_ = interactive; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension()); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check that the necessary information is present in the manifest. 323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch oauth2_client_id_ = GetOAuth2ClientId(); 324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (oauth2_client_id_.empty()) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = identity_constants::kInvalidClientId; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) std::set<std::string> scopes(oauth2_info.scopes.begin(), 330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) oauth2_info.scopes.end()); 33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string account_key = GetPrimaryAccountId(GetProfile()); 33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (params->details.get()) { 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (params->details->account.get()) { 336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::string detail_key = 337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) extensions::IdentityAPI::GetFactoryInstance() 338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ->Get(GetProfile()) 339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ->FindAccountKeyByGaiaId(params->details->account->id); 340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (detail_key != account_key) { 342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (detail_key.empty() || !switches::IsExtensionsMultiAccount()) { 343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // TODO(courage): should this be a different error? 344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error_ = identity_constants::kUserNotSignedIn; 345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 346f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 347f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 348f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) account_key = detail_key; 34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 350f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (params->details->scopes.get()) { 353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scopes = std::set<std::string>(params->details->scopes->begin(), 354f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) params->details->scopes->end()); 35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 358f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (scopes.size() == 0) { 359f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) error_ = identity_constants::kInvalidScopes; 360f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return false; 361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) token_key_.reset( 3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new ExtensionTokenKey(extension()->id(), account_key, scopes)); 365a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 366e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // From here on out, results must be returned asynchronously. 367e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch StartAsyncRun(); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_CHROMEOS) 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) policy::BrowserPolicyConnectorChromeOS* connector = 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_browser_process->platform_part()->browser_policy_connector_chromeos(); 3726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (user_manager::UserManager::Get()->IsLoggedInAsKioskApp() && 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) connector->IsEnterpriseManaged()) { 374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE); 375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!HasLoginToken()) { 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_prompt_for_signin_) { 381e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CompleteFunctionWithError(identity_constants::kUserNotSignedIn); 382e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return true; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Display a login prompt. 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartSigninFlow(); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 393e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid IdentityGetAuthTokenFunction::StartAsyncRun() { 394e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Balanced in CompleteAsyncRun 395e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch AddRef(); 396e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch extensions::IdentityAPI::GetFactoryInstance() 397e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ->Get(GetProfile()) 398e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ->AddShutdownObserver(this); 399e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 400e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 401e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid IdentityGetAuthTokenFunction::CompleteAsyncRun(bool success) { 402e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch extensions::IdentityAPI::GetFactoryInstance() 403e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ->Get(GetProfile()) 404e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ->RemoveShutdownObserver(this); 405e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 406e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch SendResponse(success); 407e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Release(); // Balanced in StartAsyncRun 408e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 409e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteFunctionWithResult( 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& access_token) { 412e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetResult(new base::StringValue(access_token)); 414e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CompleteAsyncRun(true); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteFunctionWithError( 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& error) { 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST1("identity", 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "CompleteFunctionWithError", 4235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "error", 4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error); 425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = error; 426e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CompleteAsyncRun(false); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartSigninFlow() { 430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // All cached tokens are invalid because the user is not signed in. 431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityAPI* id_api = 432a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::IdentityAPI::GetFactoryInstance()->Get(GetProfile()); 433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) id_api->EraseAllCachedTokens(); 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Display a login prompt. If the subsequent mint fails, don't display the 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // login prompt again. 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_signin_ = false; 437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ShowLoginPopup(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartMintTokenFlow( 441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue::MintType type) { 442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mint_token_flow_type_ = type; 443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Flows are serialized to prevent excessive traffic to GAIA, and 445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // to consolidate UI pop-ups. 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityAPI* id_api = 447a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::IdentityAPI::GetFactoryInstance()->Get(GetProfile()); 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!should_prompt_for_scopes_) { 450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Caller requested no interaction. 451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE) { 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // GAIA told us to do a consent UI. 454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithError(identity_constants::kNoGrant); 455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!id_api->mint_queue()->empty( 458a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE, *token_key_)) { 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Another call is going through a consent UI. 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithError(identity_constants::kNoGrant); 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 464a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) id_api->mint_queue()->RequestStart(type, *token_key_, this); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::CompleteMintTokenFlow() { 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue::MintType type = mint_token_flow_type_; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extensions::IdentityAPI::GetFactoryInstance() 471a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ->Get(GetProfile()) 4721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ->mint_queue() 473a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ->RequestComplete(type, *token_key_, this); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartMintToken( 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue::MintType type) { 4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST1("identity", 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "StartMintToken", 4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "type", 4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) type); 4845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension()); 486a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IdentityAPI* id_api = IdentityAPI::GetFactoryInstance()->Get(GetProfile()); 487a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) IdentityTokenCacheValue cache_entry = id_api->GetCachedToken(*token_key_); 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityTokenCacheValue::CacheValueStatus cache_status = 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache_entry.status(); 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (type == IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE) { 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (cache_status) { 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case IdentityTokenCacheValue::CACHE_STATUS_NOTFOUND: 494868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(OS_CHROMEOS) 495868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Always force minting token for ChromeOS kiosk app. 4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (user_manager::UserManager::Get()->IsLoggedInAsKioskApp()) { 4978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE; 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) policy::BrowserPolicyConnectorChromeOS* connector = 4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_browser_process->platform_part() 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ->browser_policy_connector_chromeos(); 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (connector->IsEnterpriseManaged()) { 5028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartDeviceLoginAccessTokenRequest(); 503eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 5047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch StartLoginAccessTokenRequest(); 505eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 506868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 507868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 508868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (oauth2_info.auto_approve) 5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // oauth2_info.auto_approve is protected by a whitelist in 5127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // _manifest_features.json hence only selected extensions take 5137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // advantage of forcefully minting the token. 5147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_FORCE; 5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) else 5167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch gaia_mint_token_mode_ = OAuth2MintTokenFlow::MODE_MINT_TOKEN_NO_FORCE; 5177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch StartLoginAccessTokenRequest(); 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case IdentityTokenCacheValue::CACHE_STATUS_TOKEN: 521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithResult(cache_entry.token()); 523c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 525c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case IdentityTokenCacheValue::CACHE_STATUS_ADVICE: 526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_signin_ = false; 528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) issue_advice_ = cache_entry.issue_advice(); 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(type == IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); 534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (cache_status == IdentityTokenCacheValue::CACHE_STATUS_TOKEN) { 536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithResult(cache_entry.token()); 538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ShowOAuthApprovalDialog(issue_advice_); 540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnMintTokenSuccess( 545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& access_token, int time_to_live) { 5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST0("identity", 5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "OnMintTokenSuccess"); 5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityTokenCacheValue token(access_token, 552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta::FromSeconds(time_to_live)); 553a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IdentityAPI::GetFactoryInstance()->Get(GetProfile())->SetCachedToken( 554a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *token_key_, token); 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithResult(access_token); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnMintTokenFailure( 561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GoogleServiceAuthError& error) { 5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST1("identity", 5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "OnMintTokenFailure", 5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "error", 5675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error.ToString()); 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (error.state()) { 571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS: 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case GoogleServiceAuthError::ACCOUNT_DELETED: 573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case GoogleServiceAuthError::ACCOUNT_DISABLED: 574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // TODO(courage): flush ticket and retry once 575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (should_prompt_for_signin_) { 576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Display a login prompt and try again (once). 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartSigninFlow(); 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Return error to caller. 583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithError( 587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(identity_constants::kAuthFailure) + error.ToString()); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnIssueAdviceSuccess( 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IssueAdviceInfo& issue_advice) { 5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST0("identity", 5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "OnIssueAdviceSuccess"); 5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 597a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IdentityAPI::GetFactoryInstance()->Get(GetProfile())->SetCachedToken( 598a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *token_key_, IdentityTokenCacheValue(issue_advice)); 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) should_prompt_for_signin_ = false; 602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Existing grant was revoked and we used NO_FORCE, so we got info back 603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // instead. Start a consent UI if we can. 604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) issue_advice_ = issue_advice; 605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_INTERACTIVE); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid IdentityGetAuthTokenFunction::SigninSuccess() { 6095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST0("identity", 6105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 6125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "SigninSuccess"); 6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // If there was no account associated this profile before the 6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // sign-in, we may not have an account_id in the token_key yet. 6165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (token_key_->account_id.empty()) { 6175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) token_key_->account_id = GetPrimaryAccountId(GetProfile()); 6185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartMintTokenFlow(IdentityMintRequestQueue::MINT_TYPE_NONINTERACTIVE); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::SigninFailed() { 6245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST0("identity", 6255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 6265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 6275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "SigninFailed"); 628c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteFunctionWithError(identity_constants::kUserNotSignedIn); 629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 63190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnGaiaFlowFailure( 63290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GaiaWebAuthFlow::Failure failure, 63390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GoogleServiceAuthError service_error, 63490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& oauth_error) { 63590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CompleteMintTokenFlow(); 63690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string error; 63790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 63890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) switch (failure) { 63990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case GaiaWebAuthFlow::WINDOW_CLOSED: 64090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = identity_constants::kUserRejected; 64190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 64290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 64390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case GaiaWebAuthFlow::INVALID_REDIRECT: 64490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = identity_constants::kInvalidRedirect; 64590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 64690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 64790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case GaiaWebAuthFlow::SERVICE_AUTH_ERROR: 64890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = std::string(identity_constants::kAuthFailure) + 64990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) service_error.ToString(); 65090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 65190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 65290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) case GaiaWebAuthFlow::OAUTH_ERROR: 65390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = MapOAuth2ErrorToDescription(oauth_error); 65490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 65590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 656868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case GaiaWebAuthFlow::LOAD_FAILED: 657868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error = identity_constants::kPageLoadFailure; 658868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 659868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 66090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) default: 66190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) NOTREACHED() << "Unexpected error from gaia web auth flow: " << failure; 66290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) error = identity_constants::kInvalidRedirect; 66390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) break; 66490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 66590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 66690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CompleteFunctionWithError(error); 667c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 668c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 66990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void IdentityGetAuthTokenFunction::OnGaiaFlowCompleted( 67090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& access_token, 67190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& expiration) { 6725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST0("identity", 6735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 6745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 6755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "OnGaiaFlowCompleted"); 67690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int time_to_live; 67790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!expiration.empty() && base::StringToInt(expiration, &time_to_live)) { 67890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) IdentityTokenCacheValue token_value( 67990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) access_token, base::TimeDelta::FromSeconds(time_to_live)); 680a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IdentityAPI::GetFactoryInstance()->Get(GetProfile())->SetCachedToken( 681a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *token_key_, token_value); 68290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 68390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 684c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CompleteMintTokenFlow(); 68590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CompleteFunctionWithResult(access_token); 686c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IdentityGetAuthTokenFunction::OnGetTokenSuccess( 689eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const OAuth2TokenService::Request* request, 690eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& access_token, 691eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::Time& expiration_time) { 6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST1("identity", 6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 6945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 6955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "OnGetTokenSuccess", 6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "account", 6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) request->GetAccountId()); 6988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) login_token_request_.reset(); 6998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) StartGaiaRequest(access_token); 700eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 701eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 702eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid IdentityGetAuthTokenFunction::OnGetTokenFailure( 703eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const OAuth2TokenService::Request* request, 704eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const GoogleServiceAuthError& error) { 7055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TRACE_EVENT_ASYNC_STEP_PAST1("identity", 7065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "IdentityGetAuthTokenFunction", 7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) this, 7085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "OnGetTokenFailure", 7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "error", 7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error.ToString()); 7118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) login_token_request_.reset(); 712eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch OnGaiaFlowFailure(GaiaWebAuthFlow::SERVICE_AUTH_ERROR, error, std::string()); 713eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 714eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 715e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid IdentityGetAuthTokenFunction::OnShutdown() { 716e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch gaia_web_auth_flow_.reset(); 717e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch signin_flow_.reset(); 718e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch login_token_request_.reset(); 719e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch extensions::IdentityAPI::GetFactoryInstance() 720e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ->Get(GetProfile()) 721e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ->mint_queue() 722e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ->RequestCancel(*token_key_, this); 723e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CompleteFunctionWithError(identity_constants::kCanceled); 724e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 725e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 7268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_CHROMEOS) 7278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartDeviceLoginAccessTokenRequest() { 728a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chromeos::DeviceOAuth2TokenService* service = 729a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) chromeos::DeviceOAuth2TokenServiceFactory::Get(); 7308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Since robot account refresh tokens are scoped down to [any-api] only, 7318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // request access token for [any-api] instead of login. 7328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OAuth2TokenService::ScopeSet scopes; 7338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scopes.insert(GaiaConstants::kAnyApiOAuth2Scope); 7348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) login_token_request_ = 7358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) service->StartRequest(service->GetRobotAccountId(), 7368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) scopes, 7378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) this); 7388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 7398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 7408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 7417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid IdentityGetAuthTokenFunction::StartLoginAccessTokenRequest() { 742a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ProfileOAuth2TokenService* service = 7431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile()); 744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#if defined(OS_CHROMEOS) 745a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (chrome::IsRunningInForcedAppMode()) { 746a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string app_client_id; 747a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string app_client_secret; 748116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (chromeos::UserSessionManager::GetInstance()-> 749116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetAppModeChromeClientOAuthInfo(&app_client_id, 750116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch &app_client_secret)) { 751a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) login_token_request_ = 75246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) service->StartRequestForClient(token_key_->account_id, 75368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) app_client_id, 754a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) app_client_secret, 755a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) OAuth2TokenService::ScopeSet(), 756a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) this); 757a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return; 758a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 759a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 760a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#endif 76168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) login_token_request_ = service->StartRequest( 76246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) token_key_->account_id, OAuth2TokenService::ScopeSet(), this); 7637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::StartGaiaRequest( 7667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& login_access_token) { 7677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!login_access_token.empty()); 7687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch mint_token_flow_.reset(CreateMintTokenFlow(login_access_token)); 769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mint_token_flow_->Start(); 770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityGetAuthTokenFunction::ShowLoginPopup() { 7731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) signin_flow_.reset(new IdentitySigninFlow(this, GetProfile())); 774c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) signin_flow_->Start(); 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IdentityGetAuthTokenFunction::ShowOAuthApprovalDialog( 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IssueAdviceInfo& issue_advice) { 7791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string locale = extension_l10n_util::CurrentLocaleOrDefault(); 78090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 781f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gaia_web_auth_flow_.reset(new GaiaWebAuthFlow( 782f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) this, GetProfile(), token_key_.get(), oauth2_client_id_, locale)); 78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) gaia_web_auth_flow_->Start(); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OAuth2MintTokenFlow* IdentityGetAuthTokenFunction::CreateMintTokenFlow( 7877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& login_access_token) { 7881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) OAuth2MintTokenFlow* mint_token_flow = new OAuth2MintTokenFlow( 7891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) GetProfile()->GetRequestContext(), 7901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) this, 791f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) OAuth2MintTokenFlow::Parameters( 792f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) login_access_token, 7935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension()->id(), 794f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) oauth2_client_id_, 795f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<std::string>(token_key_->scopes.begin(), 796f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) token_key_->scopes.end()), 797f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) gaia_mint_token_mode_)); 798c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return mint_token_flow; 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IdentityGetAuthTokenFunction::HasLoginToken() const { 80268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ProfileOAuth2TokenService* token_service = 8031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) ProfileOAuth2TokenServiceFactory::GetForProfile(GetProfile()); 80446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return token_service->RefreshTokenIsAvailable(token_key_->account_id); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)std::string IdentityGetAuthTokenFunction::MapOAuth2ErrorToDescription( 80890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& error) { 80990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kOAuth2ErrorAccessDenied[] = "access_denied"; 81090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char kOAuth2ErrorInvalidScope[] = "invalid_scope"; 81190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 81290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (error == kOAuth2ErrorAccessDenied) 81390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return std::string(identity_constants::kUserRejected); 81490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else if (error == kOAuth2ErrorInvalidScope) 81590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return std::string(identity_constants::kInvalidScopes); 81690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) else 81790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return std::string(identity_constants::kAuthFailure) + error; 81890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 81990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 820eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string IdentityGetAuthTokenFunction::GetOAuth2ClientId() const { 8215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const OAuth2Info& oauth2_info = OAuth2Info::GetOAuth2Info(extension()); 822eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string client_id = oauth2_info.client_id; 823eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 824eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Component apps using auto_approve may use Chrome's client ID by 825eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // omitting the field. 8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (client_id.empty() && extension()->location() == Manifest::COMPONENT && 827eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch oauth2_info.auto_approve) { 828eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch client_id = GaiaUrls::GetInstance()->oauth2_chrome_client_id(); 829eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 830eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return client_id; 831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 833f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IdentityGetProfileUserInfoFunction::IdentityGetProfileUserInfoFunction() { 834f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 835f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 836f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)IdentityGetProfileUserInfoFunction::~IdentityGetProfileUserInfoFunction() { 837f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 838f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 839f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)ExtensionFunction::ResponseAction IdentityGetProfileUserInfoFunction::Run() { 840f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (GetProfile()->IsOffTheRecord()) { 841f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return RespondNow(Error(identity_constants::kOffTheRecord)); 842f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 843f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 844f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) api::identity::ProfileUserInfo profile_user_info; 8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extension()->permissions_data()->HasAPIPermission( 846116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch APIPermission::kIdentityEmail)) { 847116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch profile_user_info.email = 848116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch GetProfile()->GetPrefs()->GetString(prefs::kGoogleServicesUsername); 849116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 850f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) profile_user_info.id = 851f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GetProfile()->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId); 852f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 853f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return RespondNow(OneArgument(profile_user_info.ToValue().release())); 854f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 855f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityRemoveCachedAuthTokenFunction::IdentityRemoveCachedAuthTokenFunction() { 857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IdentityRemoveCachedAuthTokenFunction:: 860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~IdentityRemoveCachedAuthTokenFunction() { 861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool IdentityRemoveCachedAuthTokenFunction::RunSync() { 8641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (GetProfile()->IsOffTheRecord()) { 865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kOffTheRecord; 866c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 867c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<identity::RemoveCachedAuthToken::Params> params( 870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) identity::RemoveCachedAuthToken::Params::Create(*args_)); 871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 872a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) IdentityAPI::GetFactoryInstance()->Get(GetProfile())->EraseCachedToken( 8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extension()->id(), params->details.token); 874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IdentityLaunchWebAuthFlowFunction::IdentityLaunchWebAuthFlowFunction() {} 87890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 87990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)IdentityLaunchWebAuthFlowFunction::~IdentityLaunchWebAuthFlowFunction() { 88090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (auth_flow_) 88190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) auth_flow_.release()->DetachDelegateAndDelete(); 88290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 884010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool IdentityLaunchWebAuthFlowFunction::RunAsync() { 8851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (GetProfile()->IsOffTheRecord()) { 886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kOffTheRecord; 887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<identity::LaunchWebAuthFlow::Params> params( 891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) identity::LaunchWebAuthFlow::Params::Create(*args_)); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXTENSION_FUNCTION_VALIDATE(params.get()); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL auth_url(params->details.url); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebAuthFlow::Mode mode = 896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) params->details.interactive && *params->details.interactive ? 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebAuthFlow::INTERACTIVE : WebAuthFlow::SILENT; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Set up acceptable target URLs. (Does not include chrome-extension 900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // scheme for this version of the API.) 9015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) InitFinalRedirectURLPrefix(extension()->id()); 902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); // Balanced in OnAuthFlowSuccess/Failure. 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) auth_flow_.reset(new WebAuthFlow(this, GetProfile(), auth_url, mode)); 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auth_flow_->Start(); 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 910b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefixForTest( 911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& extension_id) { 912b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) InitFinalRedirectURLPrefix(extension_id); 913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 915b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::InitFinalRedirectURLPrefix( 916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& extension_id) { 917b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (final_url_prefix_.is_empty()) { 918b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) final_url_prefix_ = GURL(base::StringPrintf( 919b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) kChromiumDomainRedirectUrlPattern, extension_id.c_str())); 920b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::OnAuthFlowFailure( 924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebAuthFlow::Failure failure) { 925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (failure) { 926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case WebAuthFlow::WINDOW_CLOSED: 927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kUserRejected; 928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case WebAuthFlow::INTERACTION_REQUIRED: 930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kInteractionRequired; 931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case WebAuthFlow::LOAD_FAILED: 933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) error_ = identity_constants::kPageLoadFailure; 934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; 935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) default: 936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED() << "Unexpected error from web auth flow: " << failure; 937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = identity_constants::kInvalidRedirect; 938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendResponse(false); 941010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Release(); // Balanced in RunAsync. 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void IdentityLaunchWebAuthFlowFunction::OnAuthFlowURLChange( 945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL& redirect_url) { 946b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (redirect_url.GetWithEmptyPath() == final_url_prefix_) { 9473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetResult(new base::StringValue(redirect_url.spec())); 948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendResponse(true); 949010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) Release(); // Balanced in RunAsync. 950c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 951c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 952c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 954