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