| 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 |