identity_api.h revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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" 168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/account_tracker.h" 1790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/gaia_web_auth_flow.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_mint_queue.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_signin_flow.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/web_auth_flow.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/profile_keyed_api_factory.h" 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_function.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/signin_global_error.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/oauth2_mint_token_flow.h" 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "google_apis/gaia/oauth2_token_service.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GoogleServiceAuthError; 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass MockGetAuthTokenFunction; 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Profile; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#if defined(OS_CHROMEOS) 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace chromeos { 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class DeviceOAuth2TokenService; 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif 361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class GetAuthTokenFunctionTest; 4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)class MockGetAuthTokenFunction; 4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace identity_constants { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kInvalidClientId[]; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kInvalidScopes[]; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kAuthFailure[]; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kNoGrant[]; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kUserRejected[]; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kUserNotSignedIn[]; 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)extern const char kInteractionRequired[]; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kInvalidRedirect[]; 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)extern const char kOffTheRecord[]; 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)extern const char kPageLoadFailure[]; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace identity_constants 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// identity.getAuthToken fetches an OAuth 2 function for the 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// caller. The request has three sub-flows: non-interactive, 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// interactive, and sign-in. 58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// In the non-interactive flow, getAuthToken requests a token from 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// GAIA. GAIA may respond with a token, an error, or "consent 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// required". In the consent required cases, getAuthToken proceeds to 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the second, interactive phase. 63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The interactive flow presents a scope approval dialog to the 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// user. If the user approves the request, a grant will be recorded on 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the server, and an access token will be returned to the caller. 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// In some cases we need to display a sign-in dialog. Normally the 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// profile will be signed in already, but if it turns out we need a 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// new login token, there is a sign-in flow. If that flow completes 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// successfully, getAuthToken proceeds to the non-interactive flow. 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class IdentityGetAuthTokenFunction : public ChromeAsyncExtensionFunction, 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) public GaiaWebAuthFlow::Delegate, 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public IdentityMintRequestQueue::Request, 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public OAuth2MintTokenFlow::Delegate, 76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public IdentitySigninFlow::Delegate, 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public OAuth2TokenService::Consumer { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DECLARE_EXTENSION_FUNCTION("identity.getAuthToken", 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPERIMENTAL_IDENTITY_GETAUTHTOKEN); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdentityGetAuthTokenFunction(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~IdentityGetAuthTokenFunction(); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentWithChromeClientId); 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch FRIEND_TEST_ALL_PREFIXES(GetAuthTokenFunctionTest, 91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ComponentWithNormalClientId); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class MockGetAuthTokenFunction; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ExtensionFunction: 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool RunImpl() OVERRIDE; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Helpers to report async function results to the caller. 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CompleteFunctionWithResult(const std::string& access_token); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CompleteFunctionWithError(const std::string& error); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Initiate/complete the sub-flows. 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StartSigninFlow(); 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StartMintTokenFlow(IdentityMintRequestQueue::MintType type); 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void CompleteMintTokenFlow(); 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // IdentityMintRequestQueue::Request implementation: 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void StartMintToken(IdentityMintRequestQueue::MintType type) OVERRIDE; 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OAuth2MintTokenFlow::Delegate implementation: 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnMintTokenSuccess(const std::string& access_token, 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int time_to_live) OVERRIDE; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnMintTokenFailure( 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GoogleServiceAuthError& error) OVERRIDE; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnIssueAdviceSuccess( 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const IssueAdviceInfo& issue_advice) OVERRIDE; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // IdentitySigninFlow::Delegate implementation: 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void SigninSuccess() OVERRIDE; 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void SigninFailed() OVERRIDE; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // GaiaWebAuthFlow::Delegate implementation: 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void OnGaiaFlowFailure(GaiaWebAuthFlow::Failure failure, 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GoogleServiceAuthError service_error, 12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& oauth_error) OVERRIDE; 12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void OnGaiaFlowCompleted(const std::string& access_token, 12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::string& expiration) OVERRIDE; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // OAuth2TokenService::Consumer implementation: 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request, 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& access_token, 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const base::Time& expiration_time) OVERRIDE; 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request, 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const GoogleServiceAuthError& error) OVERRIDE; 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Starts a login access token request. 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch virtual void StartLoginAccessTokenRequest(); 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#if defined(OS_CHROMEOS) 1398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Starts a login access token request for device robot account. This method 1408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // will be called only in enterprise kiosk mode in ChromeOS. 1418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void StartDeviceLoginAccessTokenRequest(); 1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Continuation of StartDeviceLoginAccessTokenRequest(). 1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) virtual void DidGetTokenService(chromeos::DeviceOAuth2TokenService* service); 1458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#endif 1468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Starts a mint token request to GAIA. 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void StartGaiaRequest(const std::string& login_access_token); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Methods for invoking UI. Overridable for testing. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ShowLoginPopup(); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Caller owns the returned instance. 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual OAuth2MintTokenFlow* CreateMintTokenFlow( 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& login_access_token); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Checks if there is a master login token to mint tokens for the extension. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool HasLoginToken() const; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Maps OAuth2 protocol errors to an error message returned to the 16190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // developer in chrome.runtime.lastError. 16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string MapOAuth2ErrorToDescription(const std::string& error); 16390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string GetOAuth2ClientId() const; 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool should_prompt_for_scopes_; 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue::MintType mint_token_flow_type_; 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<OAuth2MintTokenFlow> mint_token_flow_; 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OAuth2MintTokenFlow::Mode gaia_mint_token_mode_; 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool should_prompt_for_signin_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string oauth2_client_id_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When launched in interactive mode, and if there is no existing grant, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a permissions prompt will be popped up to the user. 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IssueAdviceInfo issue_advice_; 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) scoped_ptr<GaiaWebAuthFlow> gaia_web_auth_flow_; 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<IdentitySigninFlow> signin_flow_; 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<OAuth2TokenService::Request> login_token_request_; 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class IdentityRemoveCachedAuthTokenFunction 1821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) : public ChromeSyncExtensionFunction { 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DECLARE_EXTENSION_FUNCTION("identity.removeCachedAuthToken", 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPERIMENTAL_IDENTITY_REMOVECACHEDAUTHTOKEN) 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityRemoveCachedAuthTokenFunction(); 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected: 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual ~IdentityRemoveCachedAuthTokenFunction(); 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // SyncExtensionFunction implementation: 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual bool RunImpl() OVERRIDE; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class IdentityLaunchWebAuthFlowFunction : public ChromeAsyncExtensionFunction, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public WebAuthFlow::Delegate { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DECLARE_EXTENSION_FUNCTION("identity.launchWebAuthFlow", 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPERIMENTAL_IDENTITY_LAUNCHWEBAUTHFLOW); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IdentityLaunchWebAuthFlowFunction(); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 203b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Tests may override extension_id. 204b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void InitFinalRedirectURLPrefixForTest(const std::string& extension_id); 205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~IdentityLaunchWebAuthFlowFunction(); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool RunImpl() OVERRIDE; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WebAuthFlow::Delegate implementation. 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnAuthFlowFailure(WebAuthFlow::Failure failure) OVERRIDE; 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void OnAuthFlowURLChange(const GURL& redirect_url) OVERRIDE; 21390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) virtual void OnAuthFlowTitleChange(const std::string& title) OVERRIDE {} 214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 215b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // Helper to initialize final URL prefix. 216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) void InitFinalRedirectURLPrefix(const std::string& extension_id); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WebAuthFlow> auth_flow_; 219b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) GURL final_url_prefix_; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class IdentityTokenCacheValue { 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public: 224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityTokenCacheValue(); 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) explicit IdentityTokenCacheValue(const IssueAdviceInfo& issue_advice); 226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityTokenCacheValue(const std::string& token, 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeDelta time_to_live); 228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ~IdentityTokenCacheValue(); 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Order of these entries is used to determine whether or not new 231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // entries supercede older ones in SetCachedToken. 232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enum CacheValueStatus { 233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CACHE_STATUS_NOTFOUND, 234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CACHE_STATUS_ADVICE, 235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CACHE_STATUS_TOKEN 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CacheValueStatus status() const; 239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IssueAdviceInfo& issue_advice() const; 240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& token() const; 24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::Time& expiration_time() const; 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private: 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_expired() const; 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CacheValueStatus status_; 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IssueAdviceInfo issue_advice_; 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string token_; 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Time expiration_time_; 250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class IdentityAPI : public ProfileKeyedAPI, 2538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) public AccountTracker::Observer { 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) struct TokenCacheKey { 25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) TokenCacheKey(const std::string& extension_id, 25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const std::set<std::string> scopes); 25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ~TokenCacheKey(); 25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool operator<(const TokenCacheKey& rhs) const; 26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string extension_id; 26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::set<std::string> scopes; 26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) }; 26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) typedef std::map<TokenCacheKey, IdentityTokenCacheValue> CachedTokens; 26590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit IdentityAPI(Profile* profile); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~IdentityAPI(); 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Request serialization queue for getAuthToken. 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue* mint_queue(); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Token cache 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void SetCachedToken(const std::string& extension_id, 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::vector<std::string> scopes, 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IdentityTokenCacheValue& token_data); 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void EraseCachedToken(const std::string& extension_id, 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& token); 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void EraseAllCachedTokens(); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IdentityTokenCacheValue& GetCachedToken( 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& extension_id, const std::vector<std::string> scopes); 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 28290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const CachedTokens& GetAllCachedTokens(); 28390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void ReportAuthError(const GoogleServiceAuthError& error); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ProfileKeyedAPI implementation. 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual void Shutdown() OVERRIDE; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static ProfileKeyedAPIFactory<IdentityAPI>* GetFactoryInstance(); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // AccountTracker::Observer implementation: 2918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void OnAccountAdded(const AccountIds& ids) OVERRIDE; 2928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void OnAccountRemoved(const AccountIds& ids) OVERRIDE; 2938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) virtual void OnAccountSignInChanged(const AccountIds& ids, bool is_signed_in) 2948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) OVERRIDE; 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class ProfileKeyedAPIFactory<IdentityAPI>; 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ProfileKeyedAPI implementation. 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const char* service_name() { 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return "IdentityAPI"; 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static const bool kServiceIsNULLWhileTesting = true; 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Profile* profile_; 306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IdentityMintRequestQueue mint_queue_; 30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CachedTokens token_cache_; 3088bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) AccountTracker account_tracker_; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <> 312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies(); 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_API_H_ 317