- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / identity / experimental_identity_api.h
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_IDENTITY_EXPERIMENTAL_IDENTITY_API_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_IDENTITY_EXPERIMENTAL_IDENTITY_API_H_
7
8 #include <string>
9 #include <vector>
10
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/weak_ptr.h"
13 #include "chrome/browser/extensions/api/identity/experimental_web_auth_flow.h"
14 #include "chrome/browser/extensions/api/identity/identity_mint_queue.h"
15 #include "chrome/browser/extensions/api/identity/identity_signin_flow.h"
16 #include "chrome/browser/extensions/chrome_extension_function.h"
17 #include "chrome/browser/extensions/extension_install_prompt.h"
18 #include "google_apis/gaia/oauth2_mint_token_flow.h"
19 #include "google_apis/gaia/oauth2_token_service.h"
20
21 namespace extensions {
22
23 // TODO(courage): These functions exist to support some apps that were
24 // whitelisted to use the experimental API. Remove them once those
25 // apps have migrated.
26
27 // experimental.identity.getAuthToken fetches an OAuth 2 function for
28 // the caller. The request has three sub-flows: non-interactive,
29 // interactive, and sign-in.
30 //
31 // In the non-interactive flow, getAuthToken requests a token from
32 // GAIA. GAIA may respond with a token, an error, or "consent
33 // required". In the consent required cases, getAuthToken proceeds to
34 // the second, interactive phase.
35 //
36 // The interactive flow presents a scope approval dialog to the
37 // user. If the user approves the request, a grant will be recorded on
38 // the server, and an access token will be returned to the caller.
39 //
40 // In some cases we need to display a sign-in dialog. Normally the
41 // profile will be signed in already, but if it turns out we need a
42 // new login token, there is a sign-in flow. If that flow completes
43 // successfully, getAuthToken proceeds to the non-interactive flow.
44 class ExperimentalIdentityGetAuthTokenFunction
45     : public ChromeAsyncExtensionFunction,
46       public ExtensionInstallPrompt::Delegate,
47       public OAuth2MintTokenFlow::Delegate,
48       public IdentitySigninFlow::Delegate,
49       public OAuth2TokenService::Consumer {
50  public:
51   DECLARE_EXTENSION_FUNCTION("experimental.identity.getAuthToken",
52                              EXPERIMENTAL_IDENTITY_GETAUTHTOKEN);
53
54   ExperimentalIdentityGetAuthTokenFunction();
55   virtual bool RunImpl() OVERRIDE;
56
57  protected:
58   virtual ~ExperimentalIdentityGetAuthTokenFunction();
59
60  private:
61   friend class ExperimentalGetAuthTokenFunctionTest;
62   friend class ExperimentalMockGetAuthTokenFunction;
63
64   // Helpers to report async function results to the caller.
65   void CompleteFunctionWithResult(const std::string& access_token);
66   void CompleteFunctionWithError(const std::string& error);
67
68   // Initiate/complete the sub-flows.
69   void StartSigninFlow();
70   void StartMintTokenFlow(IdentityMintRequestQueue::MintType type);
71
72   // OAuth2MintTokenFlow::Delegate implementation:
73   virtual void OnMintTokenSuccess(const std::string& access_token,
74                                   int time_to_live) OVERRIDE;
75   virtual void OnMintTokenFailure(
76       const GoogleServiceAuthError& error) OVERRIDE;
77   virtual void OnIssueAdviceSuccess(
78       const IssueAdviceInfo& issue_advice) OVERRIDE;
79
80   // IdentitySigninFlow::Delegate implementation:
81   virtual void SigninSuccess() OVERRIDE;
82   virtual void SigninFailed() OVERRIDE;
83
84   // ExtensionInstallPrompt::Delegate implementation:
85   virtual void InstallUIProceed() OVERRIDE;
86   virtual void InstallUIAbort(bool user_initiated) OVERRIDE;
87
88   // OAuth2TokenService::Consumer implementation:
89   virtual void OnGetTokenSuccess(
90       const OAuth2TokenService::Request* request,
91       const std::string& access_token,
92       const base::Time& expiration_time) OVERRIDE;
93   virtual void OnGetTokenFailure(
94       const OAuth2TokenService::Request* request,
95       const GoogleServiceAuthError& error) OVERRIDE;
96
97   // Starts a login access token request.
98   virtual void StartLoginAccessTokenRequest();
99
100   // Starts a mint token request to GAIA.
101   void StartGaiaRequest(const std::string& login_access_token);
102
103   // Methods for invoking UI. Overridable for testing.
104   virtual void ShowLoginPopup();
105   virtual void ShowOAuthApprovalDialog(const IssueAdviceInfo& issue_advice);
106   // Caller owns the returned instance.
107   virtual OAuth2MintTokenFlow* CreateMintTokenFlow(
108       const std::string& login_access_token);
109
110   // Checks if there is a master login token to mint tokens for the extension.
111   virtual bool HasLoginToken() const;
112
113   bool should_prompt_for_scopes_;
114   scoped_ptr<OAuth2MintTokenFlow> mint_token_flow_;
115   OAuth2MintTokenFlow::Mode gaia_mint_token_mode_;
116   bool should_prompt_for_signin_;
117
118   // When launched in interactive mode, and if there is no existing grant,
119   // a permissions prompt will be popped up to the user.
120   IssueAdviceInfo issue_advice_;
121   scoped_ptr<ExtensionInstallPrompt> install_ui_;
122   scoped_ptr<IdentitySigninFlow> signin_flow_;
123   scoped_ptr<OAuth2TokenService::Request> login_token_request_;
124 };
125
126 class ExperimentalIdentityLaunchWebAuthFlowFunction
127     : public ChromeAsyncExtensionFunction,
128       public ExperimentalWebAuthFlow::Delegate {
129  public:
130   DECLARE_EXTENSION_FUNCTION("experimental.identity.launchWebAuthFlow",
131                              EXPERIMENTAL_IDENTITY_LAUNCHWEBAUTHFLOW);
132   ExperimentalIdentityLaunchWebAuthFlowFunction();
133
134   // URL checking helpers. Public for testing.
135   // Checks to see if the current URL ends the flow.
136   bool IsFinalRedirectURL(const GURL& url) const;
137
138   // Unit tests may override extension_id.
139   void InitFinalRedirectURLPrefixesForTest(const std::string& extension_id);
140
141  protected:
142   virtual ~ExperimentalIdentityLaunchWebAuthFlowFunction();
143   virtual bool RunImpl() OVERRIDE;
144
145   // Helper to initialize final URLs vector.
146   void InitFinalRedirectURLPrefixes(const std::string& extension_id);
147
148   scoped_ptr<ExperimentalWebAuthFlow> auth_flow_;
149   std::vector<GURL> final_prefixes_;
150
151  private:
152   // ExperimentalWebAuthFlow::Delegate implementation.
153   virtual void OnAuthFlowFailure(ExperimentalWebAuthFlow::Failure failure)
154       OVERRIDE;
155   virtual void OnAuthFlowURLChange(const GURL& redirect_url) OVERRIDE;
156 };
157
158 }  // namespace extensions
159
160 #endif  // CHROME_BROWSER_EXTENSIONS_API_IDENTITY_EXPERIMENTAL_IDENTITY_API_H_