identity_api.h revision 116680a4aac90f2aa7413d9095a592090648e557
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)#ifndef CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_API_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_API_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <map> 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <set> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 1190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <utility> 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "base/observer_list.h" 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/extension_token_key.h" 1890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_mint_queue.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_signin_flow.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/web_auth_flow.h" 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_function.h" 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/signin/profile_identity_provider.h" 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/browser_context_keyed_api_factory.h" 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "google_apis/gaia/account_tracker.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/oauth2_mint_token_flow.h" 27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "google_apis/gaia/oauth2_token_service.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GoogleServiceAuthError; 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass MockGetAuthTokenFunction; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace content { 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class BrowserContext; 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class GetAuthTokenFunctionTest; 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class MockGetAuthTokenFunction; 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace identity_constants { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kInvalidClientId[]; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kInvalidScopes[]; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kAuthFailure[]; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kNoGrant[]; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kUserRejected[]; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kUserNotSignedIn[]; 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)extern const char kInteractionRequired[]; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kInvalidRedirect[]; 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)extern const char kOffTheRecord[]; 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)extern const char kPageLoadFailure[]; 52e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochextern const char kCanceled[]; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace identity_constants 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass IdentityTokenCacheValue { 56e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public: 57e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IdentityTokenCacheValue(); 58e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch explicit IdentityTokenCacheValue(const IssueAdviceInfo& issue_advice); 59e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IdentityTokenCacheValue(const std::string& token, 60e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::TimeDelta time_to_live); 61e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ~IdentityTokenCacheValue(); 62e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 63e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Order of these entries is used to determine whether or not new 64e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // entries supercede older ones in SetCachedToken. 65e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch enum CacheValueStatus { 66e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CACHE_STATUS_NOTFOUND, 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CACHE_STATUS_ADVICE, 68e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CACHE_STATUS_TOKEN 69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch }; 70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CacheValueStatus status() const; 72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const IssueAdviceInfo& issue_advice() const; 73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const std::string& token() const; 74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const base::Time& expiration_time() const; 75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch private: 77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool is_expired() const; 78e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CacheValueStatus status_; 80e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IssueAdviceInfo issue_advice_; 81e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch std::string token_; 82e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch base::Time expiration_time_; 83e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}; 84e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 85e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochclass IdentityAPI : public BrowserContextKeyedAPI, 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public gaia::AccountTracker::Observer { 87e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public: 88e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch typedef std::map<ExtensionTokenKey, IdentityTokenCacheValue> CachedTokens; 89e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch class ShutdownObserver { 91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public: 92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual void OnShutdown() = 0; 93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch }; 94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch explicit IdentityAPI(content::BrowserContext* context); 96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual ~IdentityAPI(); 97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 98e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Request serialization queue for getAuthToken. 99e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IdentityMintRequestQueue* mint_queue(); 100e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 101e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Token cache 102e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void SetCachedToken(const ExtensionTokenKey& key, 103e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const IdentityTokenCacheValue& token_data); 104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void EraseCachedToken(const std::string& extension_id, 105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const std::string& token); 106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void EraseAllCachedTokens(); 107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const IdentityTokenCacheValue& GetCachedToken(const ExtensionTokenKey& key); 108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const CachedTokens& GetAllCachedTokens(); 110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Account queries. 112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> GetAccounts() const; 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string FindAccountKeyByGaiaId(const std::string& gaia_id); 114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // BrowserContextKeyedAPI implementation. 116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual void Shutdown() OVERRIDE; 117e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static BrowserContextKeyedAPIFactory<IdentityAPI>* GetFactoryInstance(); 118e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // gaia::AccountTracker::Observer implementation: 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnAccountAdded(const gaia::AccountIds& ids) OVERRIDE; 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnAccountRemoved(const gaia::AccountIds& ids) OVERRIDE; 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch virtual void OnAccountSignInChanged(const gaia::AccountIds& ids, 123e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch bool is_signed_in) OVERRIDE; 124e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 125e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void AddShutdownObserver(ShutdownObserver* observer); 126e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void RemoveShutdownObserver(ShutdownObserver* observer); 127e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch void SetAccountStateForTest(gaia::AccountIds ids, bool is_signed_in); 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 130e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch private: 131e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch friend class BrowserContextKeyedAPIFactory<IdentityAPI>; 132e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 133e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // BrowserContextKeyedAPI implementation. 134e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static const char* service_name() { return "IdentityAPI"; } 135e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static const bool kServiceIsNULLWhileTesting = true; 136e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 137e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch content::BrowserContext* browser_context_; 138e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch IdentityMintRequestQueue mint_queue_; 139e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch CachedTokens token_cache_; 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ProfileIdentityProvider profile_identity_provider_; 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch gaia::AccountTracker account_tracker_; 142e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ObserverList<ShutdownObserver> shutdown_observer_list_; 143e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}; 144e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 145e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochtemplate <> 146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid BrowserContextKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies(); 147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class IdentityGetAccountsFunction : public ChromeUIThreadExtensionFunction { 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) public: 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DECLARE_EXTENSION_FUNCTION("identity.getAccounts", 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IDENTITY_GETACCOUNTS); 152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 153cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) IdentityGetAccountsFunction(); 154cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 155cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) private: 156cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ~IdentityGetAccountsFunction(); 157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // UIThreadExtensionFunction implementation. 159cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) virtual ExtensionFunction::ResponseAction Run() OVERRIDE; 160cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}; 161cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// identity.getAuthToken fetches an OAuth 2 function for the 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// caller. The request has three sub-flows: non-interactive, 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// interactive, and sign-in. 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// In the non-interactive flow, getAuthToken requests a token from 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// GAIA. GAIA may respond with a token, an error, or "consent 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// required". In the consent required cases, getAuthToken proceeds to 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the second, interactive phase. 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The interactive flow presents a scope approval dialog to the 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// user. If the user approves the request, a grant will be recorded on 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the server, and an access token will be returned to the caller. 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// In some cases we need to display a sign-in dialog. Normally the 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// profile will be signed in already, but if it turns out we need a 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// new login token, there is a sign-in flow. If that flow completes 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// successfully, getAuthToken proceeds to the non-interactive flow. 1791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class IdentityGetAuthTokenFunction : public ChromeAsyncExtensionFunction, 18090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public GaiaWebAuthFlow::Delegate, 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public IdentityMintRequestQueue::Request, 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public OAuth2MintTokenFlow::Delegate, 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public IdentitySigninFlow::Delegate, 184e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public OAuth2TokenService::Consumer, 185e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch public IdentityAPI::ShutdownObserver { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DECLARE_EXTENSION_FUNCTION("identity.getAuthToken", 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPERIMENTAL_IDENTITY_GETAUTHTOKEN); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdentityGetAuthTokenFunction(); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~IdentityGetAuthTokenFunction(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // IdentitySigninFlow::Delegate implementation: 19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void SigninSuccess() OVERRIDE; 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void SigninFailed() OVERRIDE; 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // GaiaWebAuthFlow::Delegate implementation: 20046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void OnGaiaFlowFailure(GaiaWebAuthFlow::Failure failure, 20146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GoogleServiceAuthError service_error, 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& oauth_error) OVERRIDE; 20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void OnGaiaFlowCompleted(const std::string& access_token, 20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& expiration) OVERRIDE; 20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // OAuth2TokenService::Consumer implementation: 20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request, 20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& access_token, 20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::Time& expiration_time) OVERRIDE; 21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request, 21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GoogleServiceAuthError& error) OVERRIDE; 21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<OAuth2TokenService::Request> login_token_request_; 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentWithChromeClientId); 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentWithNormalClientId); 220e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, InteractiveQueueShutdown); 221e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, NoninteractiveShutdown); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class MockGetAuthTokenFunction; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ExtensionFunction: 225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual bool RunAsync() OVERRIDE; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Helpers to report async function results to the caller. 228e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void StartAsyncRun(); 229e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch void CompleteAsyncRun(bool success); 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CompleteFunctionWithResult(const std::string& access_token); 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CompleteFunctionWithError(const std::string& error); 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initiate/complete the sub-flows. 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StartSigninFlow(); 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StartMintTokenFlow(IdentityMintRequestQueue::MintType type); 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CompleteMintTokenFlow(); 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // IdentityMintRequestQueue::Request implementation: 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void StartMintToken(IdentityMintRequestQueue::MintType type) OVERRIDE; 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OAuth2MintTokenFlow::Delegate implementation: 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnMintTokenSuccess(const std::string& access_token, 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int time_to_live) OVERRIDE; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnMintTokenFailure( 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GoogleServiceAuthError& error) OVERRIDE; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnIssueAdviceSuccess( 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IssueAdviceInfo& issue_advice) OVERRIDE; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 249e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // IdentityAPI::ShutdownObserver implementation: 250e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch virtual void OnShutdown() OVERRIDE; 251e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Starts a login access token request. 2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void StartLoginAccessTokenRequest(); 2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_CHROMEOS) 2568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Starts a login access token request for device robot account. This method 2578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // will be called only in enterprise kiosk mode in ChromeOS. 2588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void StartDeviceLoginAccessTokenRequest(); 2598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 2608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Starts a mint token request to GAIA. 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void StartGaiaRequest(const std::string& login_access_token); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Methods for invoking UI. Overridable for testing. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ShowLoginPopup(); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Caller owns the returned instance. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual OAuth2MintTokenFlow* CreateMintTokenFlow( 2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& login_access_token); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks if there is a master login token to mint tokens for the extension. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool HasLoginToken() const; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 27490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Maps OAuth2 protocol errors to an error message returned to the 27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // developer in chrome.runtime.lastError. 27690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string MapOAuth2ErrorToDescription(const std::string& error); 27790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string GetOAuth2ClientId() const; 279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool should_prompt_for_scopes_; 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue::MintType mint_token_flow_type_; 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<OAuth2MintTokenFlow> mint_token_flow_; 2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OAuth2MintTokenFlow::Mode gaia_mint_token_mode_; 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool should_prompt_for_signin_; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 286a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) scoped_ptr<ExtensionTokenKey> token_key_; 287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string oauth2_client_id_; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When launched in interactive mode, and if there is no existing grant, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a permissions prompt will be popped up to the user. 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IssueAdviceInfo issue_advice_; 29190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<GaiaWebAuthFlow> gaia_web_auth_flow_; 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<IdentitySigninFlow> signin_flow_; 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class IdentityGetProfileUserInfoFunction 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : public ChromeUIThreadExtensionFunction { 297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) public: 298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DECLARE_EXTENSION_FUNCTION("identity.getProfileUserInfo", 299f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IDENTITY_GETPROFILEUSERINFO); 300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 301f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) IdentityGetProfileUserInfoFunction(); 302f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 303f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) private: 304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual ~IdentityGetProfileUserInfoFunction(); 305f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // UIThreadExtensionFunction implementation. 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual ExtensionFunction::ResponseAction Run() OVERRIDE; 308f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}; 309f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 3101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class IdentityRemoveCachedAuthTokenFunction 3111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) : public ChromeSyncExtensionFunction { 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DECLARE_EXTENSION_FUNCTION("identity.removeCachedAuthToken", 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPERIMENTAL_IDENTITY_REMOVECACHEDAUTHTOKEN) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityRemoveCachedAuthTokenFunction(); 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~IdentityRemoveCachedAuthTokenFunction(); 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // SyncExtensionFunction implementation: 3215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu virtual bool RunSync() OVERRIDE; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class IdentityLaunchWebAuthFlowFunction : public ChromeAsyncExtensionFunction, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public WebAuthFlow::Delegate { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DECLARE_EXTENSION_FUNCTION("identity.launchWebAuthFlow", 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPERIMENTAL_IDENTITY_LAUNCHWEBAUTHFLOW); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdentityLaunchWebAuthFlowFunction(); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 332b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Tests may override extension_id. 333b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void InitFinalRedirectURLPrefixForTest(const std::string& extension_id); 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~IdentityLaunchWebAuthFlowFunction(); 337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual bool RunAsync() OVERRIDE; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebAuthFlow::Delegate implementation. 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnAuthFlowFailure(WebAuthFlow::Failure failure) OVERRIDE; 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnAuthFlowURLChange(const GURL& redirect_url) OVERRIDE; 34290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void OnAuthFlowTitleChange(const std::string& title) OVERRIDE {} 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 344b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Helper to initialize final URL prefix. 345b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void InitFinalRedirectURLPrefix(const std::string& extension_id); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WebAuthFlow> auth_flow_; 348b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GURL final_url_prefix_; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_API_H_ 354