OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "google_apis/gaia/oauth2_token_service.h" | 5 #include "google_apis/gaia/oauth2_token_service.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "base/time/time.h" | 14 #include "base/time/time.h" |
15 #include "base/timer/timer.h" | 15 #include "base/timer/timer.h" |
16 #include "google_apis/gaia/gaia_urls.h" | 16 #include "google_apis/gaia/gaia_urls.h" |
17 #include "google_apis/gaia/google_service_auth_error.h" | 17 #include "google_apis/gaia/google_service_auth_error.h" |
18 #include "google_apis/gaia/oauth2_access_token_consumer.h" | |
19 #include "google_apis/gaia/oauth2_access_token_fetcher.h" | |
20 #include "net/url_request/url_request_context_getter.h" | 18 #include "net/url_request/url_request_context_getter.h" |
21 | 19 |
22 int OAuth2TokenService::max_fetch_retry_num_ = 5; | 20 int OAuth2TokenService::max_fetch_retry_num_ = 5; |
23 | 21 |
| 22 OAuth2TokenService::ClientScopeSet::ClientScopeSet( |
| 23 const std::string& client_id, |
| 24 const ScopeSet& scopes) |
| 25 : client_id(client_id), |
| 26 scopes(scopes) { |
| 27 } |
| 28 |
| 29 OAuth2TokenService::ClientScopeSet::~ClientScopeSet() { |
| 30 } |
| 31 |
| 32 bool OAuth2TokenService::ClientScopeSet::operator<( |
| 33 const ClientScopeSet& s) const { |
| 34 if (client_id < s.client_id) |
| 35 return true; |
| 36 else if (s.client_id < client_id) |
| 37 return false; |
| 38 |
| 39 return scopes < s.scopes; |
| 40 } |
| 41 |
| 42 OAuth2TokenService::FetchParameters::FetchParameters( |
| 43 const std::string& client_id, |
| 44 const std::string& refresh_token, |
| 45 const ScopeSet& scopes) |
| 46 : client_id(client_id), |
| 47 refresh_token(refresh_token), |
| 48 scopes(scopes) { |
| 49 } |
| 50 |
| 51 OAuth2TokenService::FetchParameters::~FetchParameters() { |
| 52 } |
| 53 |
| 54 bool OAuth2TokenService::FetchParameters::operator<( |
| 55 const FetchParameters& p) const { |
| 56 if (client_id < p.client_id) |
| 57 return true; |
| 58 else if (p.client_id < client_id) |
| 59 return false; |
| 60 |
| 61 if (refresh_token < p.refresh_token) |
| 62 return true; |
| 63 else if (p.refresh_token < refresh_token) |
| 64 return false; |
| 65 |
| 66 return scopes < p.scopes; |
| 67 } |
| 68 |
24 OAuth2TokenService::RequestImpl::RequestImpl( | 69 OAuth2TokenService::RequestImpl::RequestImpl( |
25 OAuth2TokenService::Consumer* consumer) | 70 OAuth2TokenService::Consumer* consumer) |
26 : consumer_(consumer) { | 71 : consumer_(consumer) { |
27 } | 72 } |
28 | 73 |
29 OAuth2TokenService::RequestImpl::~RequestImpl() { | 74 OAuth2TokenService::RequestImpl::~RequestImpl() { |
30 DCHECK(CalledOnValidThread()); | 75 DCHECK(CalledOnValidThread()); |
31 } | 76 } |
32 | 77 |
33 void OAuth2TokenService::RequestImpl::InformConsumer( | 78 void OAuth2TokenService::RequestImpl::InformConsumer( |
34 const GoogleServiceAuthError& error, | 79 const GoogleServiceAuthError& error, |
35 const std::string& access_token, | 80 const std::string& access_token, |
36 const base::Time& expiration_date) { | 81 const base::Time& expiration_date) { |
37 DCHECK(CalledOnValidThread()); | 82 DCHECK(CalledOnValidThread()); |
38 if (error.state() == GoogleServiceAuthError::NONE) | 83 if (error.state() == GoogleServiceAuthError::NONE) |
39 consumer_->OnGetTokenSuccess(this, access_token, expiration_date); | 84 consumer_->OnGetTokenSuccess(this, access_token, expiration_date); |
40 else | 85 else |
41 consumer_->OnGetTokenFailure(this, error); | 86 consumer_->OnGetTokenFailure(this, error); |
42 } | 87 } |
43 | 88 |
| 89 // Class that fetches an OAuth2 access token for a given set of scopes and |
| 90 // OAuth2 refresh token. |
| 91 |
44 // Class that fetches OAuth2 access tokens for given scopes and refresh token. | 92 // Class that fetches OAuth2 access tokens for given scopes and refresh token. |
45 // | 93 // |
46 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry | 94 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry |
47 // mechanism is used to handle failures. | 95 // mechanism is used to handle failures. |
48 // | 96 // |
49 // To use this class, call CreateAndStart() to create and start a Fetcher. | 97 // To use this class, call CreateAndStart() to create and start a Fetcher. |
50 // | 98 // |
51 // The Fetcher will call back the service by calling | 99 // The Fetcher will call back the service by calling |
52 // OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is | 100 // OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is |
53 // not destructed before it completes fetching; if the Fetcher is destructed | 101 // not destructed before it completes fetching; if the Fetcher is destructed |
54 // before it completes fetching, the service will never be called back. The | 102 // before it completes fetching, the service will never be called back. The |
55 // Fetcher destructs itself after calling back the service when finishes | 103 // Fetcher destructs itself after calling back the service when finishes |
56 // fetching. | 104 // fetching. |
57 // | 105 // |
58 // Requests that are waiting for the fetching results of this Fetcher can be | 106 // Requests that are waiting for the fetching results of this Fetcher can be |
59 // added to the Fetcher by calling | 107 // added to the Fetcher by calling |
60 // OAuth2TokenService::Fetcher::AddWaitingRequest() before the Fetcher completes | 108 // OAuth2TokenService::Fetcher::AddWaitingRequest() before the Fetcher |
61 // fetching. | 109 // completes fetching. |
62 // | 110 // |
63 // The waiting requests are taken as weak pointers and they can be deleted. The | 111 // The waiting requests are taken as weak pointers and they can be deleted. |
64 // waiting requests will be called back with fetching results if they are not | 112 // The waiting requests will be called back with fetching results if they are |
65 // deleted | 113 // not deleted |
66 // - when the Fetcher completes fetching, if the Fetcher is not destructed | 114 // - when the Fetcher completes fetching, if the Fetcher is not destructed |
67 // before it completes fetching, or | 115 // before it completes fetching, or |
68 // - when the Fetcher is destructed if the Fetcher is destructed before it | 116 // - when the Fetcher is destructed if the Fetcher is destructed before it |
69 // completes fetching (in this case, the waiting requests will be called back | 117 // completes fetching (in this case, the waiting requests will be called |
70 // with error). | 118 // back with error). |
71 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { | 119 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { |
72 public: | 120 public: |
73 // Creates a Fetcher and starts fetching an OAuth2 access token for | 121 // Creates a Fetcher and starts fetching an OAuth2 access token for |
74 // |refresh_token| and |scopes| in the request context obtained by |getter|. | 122 // |refresh_token| and |scopes| in the request context obtained by |getter|. |
75 // The given |oauth2_token_service| will be informed when fetching is done. | 123 // The given |oauth2_token_service| will be informed when fetching is done. |
76 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, | 124 static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, |
77 net::URLRequestContextGetter* getter, | 125 net::URLRequestContextGetter* getter, |
78 const std::string& chrome_client_id, | 126 const std::string& client_id, |
79 const std::string& chrome_client_secret, | 127 const std::string& client_secret, |
80 const std::string& refresh_token, | 128 const std::string& refresh_token, |
81 const OAuth2TokenService::ScopeSet& scopes, | 129 const ScopeSet& scopes, |
82 base::WeakPtr<RequestImpl> waiting_request); | 130 base::WeakPtr<RequestImpl> waiting_request); |
83 virtual ~Fetcher(); | 131 virtual ~Fetcher(); |
84 | 132 |
85 // Add a request that is waiting for the result of this Fetcher. | 133 // Add a request that is waiting for the result of this Fetcher. |
86 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); | 134 void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); |
87 | 135 |
| 136 // Returns count of waiting requests. |
| 137 size_t GetWaitingRequestCount() const; |
| 138 |
88 void Cancel(); | 139 void Cancel(); |
89 | 140 |
90 const OAuth2TokenService::ScopeSet& GetScopeSet() const; | 141 const ScopeSet& GetScopeSet() const; |
91 const std::string& GetRefreshToken() const; | 142 const std::string& GetRefreshToken() const; |
| 143 const std::string& GetClientId() const; |
92 | 144 |
93 // The error result from this fetcher. | 145 // The error result from this fetcher. |
94 const GoogleServiceAuthError& error() const { return error_; } | 146 const GoogleServiceAuthError& error() const { return error_; } |
95 | 147 |
96 protected: | 148 protected: |
97 // OAuth2AccessTokenConsumer | 149 // OAuth2AccessTokenConsumer |
98 virtual void OnGetTokenSuccess(const std::string& access_token, | 150 virtual void OnGetTokenSuccess(const std::string& access_token, |
99 const base::Time& expiration_date) OVERRIDE; | 151 const base::Time& expiration_date) OVERRIDE; |
100 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; | 152 virtual void OnGetTokenFailure( |
| 153 const GoogleServiceAuthError& error) OVERRIDE; |
101 | 154 |
102 private: | 155 private: |
103 Fetcher(OAuth2TokenService* oauth2_token_service, | 156 Fetcher(OAuth2TokenService* oauth2_token_service, |
104 net::URLRequestContextGetter* getter, | 157 net::URLRequestContextGetter* getter, |
105 const std::string& chrome_client_id, | 158 const std::string& client_id, |
106 const std::string& chrome_client_secret, | 159 const std::string& client_secret, |
107 const std::string& refresh_token, | 160 const std::string& refresh_token, |
108 const OAuth2TokenService::ScopeSet& scopes, | 161 const OAuth2TokenService::ScopeSet& scopes, |
109 base::WeakPtr<RequestImpl> waiting_request); | 162 base::WeakPtr<RequestImpl> waiting_request); |
110 void Start(); | 163 void Start(); |
111 void InformWaitingRequests(); | 164 void InformWaitingRequests(); |
112 void InformWaitingRequestsAndDelete(); | 165 void InformWaitingRequestsAndDelete(); |
113 static bool ShouldRetry(const GoogleServiceAuthError& error); | 166 static bool ShouldRetry(const GoogleServiceAuthError& error); |
114 int64 ComputeExponentialBackOffMilliseconds(int retry_num); | 167 int64 ComputeExponentialBackOffMilliseconds(int retry_num); |
115 | 168 |
116 // |oauth2_token_service_| remains valid for the life of this Fetcher, since | 169 // |oauth2_token_service_| remains valid for the life of this Fetcher, since |
117 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is | 170 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is |
118 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess | 171 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess |
119 // (whichever comes first). | 172 // (whichever comes first). |
120 OAuth2TokenService* const oauth2_token_service_; | 173 OAuth2TokenService* const oauth2_token_service_; |
121 scoped_refptr<net::URLRequestContextGetter> getter_; | 174 scoped_refptr<net::URLRequestContextGetter> getter_; |
122 const std::string refresh_token_; | 175 const std::string refresh_token_; |
123 const OAuth2TokenService::ScopeSet scopes_; | 176 const ScopeSet scopes_; |
124 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; | 177 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; |
125 | 178 |
126 int retry_number_; | 179 int retry_number_; |
127 base::OneShotTimer<OAuth2TokenService::Fetcher> retry_timer_; | 180 base::OneShotTimer<Fetcher> retry_timer_; |
128 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; | 181 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; |
129 | 182 |
130 // Variables that store fetch results. | 183 // Variables that store fetch results. |
131 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle | 184 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle |
132 // destruction. | 185 // destruction. |
133 GoogleServiceAuthError error_; | 186 GoogleServiceAuthError error_; |
134 std::string access_token_; | 187 std::string access_token_; |
135 base::Time expiration_date_; | 188 base::Time expiration_date_; |
| 189 |
136 // OAuth2 client id and secret. | 190 // OAuth2 client id and secret. |
137 std::string chrome_client_id_; | 191 std::string client_id_; |
138 std::string chrome_client_secret_; | 192 std::string client_secret_; |
139 | 193 |
140 DISALLOW_COPY_AND_ASSIGN(Fetcher); | 194 DISALLOW_COPY_AND_ASSIGN(Fetcher); |
141 }; | 195 }; |
142 | 196 |
143 // static | 197 // static |
144 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( | 198 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( |
145 OAuth2TokenService* oauth2_token_service, | 199 OAuth2TokenService* oauth2_token_service, |
146 net::URLRequestContextGetter* getter, | 200 net::URLRequestContextGetter* getter, |
147 const std::string& chrome_client_id, | 201 const std::string& client_id, |
148 const std::string& chrome_client_secret, | 202 const std::string& client_secret, |
149 const std::string& refresh_token, | 203 const std::string& refresh_token, |
150 const OAuth2TokenService::ScopeSet& scopes, | 204 const OAuth2TokenService::ScopeSet& scopes, |
151 base::WeakPtr<RequestImpl> waiting_request) { | 205 base::WeakPtr<RequestImpl> waiting_request) { |
152 OAuth2TokenService::Fetcher* fetcher = new Fetcher( | 206 OAuth2TokenService::Fetcher* fetcher = new Fetcher( |
153 oauth2_token_service, | 207 oauth2_token_service, |
154 getter, | 208 getter, |
155 chrome_client_id, | 209 client_id, |
156 chrome_client_secret, | 210 client_secret, |
157 refresh_token, | 211 refresh_token, |
158 scopes, | 212 scopes, |
159 waiting_request); | 213 waiting_request); |
160 fetcher->Start(); | 214 fetcher->Start(); |
161 return fetcher; | 215 return fetcher; |
162 } | 216 } |
163 | 217 |
164 OAuth2TokenService::Fetcher::Fetcher( | 218 OAuth2TokenService::Fetcher::Fetcher( |
165 OAuth2TokenService* oauth2_token_service, | 219 OAuth2TokenService* oauth2_token_service, |
166 net::URLRequestContextGetter* getter, | 220 net::URLRequestContextGetter* getter, |
167 const std::string& chrome_client_id, | 221 const std::string& client_id, |
168 const std::string& chrome_client_secret, | 222 const std::string& client_secret, |
169 const std::string& refresh_token, | 223 const std::string& refresh_token, |
170 const OAuth2TokenService::ScopeSet& scopes, | 224 const OAuth2TokenService::ScopeSet& scopes, |
171 base::WeakPtr<RequestImpl> waiting_request) | 225 base::WeakPtr<RequestImpl> waiting_request) |
172 : oauth2_token_service_(oauth2_token_service), | 226 : oauth2_token_service_(oauth2_token_service), |
173 getter_(getter), | 227 getter_(getter), |
174 refresh_token_(refresh_token), | 228 refresh_token_(refresh_token), |
175 scopes_(scopes), | 229 scopes_(scopes), |
176 retry_number_(0), | 230 retry_number_(0), |
177 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE), | 231 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE), |
178 chrome_client_id_(chrome_client_id), | 232 client_id_(client_id), |
179 chrome_client_secret_(chrome_client_secret) { | 233 client_secret_(client_secret) { |
180 DCHECK(oauth2_token_service_); | 234 DCHECK(oauth2_token_service_); |
181 DCHECK(getter_.get()); | 235 DCHECK(getter_.get()); |
182 DCHECK(refresh_token_.length()); | 236 DCHECK(refresh_token_.length()); |
183 waiting_requests_.push_back(waiting_request); | 237 waiting_requests_.push_back(waiting_request); |
184 } | 238 } |
185 | 239 |
186 OAuth2TokenService::Fetcher::~Fetcher() { | 240 OAuth2TokenService::Fetcher::~Fetcher() { |
187 // Inform the waiting requests if it has not done so. | 241 // Inform the waiting requests if it has not done so. |
188 if (waiting_requests_.size()) | 242 if (waiting_requests_.size()) |
189 InformWaitingRequests(); | 243 InformWaitingRequests(); |
190 } | 244 } |
191 | 245 |
192 void OAuth2TokenService::Fetcher::Start() { | 246 void OAuth2TokenService::Fetcher::Start() { |
193 fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_.get())); | 247 fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_.get())); |
194 fetcher_->Start(chrome_client_id_, | 248 fetcher_->Start(client_id_, |
195 chrome_client_secret_, | 249 client_secret_, |
196 refresh_token_, | 250 refresh_token_, |
197 std::vector<std::string>(scopes_.begin(), scopes_.end())); | 251 std::vector<std::string>(scopes_.begin(), scopes_.end())); |
198 retry_timer_.Stop(); | 252 retry_timer_.Stop(); |
199 } | 253 } |
200 | 254 |
201 void OAuth2TokenService::Fetcher::OnGetTokenSuccess( | 255 void OAuth2TokenService::Fetcher::OnGetTokenSuccess( |
202 const std::string& access_token, | 256 const std::string& access_token, |
203 const base::Time& expiration_date) { | 257 const base::Time& expiration_date) { |
204 fetcher_.reset(); | 258 fetcher_.reset(); |
205 | 259 |
206 // Fetch completes. | 260 // Fetch completes. |
207 error_ = GoogleServiceAuthError::AuthErrorNone(); | 261 error_ = GoogleServiceAuthError::AuthErrorNone(); |
208 access_token_ = access_token; | 262 access_token_ = access_token; |
209 expiration_date_ = expiration_date; | 263 expiration_date_ = expiration_date; |
210 | 264 |
211 // Subclasses may override this method to skip caching in some cases, but | 265 // Subclasses may override this method to skip caching in some cases, but |
212 // we still inform all waiting Consumers of a successful token fetch below. | 266 // we still inform all waiting Consumers of a successful token fetch below. |
213 // This is intentional -- some consumers may need the token for cleanup | 267 // This is intentional -- some consumers may need the token for cleanup |
214 // tasks. https://chromiumcodereview.appspot.com/11312124/ | 268 // tasks. https://chromiumcodereview.appspot.com/11312124/ |
215 oauth2_token_service_->RegisterCacheEntry(refresh_token_, | 269 oauth2_token_service_->RegisterCacheEntry(client_id_, |
| 270 refresh_token_, |
216 scopes_, | 271 scopes_, |
217 access_token_, | 272 access_token_, |
218 expiration_date_); | 273 expiration_date_); |
219 InformWaitingRequestsAndDelete(); | 274 InformWaitingRequestsAndDelete(); |
220 } | 275 } |
221 | 276 |
222 void OAuth2TokenService::Fetcher::OnGetTokenFailure( | 277 void OAuth2TokenService::Fetcher::OnGetTokenFailure( |
223 const GoogleServiceAuthError& error) { | 278 const GoogleServiceAuthError& error) { |
224 fetcher_.reset(); | 279 fetcher_.reset(); |
225 | 280 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 oauth2_token_service_->OnFetchComplete(this); | 329 oauth2_token_service_->OnFetchComplete(this); |
275 InformWaitingRequests(); | 330 InformWaitingRequests(); |
276 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 331 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
277 } | 332 } |
278 | 333 |
279 void OAuth2TokenService::Fetcher::AddWaitingRequest( | 334 void OAuth2TokenService::Fetcher::AddWaitingRequest( |
280 base::WeakPtr<OAuth2TokenService::RequestImpl> waiting_request) { | 335 base::WeakPtr<OAuth2TokenService::RequestImpl> waiting_request) { |
281 waiting_requests_.push_back(waiting_request); | 336 waiting_requests_.push_back(waiting_request); |
282 } | 337 } |
283 | 338 |
| 339 size_t OAuth2TokenService::Fetcher::GetWaitingRequestCount() const { |
| 340 return waiting_requests_.size(); |
| 341 } |
| 342 |
284 void OAuth2TokenService::Fetcher::Cancel() { | 343 void OAuth2TokenService::Fetcher::Cancel() { |
285 fetcher_.reset(); | 344 fetcher_.reset(); |
286 retry_timer_.Stop(); | 345 retry_timer_.Stop(); |
287 error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED); | 346 error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED); |
288 InformWaitingRequestsAndDelete(); | 347 InformWaitingRequestsAndDelete(); |
289 } | 348 } |
290 | 349 |
291 const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet() | 350 const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet() |
292 const { | 351 const { |
293 return scopes_; | 352 return scopes_; |
294 } | 353 } |
295 | 354 |
296 const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const { | 355 const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const { |
297 return refresh_token_; | 356 return refresh_token_; |
298 } | 357 } |
299 | 358 |
| 359 const std::string& OAuth2TokenService::Fetcher::GetClientId() const { |
| 360 return client_id_; |
| 361 } |
| 362 |
300 OAuth2TokenService::Request::Request() { | 363 OAuth2TokenService::Request::Request() { |
301 } | 364 } |
302 | 365 |
303 OAuth2TokenService::Request::~Request() { | 366 OAuth2TokenService::Request::~Request() { |
304 } | 367 } |
305 | 368 |
306 OAuth2TokenService::Consumer::Consumer() { | 369 OAuth2TokenService::Consumer::Consumer() { |
307 } | 370 } |
308 | 371 |
309 OAuth2TokenService::Consumer::~Consumer() { | 372 OAuth2TokenService::Consumer::~Consumer() { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 if (!RefreshTokenIsAvailable()) { | 445 if (!RefreshTokenIsAvailable()) { |
383 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 446 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
384 &RequestImpl::InformConsumer, | 447 &RequestImpl::InformConsumer, |
385 request->AsWeakPtr(), | 448 request->AsWeakPtr(), |
386 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP), | 449 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP), |
387 std::string(), | 450 std::string(), |
388 base::Time())); | 451 base::Time())); |
389 return request.PassAs<Request>(); | 452 return request.PassAs<Request>(); |
390 } | 453 } |
391 | 454 |
392 if (HasCacheEntry(scopes)) { | 455 ClientScopeSet client_scopes(client_id, scopes); |
393 StartCacheLookupRequest(request.get(), scopes, consumer); | 456 if (HasCacheEntry(client_scopes)) { |
| 457 StartCacheLookupRequest(request.get(), client_scopes, consumer); |
394 } else { | 458 } else { |
395 FetchOAuth2Token(request.get(), | 459 FetchOAuth2Token(request.get(), |
396 getter, | 460 getter, |
397 client_id, | 461 client_id, |
398 client_secret, | 462 client_secret, |
399 scopes); | 463 scopes); |
400 } | 464 } |
401 return request.PassAs<Request>(); | 465 return request.PassAs<Request>(); |
402 } | 466 } |
403 | 467 |
404 void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request, | 468 void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request, |
405 net::URLRequestContextGetter* getter, | 469 net::URLRequestContextGetter* getter, |
406 const std::string& client_id, | 470 const std::string& client_id, |
407 const std::string& client_secret, | 471 const std::string& client_secret, |
408 const ScopeSet& scopes) { | 472 const ScopeSet& scopes) { |
409 std::string refresh_token = GetRefreshToken(); | 473 std::string refresh_token = GetRefreshToken(); |
410 | 474 |
411 // If there is already a pending fetcher for |scopes| and |refresh_token|, | 475 // If there is already a pending fetcher for |scopes| and |refresh_token|, |
412 // simply register this |request| for those results rather than starting | 476 // simply register this |request| for those results rather than starting |
413 // a new fetcher. | 477 // a new fetcher. |
414 FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes); | 478 FetchParameters fetch_parameters = FetchParameters(client_id, |
| 479 refresh_token, |
| 480 scopes); |
415 std::map<FetchParameters, Fetcher*>::iterator iter = | 481 std::map<FetchParameters, Fetcher*>::iterator iter = |
416 pending_fetchers_.find(fetch_parameters); | 482 pending_fetchers_.find(fetch_parameters); |
417 if (iter != pending_fetchers_.end()) { | 483 if (iter != pending_fetchers_.end()) { |
418 iter->second->AddWaitingRequest(request->AsWeakPtr()); | 484 iter->second->AddWaitingRequest(request->AsWeakPtr()); |
419 return; | 485 return; |
420 } | 486 } |
421 | 487 |
422 pending_fetchers_[fetch_parameters] = | 488 pending_fetchers_[fetch_parameters] = |
423 Fetcher::CreateAndStart(this, | 489 Fetcher::CreateAndStart(this, |
424 getter, | 490 getter, |
425 client_id, | 491 client_id, |
426 client_secret, | 492 client_secret, |
427 refresh_token, | 493 refresh_token, |
428 scopes, | 494 scopes, |
429 request->AsWeakPtr()); | 495 request->AsWeakPtr()); |
430 } | 496 } |
431 | 497 |
432 void OAuth2TokenService::StartCacheLookupRequest( | 498 void OAuth2TokenService::StartCacheLookupRequest( |
433 RequestImpl* request, | 499 RequestImpl* request, |
434 const OAuth2TokenService::ScopeSet& scopes, | 500 const OAuth2TokenService::ClientScopeSet& client_scopes, |
435 OAuth2TokenService::Consumer* consumer) { | 501 OAuth2TokenService::Consumer* consumer) { |
436 CHECK(HasCacheEntry(scopes)); | 502 CHECK(HasCacheEntry(client_scopes)); |
437 const CacheEntry* cache_entry = GetCacheEntry(scopes); | 503 const CacheEntry* cache_entry = GetCacheEntry(client_scopes); |
438 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 504 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
439 &RequestImpl::InformConsumer, | 505 &RequestImpl::InformConsumer, |
440 request->AsWeakPtr(), | 506 request->AsWeakPtr(), |
441 GoogleServiceAuthError(GoogleServiceAuthError::NONE), | 507 GoogleServiceAuthError(GoogleServiceAuthError::NONE), |
442 cache_entry->access_token, | 508 cache_entry->access_token, |
443 cache_entry->expiration_date)); | 509 cache_entry->expiration_date)); |
444 } | 510 } |
445 | 511 |
446 void OAuth2TokenService::InvalidateToken(const ScopeSet& scopes, | 512 void OAuth2TokenService::InvalidateToken(const ScopeSet& scopes, |
447 const std::string& invalid_token) { | 513 const std::string& invalid_token) { |
448 DCHECK(CalledOnValidThread()); | 514 DCHECK(CalledOnValidThread()); |
449 RemoveCacheEntry(scopes, invalid_token); | 515 RemoveCacheEntry( |
| 516 ClientScopeSet(GaiaUrls::GetInstance()->oauth2_chrome_client_id(), |
| 517 scopes), |
| 518 invalid_token); |
450 } | 519 } |
451 | 520 |
452 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { | 521 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { |
453 DCHECK(CalledOnValidThread()); | 522 DCHECK(CalledOnValidThread()); |
454 | 523 |
455 // Update the auth error state so auth errors are appropriately communicated | 524 // Update the auth error state so auth errors are appropriately communicated |
456 // to the user. | 525 // to the user. |
457 UpdateAuthError(fetcher->error()); | 526 UpdateAuthError(fetcher->error()); |
458 | 527 |
459 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh | 528 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh |
(...skipping 16 matching lines...) Expand all Loading... |
476 // | 545 // |
477 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its | 546 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its |
478 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in | 547 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in |
479 // method StartRequest(). | 548 // method StartRequest(). |
480 // | 549 // |
481 // When this method is called, |fetcher| is alive and uncompleted. | 550 // When this method is called, |fetcher| is alive and uncompleted. |
482 // By (1), |fetcher| is created by this service. | 551 // By (1), |fetcher| is created by this service. |
483 // Then by (2), |fetcher| is recorded in |pending_fetchers_|. | 552 // Then by (2), |fetcher| is recorded in |pending_fetchers_|. |
484 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. | 553 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. |
485 std::map<FetchParameters, Fetcher*>::iterator iter = | 554 std::map<FetchParameters, Fetcher*>::iterator iter = |
486 pending_fetchers_.find(std::make_pair( | 555 pending_fetchers_.find(FetchParameters( |
487 fetcher->GetRefreshToken(), fetcher->GetScopeSet())); | 556 fetcher->GetClientId(), |
| 557 fetcher->GetRefreshToken(), |
| 558 fetcher->GetScopeSet())); |
488 DCHECK(iter != pending_fetchers_.end()); | 559 DCHECK(iter != pending_fetchers_.end()); |
489 DCHECK_EQ(fetcher, iter->second); | 560 DCHECK_EQ(fetcher, iter->second); |
490 pending_fetchers_.erase(iter); | 561 pending_fetchers_.erase(iter); |
491 } | 562 } |
492 | 563 |
493 bool OAuth2TokenService::HasCacheEntry( | 564 bool OAuth2TokenService::HasCacheEntry( |
494 const OAuth2TokenService::ScopeSet& scopes) { | 565 const ClientScopeSet& client_scopes) { |
495 const CacheEntry* cache_entry = GetCacheEntry(scopes); | 566 const CacheEntry* cache_entry = GetCacheEntry(client_scopes); |
496 return cache_entry && cache_entry->access_token.length(); | 567 return cache_entry && cache_entry->access_token.length(); |
497 } | 568 } |
498 | 569 |
499 const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( | 570 const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( |
500 const OAuth2TokenService::ScopeSet& scopes) { | 571 const ClientScopeSet& client_scopes) { |
501 DCHECK(CalledOnValidThread()); | 572 DCHECK(CalledOnValidThread()); |
502 TokenCache::iterator token_iterator = token_cache_.find(scopes); | 573 TokenCache::iterator token_iterator = token_cache_.find(client_scopes); |
503 if (token_iterator == token_cache_.end()) | 574 if (token_iterator == token_cache_.end()) |
504 return NULL; | 575 return NULL; |
505 if (token_iterator->second.expiration_date <= base::Time::Now()) { | 576 if (token_iterator->second.expiration_date <= base::Time::Now()) { |
506 token_cache_.erase(token_iterator); | 577 token_cache_.erase(token_iterator); |
507 return NULL; | 578 return NULL; |
508 } | 579 } |
509 return &token_iterator->second; | 580 return &token_iterator->second; |
510 } | 581 } |
511 | 582 |
512 bool OAuth2TokenService::RemoveCacheEntry( | 583 bool OAuth2TokenService::RemoveCacheEntry( |
513 const OAuth2TokenService::ScopeSet& scopes, | 584 const ClientScopeSet& client_scopes, |
514 const std::string& token_to_remove) { | 585 const std::string& token_to_remove) { |
515 DCHECK(CalledOnValidThread()); | 586 DCHECK(CalledOnValidThread()); |
516 TokenCache::iterator token_iterator = token_cache_.find(scopes); | 587 TokenCache::iterator token_iterator = token_cache_.find(client_scopes); |
517 if (token_iterator != token_cache_.end() && | 588 if (token_iterator != token_cache_.end() && |
518 token_iterator->second.access_token == token_to_remove) { | 589 token_iterator->second.access_token == token_to_remove) { |
519 token_cache_.erase(token_iterator); | 590 token_cache_.erase(token_iterator); |
520 return true; | 591 return true; |
521 } | 592 } |
522 return false; | 593 return false; |
523 } | 594 } |
524 | 595 |
525 void OAuth2TokenService::RegisterCacheEntry( | 596 void OAuth2TokenService::RegisterCacheEntry( |
| 597 const std::string& client_id, |
526 const std::string& refresh_token, | 598 const std::string& refresh_token, |
527 const OAuth2TokenService::ScopeSet& scopes, | 599 const OAuth2TokenService::ScopeSet& scopes, |
528 const std::string& access_token, | 600 const std::string& access_token, |
529 const base::Time& expiration_date) { | 601 const base::Time& expiration_date) { |
530 DCHECK(CalledOnValidThread()); | 602 DCHECK(CalledOnValidThread()); |
531 | 603 |
532 CacheEntry& token = token_cache_[scopes]; | 604 CacheEntry& token = token_cache_[ClientScopeSet(client_id, |
| 605 scopes)]; |
533 token.access_token = access_token; | 606 token.access_token = access_token; |
534 token.expiration_date = expiration_date; | 607 token.expiration_date = expiration_date; |
535 } | 608 } |
536 | 609 |
537 void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) { | 610 void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) { |
538 // Default implementation does nothing. | 611 // Default implementation does nothing. |
539 } | 612 } |
540 | 613 |
541 void OAuth2TokenService::ClearCache() { | 614 void OAuth2TokenService::ClearCache() { |
542 DCHECK(CalledOnValidThread()); | 615 DCHECK(CalledOnValidThread()); |
(...skipping 11 matching lines...) Expand all Loading... |
554 CancelFetchers(fetchers_to_cancel); | 627 CancelFetchers(fetchers_to_cancel); |
555 } | 628 } |
556 | 629 |
557 void OAuth2TokenService::CancelRequestsForToken( | 630 void OAuth2TokenService::CancelRequestsForToken( |
558 const std::string& refresh_token) { | 631 const std::string& refresh_token) { |
559 std::vector<Fetcher*> fetchers_to_cancel; | 632 std::vector<Fetcher*> fetchers_to_cancel; |
560 for (std::map<FetchParameters, Fetcher*>::iterator iter = | 633 for (std::map<FetchParameters, Fetcher*>::iterator iter = |
561 pending_fetchers_.begin(); | 634 pending_fetchers_.begin(); |
562 iter != pending_fetchers_.end(); | 635 iter != pending_fetchers_.end(); |
563 ++iter) { | 636 ++iter) { |
564 if (iter->first.first == refresh_token) | 637 if (iter->first.refresh_token == refresh_token) |
565 fetchers_to_cancel.push_back(iter->second); | 638 fetchers_to_cancel.push_back(iter->second); |
566 } | 639 } |
567 CancelFetchers(fetchers_to_cancel); | 640 CancelFetchers(fetchers_to_cancel); |
568 } | 641 } |
569 | 642 |
570 void OAuth2TokenService::CancelFetchers( | 643 void OAuth2TokenService::CancelFetchers( |
571 std::vector<Fetcher*> fetchers_to_cancel) { | 644 std::vector<Fetcher*> fetchers_to_cancel) { |
572 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = | 645 for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = |
573 fetchers_to_cancel.begin(); | 646 fetchers_to_cancel.begin(); |
574 iter != fetchers_to_cancel.end(); | 647 iter != fetchers_to_cancel.end(); |
(...skipping 24 matching lines...) Expand all Loading... |
599 | 672 |
600 int OAuth2TokenService::cache_size_for_testing() const { | 673 int OAuth2TokenService::cache_size_for_testing() const { |
601 return token_cache_.size(); | 674 return token_cache_.size(); |
602 } | 675 } |
603 | 676 |
604 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( | 677 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( |
605 int max_retries) { | 678 int max_retries) { |
606 DCHECK(CalledOnValidThread()); | 679 DCHECK(CalledOnValidThread()); |
607 max_fetch_retry_num_ = max_retries; | 680 max_fetch_retry_num_ = max_retries; |
608 } | 681 } |
| 682 |
| 683 size_t OAuth2TokenService::GetNumPendingRequestsForTesting( |
| 684 const std::string& client_id, |
| 685 const std::string& refresh_token, |
| 686 const ScopeSet& scopes) const { |
| 687 PendingFetcherMap::const_iterator iter = pending_fetchers_.find( |
| 688 OAuth2TokenService::FetchParameters( |
| 689 client_id, |
| 690 refresh_token, |
| 691 scopes)); |
| 692 return iter == pending_fetchers_.end() ? |
| 693 0 : iter->second->GetWaitingRequestCount(); |
| 694 } |
OLD | NEW |