OLD | NEW |
| (Empty) |
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_APP_NOTIFY_CHANNEL_SETUP_H_ | |
6 #define CHROME_BROWSER_EXTENSIONS_APP_NOTIFY_CHANNEL_SETUP_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "base/memory/ref_counted.h" | |
11 #include "base/memory/scoped_ptr.h" | |
12 #include "base/memory/weak_ptr.h" | |
13 #include "chrome/browser/extensions/app_notify_channel_ui.h" | |
14 #include "google_apis/gaia/oauth2_access_token_consumer.h" | |
15 #include "google_apis/gaia/oauth2_access_token_fetcher.h" | |
16 #include "googleurl/src/gurl.h" | |
17 #include "net/url_request/url_fetcher.h" | |
18 #include "net/url_request/url_fetcher_delegate.h" | |
19 | |
20 class Profile; | |
21 | |
22 namespace extensions { | |
23 class AppNotifyChannelSetupTest; | |
24 | |
25 // This class uses the browser login credentials to setup app notifications | |
26 // for a given app. | |
27 // | |
28 // Performs the following steps when Start() is called: | |
29 // 1. If the user is not logged in, prompt the user to login. | |
30 // 2. OAuth2: Record a notifications grant for the user and the given app. | |
31 // 3. Get notifications channel id for the current user. | |
32 // 4. Call the delegate passed in to the constructor with the results of | |
33 // the above steps. | |
34 class AppNotifyChannelSetup | |
35 : public net::URLFetcherDelegate, | |
36 public AppNotifyChannelUI::Delegate, | |
37 public OAuth2AccessTokenConsumer, | |
38 public base::RefCountedThreadSafe<AppNotifyChannelSetup> { | |
39 public: | |
40 // These are the various error conditions, made public for use by the test | |
41 // interceptor. | |
42 enum SetupError { | |
43 NONE, | |
44 AUTH_ERROR, | |
45 INTERNAL_ERROR, | |
46 USER_CANCELLED, | |
47 | |
48 // This is used for histograms, and should always be the last value. | |
49 SETUP_ERROR_BOUNDARY | |
50 }; | |
51 | |
52 class Delegate { | |
53 public: | |
54 // If successful, |channel_id| will be non-empty. On failure, |channel_id| | |
55 // will be empty and |error| will contain an error to report to the JS | |
56 // callback. | |
57 virtual void AppNotifyChannelSetupComplete( | |
58 const std::string& channel_id, | |
59 const std::string& error, | |
60 const AppNotifyChannelSetup* setup) = 0; | |
61 }; | |
62 | |
63 // For tests, we allow intercepting the request to setup the channel and | |
64 // forcing the return of a certain result to the delegate. | |
65 class InterceptorForTests { | |
66 public: | |
67 virtual void DoIntercept( | |
68 const AppNotifyChannelSetup* setup, | |
69 std::string* result_channel_id, | |
70 AppNotifyChannelSetup::SetupError* result_error) = 0; | |
71 }; | |
72 static void SetInterceptorForTests(InterceptorForTests* interceptor); | |
73 | |
74 // Ownership of |ui| is transferred to this object. | |
75 AppNotifyChannelSetup(Profile* profile, | |
76 const std::string& extension_id, | |
77 const std::string& client_id, | |
78 const GURL& requestor_url, | |
79 int return_route_id, | |
80 int callback_id, | |
81 AppNotifyChannelUI* ui, | |
82 base::WeakPtr<Delegate> delegate); | |
83 | |
84 AppNotifyChannelUI* ui() { return ui_.get(); } | |
85 | |
86 // This begins the process of fetching the channel id using the browser login | |
87 // credentials (or using |ui_| to prompt for login if needed). | |
88 void Start(); | |
89 | |
90 // OAuth2AccessTokenConsumer implementation. | |
91 virtual void OnGetTokenSuccess(const std::string& access_token, | |
92 const base::Time& expiration_time) OVERRIDE; | |
93 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; | |
94 | |
95 | |
96 // Getters for various members. | |
97 const std::string& extension_id() const { return extension_id_; } | |
98 const std::string& client_id() const { return client_id_; } | |
99 int return_route_id() const { return return_route_id_; } | |
100 int callback_id() const { return callback_id_; } | |
101 | |
102 protected: | |
103 // net::URLFetcherDelegate. | |
104 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; | |
105 | |
106 // AppNotifyChannelUI::Delegate. | |
107 virtual void OnSyncSetupResult(bool enabled) OVERRIDE; | |
108 | |
109 private: | |
110 enum State { | |
111 INITIAL, | |
112 LOGIN_STARTED, | |
113 LOGIN_DONE, | |
114 FETCH_ACCESS_TOKEN_STARTED, | |
115 FETCH_ACCESS_TOKEN_DONE, | |
116 RECORD_GRANT_STARTED, | |
117 RECORD_GRANT_DONE, | |
118 CHANNEL_ID_SETUP_STARTED, | |
119 CHANNEL_ID_SETUP_DONE, | |
120 ERROR_STATE | |
121 }; | |
122 | |
123 friend class base::RefCountedThreadSafe<AppNotifyChannelSetup>; | |
124 friend class AppNotifyChannelSetupTest; | |
125 | |
126 virtual ~AppNotifyChannelSetup(); | |
127 | |
128 // Creates an instance of URLFetcher that does not send or save cookies. | |
129 // The URLFether's method will be GET if body is empty, POST otherwise. | |
130 // Caller owns the returned instance. | |
131 net::URLFetcher* CreateURLFetcher( | |
132 const GURL& url, const std::string& body, const std::string& auth_token); | |
133 void BeginLogin(); | |
134 void EndLogin(bool success); | |
135 void BeginGetAccessToken(); | |
136 void EndGetAccessToken(bool success); | |
137 void BeginRecordGrant(); | |
138 void EndRecordGrant(const net::URLFetcher* source); | |
139 void BeginGetChannelId(); | |
140 void EndGetChannelId(const net::URLFetcher* source); | |
141 | |
142 void ReportResult(const std::string& channel_id, SetupError error); | |
143 | |
144 static std::string GetErrorString(SetupError error); | |
145 static GURL GetCWSChannelServiceURL(); | |
146 static GURL GetOAuth2IssueTokenURL(); | |
147 static std::string MakeOAuth2IssueTokenBody( | |
148 const std::string& oauth_client_id, const std::string& extension_id); | |
149 static std::string MakeAuthorizationHeader(const std::string& auth_token); | |
150 static bool ParseCWSChannelServiceResponse( | |
151 const std::string& data, std::string* result); | |
152 // Checks if the user needs to be prompted for login. | |
153 bool ShouldPromptForLogin() const; | |
154 void RegisterForTokenServiceNotifications(); | |
155 void UnregisterForTokenServiceNotifications(); | |
156 | |
157 Profile* profile_; | |
158 std::string extension_id_; | |
159 std::string client_id_; | |
160 GURL requestor_url_; | |
161 int return_route_id_; | |
162 int callback_id_; | |
163 base::WeakPtr<Delegate> delegate_; | |
164 scoped_ptr<net::URLFetcher> url_fetcher_; | |
165 scoped_ptr<OAuth2AccessTokenFetcher> oauth2_fetcher_; | |
166 scoped_ptr<AppNotifyChannelUI> ui_; | |
167 State state_; | |
168 std::string oauth2_access_token_; | |
169 // Keeps track of whether we have encountered failure in OAuth2 access | |
170 // token generation already. We use this to prevent us from doing an | |
171 // infinite loop of trying to generate access token, if that fails, try | |
172 // to login the user and generate access token, etc. | |
173 bool oauth2_access_token_failure_; | |
174 | |
175 DISALLOW_COPY_AND_ASSIGN(AppNotifyChannelSetup); | |
176 }; | |
177 | |
178 } // namespace extensions | |
179 | |
180 #endif // CHROME_BROWSER_EXTENSIONS_APP_NOTIFY_CHANNEL_SETUP_H_ | |
OLD | NEW |