identity_api.h revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_mint_queue.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/extensions/api/identity/identity_signin_flow.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/identity/web_auth_flow.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_function.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_prompt.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/signin_global_error.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/oauth2_mint_token_flow.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GetAuthTokenFunctionTest;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockGetAuthTokenFunction;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GoogleServiceAuthError;
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Profile;
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class SigninManagerBase;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace identity_constants {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kInvalidClientId[];
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kInvalidScopes[];
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kAuthFailure[];
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kNoGrant[];
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kUserRejected[];
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kUserNotSignedIn[];
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)extern const char kInteractionRequired[];
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern const char kInvalidRedirect[];
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)extern const char kOffTheRecord[];
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace identity_constants
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// identity.getAuthToken fetches an OAuth 2 function for the
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// caller. The request has three sub-flows: non-interactive,
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// interactive, and sign-in.
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// In the non-interactive flow, getAuthToken requests a token from
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// GAIA. GAIA may respond with a token, an error, or "consent
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// required". In the consent required cases, getAuthToken proceeds to
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the second, interactive phase.
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The interactive flow presents a scope approval dialog to the
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// user. If the user approves the request, a grant will be recorded on
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// the server, and an access token will be returned to the caller.
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)//
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// In some cases we need to display a sign-in dialog. Normally the
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// profile will be signed in already, but if it turns out we need a
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// new login token, there is a sign-in flow. If that flow completes
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// successfully, getAuthToken proceeds to the non-interactive flow.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IdentityGetAuthTokenFunction : public AsyncExtensionFunction,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     public ExtensionInstallPrompt::Delegate,
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     public IdentityMintRequestQueue::Request,
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     public OAuth2MintTokenFlow::Delegate,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     public IdentitySigninFlow::Delegate {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DECLARE_EXTENSION_FUNCTION("identity.getAuthToken",
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             EXPERIMENTAL_IDENTITY_GETAUTHTOKEN);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdentityGetAuthTokenFunction();
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~IdentityGetAuthTokenFunction();
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class GetAuthTokenFunctionTest;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class MockGetAuthTokenFunction;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExtensionFunction:
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RunImpl() OVERRIDE;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Helpers to report async function results to the caller.
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CompleteFunctionWithResult(const std::string& access_token);
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CompleteFunctionWithError(const std::string& error);
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Initiate/complete the sub-flows.
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StartSigninFlow();
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StartMintTokenFlow(IdentityMintRequestQueue::MintType type);
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void CompleteMintTokenFlow();
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // IdentityMintRequestQueue::Request implementation:
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void StartMintToken(IdentityMintRequestQueue::MintType type) OVERRIDE;
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OAuth2MintTokenFlow::Delegate implementation:
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnMintTokenSuccess(const std::string& access_token,
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                  int time_to_live) OVERRIDE;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMintTokenFailure(
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GoogleServiceAuthError& error) OVERRIDE;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnIssueAdviceSuccess(
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const IssueAdviceInfo& issue_advice) OVERRIDE;
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // IdentitySigninFlow::Delegate implementation:
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SigninSuccess(const std::string& token) OVERRIDE;
103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void SigninFailed() OVERRIDE;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ExtensionInstallPrompt::Delegate implementation:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIProceed() OVERRIDE;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Starts a mint token request to GAIA.
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void StartGaiaRequest(OAuth2MintTokenFlow::Mode mode);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Methods for invoking UI. Overridable for testing.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowLoginPopup();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Caller owns the returned instance.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual OAuth2MintTokenFlow* CreateMintTokenFlow(
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      OAuth2MintTokenFlow::Mode mode);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Checks if there is a master login token to mint tokens for the extension.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool HasLoginToken() const;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool should_prompt_for_scopes_;
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue::MintType mint_token_flow_type_;
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<OAuth2MintTokenFlow> mint_token_flow_;
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string refresh_token_;
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool should_prompt_for_signin_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When launched in interactive mode, and if there is no existing grant,
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a permissions prompt will be popped up to the user.
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo issue_advice_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExtensionInstallPrompt> install_ui_;
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<IdentitySigninFlow> signin_flow_;
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class IdentityRemoveCachedAuthTokenFunction : public SyncExtensionFunction {
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DECLARE_EXTENSION_FUNCTION("identity.removeCachedAuthToken",
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             EXPERIMENTAL_IDENTITY_REMOVECACHEDAUTHTOKEN)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityRemoveCachedAuthTokenFunction();
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) protected:
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual ~IdentityRemoveCachedAuthTokenFunction();
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // SyncExtensionFunction implementation:
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual bool RunImpl() OVERRIDE;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IdentityLaunchWebAuthFlowFunction : public AsyncExtensionFunction,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          public WebAuthFlow::Delegate {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DECLARE_EXTENSION_FUNCTION("identity.launchWebAuthFlow",
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             EXPERIMENTAL_IDENTITY_LAUNCHWEBAUTHFLOW);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IdentityLaunchWebAuthFlowFunction();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Tests may override extension_id.
157b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void InitFinalRedirectURLPrefixForTest(const std::string& extension_id);
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~IdentityLaunchWebAuthFlowFunction();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool RunImpl() OVERRIDE;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebAuthFlow::Delegate implementation.
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnAuthFlowFailure(WebAuthFlow::Failure failure) OVERRIDE;
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void OnAuthFlowURLChange(const GURL& redirect_url) OVERRIDE;
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
167b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  // Helper to initialize final URL prefix.
168b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  void InitFinalRedirectURLPrefix(const std::string& extension_id);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<WebAuthFlow> auth_flow_;
171b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  GURL final_url_prefix_;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class IdentityTokenCacheValue {
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue();
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  explicit IdentityTokenCacheValue(const IssueAdviceInfo& issue_advice);
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityTokenCacheValue(const std::string& token,
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                          base::TimeDelta time_to_live);
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ~IdentityTokenCacheValue();
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Order of these entries is used to determine whether or not new
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // entries supercede older ones in SetCachedToken.
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  enum CacheValueStatus {
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CACHE_STATUS_NOTFOUND,
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CACHE_STATUS_ADVICE,
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    CACHE_STATUS_TOKEN
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CacheValueStatus status() const;
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const IssueAdviceInfo& issue_advice() const;
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const std::string& token() const;
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool is_expired() const;
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  CacheValueStatus status_;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IssueAdviceInfo issue_advice_;
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::string token_;
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::Time expiration_time_;
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)class IdentityAPI : public ProfileKeyedAPI,
204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    public SigninGlobalError::AuthStatusProvider,
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    public content::NotificationObserver {
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit IdentityAPI(Profile* profile);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~IdentityAPI();
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Initialize();
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Request serialization queue for getAuthToken.
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue* mint_queue();
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Token cache
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void SetCachedToken(const std::string& extension_id,
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      const std::vector<std::string> scopes,
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                      const IdentityTokenCacheValue& token_data);
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void EraseCachedToken(const std::string& extension_id,
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        const std::string& token);
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void EraseAllCachedTokens();
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const IdentityTokenCacheValue& GetCachedToken(
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      const std::string& extension_id, const std::vector<std::string> scopes);
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void ReportAuthError(const GoogleServiceAuthError& error);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ProfileKeyedAPI implementation.
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Shutdown() OVERRIDE;
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static ProfileKeyedAPIFactory<IdentityAPI>* GetFactoryInstance();
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // AuthStatusProvider implementation.
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual GoogleServiceAuthError GetAuthStatus() const OVERRIDE;
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // content::NotificationObserver implementation.
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Observe(int type,
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       const content::NotificationSource& source,
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class ProfileKeyedAPIFactory<IdentityAPI>;
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  struct TokenCacheKey {
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TokenCacheKey(const std::string& extension_id,
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                  const std::set<std::string> scopes);
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ~TokenCacheKey();
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool operator<(const TokenCacheKey& rhs) const;
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::string extension_id;
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    std::set<std::string> scopes;
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ProfileKeyedAPI implementation.
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const char* service_name() {
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return "IdentityAPI";
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const bool kServiceIsNULLWhileTesting = true;
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Profile* profile_;
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  SigninManagerBase* signin_manager_;
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GoogleServiceAuthError error_;
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Used to listen to notifications from the TokenService.
260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::NotificationRegistrar registrar_;
261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  IdentityMintRequestQueue mint_queue_;
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::map<TokenCacheKey, IdentityTokenCacheValue> token_cache_;
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template <>
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ProfileKeyedAPIFactory<IdentityAPI>::DeclareFactoryDependencies();
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_IDENTITY_API_H_
271