Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: chrome/browser/signin/oauth2_token_service.cc

Issue 11038063: Support chrome_to_mobile job receiving Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix format Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 #include "chrome/browser/signin/oauth2_token_service.h"
6
7 #include "base/callback.h"
8 #include "base/time.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/signin/oauth2_token_service_factory.h"
11 #include "chrome/browser/signin/token_service.h"
12 #include "chrome/browser/signin/token_service_factory.h"
13 #include "chrome/common/chrome_notification_types.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/notification_details.h"
16 #include "content/public/browser/notification_source.h"
17 #include "google_apis/gaia/gaia_constants.h"
18 #include "google_apis/gaia/gaia_urls.h"
19 #include "google_apis/gaia/google_service_auth_error.h"
20 #include "google_apis/gaia/oauth2_access_token_consumer.h"
21 #include "google_apis/gaia/oauth2_access_token_fetcher.h"
22
23 using content::BrowserThread;
24
25 // Data structure used to communicate between the thread the request is made on
26 // and the UI thread where the TokenService is accessible.
27 struct Tokens {
28 Tokens() : error(GoogleServiceAuthError::None()) {}
29 GoogleServiceAuthError error;
30 std::string refresh_token;
31 std::string access_token;
32 base::Time expiration_date;
33 };
34
35 // Callback from the UI thread to the thread the request is made on.
36 typedef base::Callback<void(Tokens)> RequestCallbackType;
37
38 class OAuth2TokenService::RequestImpl : public CancelableRequestConsumer,
39 public OAuth2TokenService::Request,
40 public OAuth2AccessTokenConsumer {
41 public:
42 RequestImpl(Profile* profile,
43 net::URLRequestContextGetter* getter,
44 const std::set<std::string>& scopes,
45 OAuth2AccessTokenConsumer* consumer);
46
47 virtual ~RequestImpl();
48
49 // OAuth2AccessTokenConsumer implemenation;
50 virtual void OnGetTokenSuccess(const std::string& access_token,
51 const base::Time& expiration_date) OVERRIDE;
52 virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
53
54 private:
55 friend class OAuth2TokenService;
56
57 // This method is called on the UI thread so that it can access the profile
58 // services and retrieve the tokens needed to solve or execute the request.
59 static void GetTokens(CancelableRequest<RequestCallbackType>* request,
60 Profile* profile,
61 std::set<std::string> scopes);
62
63 // Register an entry in the cache of the OAuth2TokenService associated to
64 // |profile|.
65 static void RegisterCacheEntry(Profile* profile,
66 const std::set<std::string>& scopes,
67 const std::string& access_token,
68 const base::Time& expiration_date);
69
70 // Callback on the request thread with the tokens needed to do the request.
71 void FetchWithTokens(Tokens tokens);
72
73 Profile* profile_;
74 scoped_refptr<net::URLRequestContextGetter> getter_;
75 std::set<std::string> scopes_;
76 OAuth2AccessTokenConsumer* consumer_;
77 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_;
78
79 DISALLOW_COPY_AND_ASSIGN(RequestImpl);
80 };
81
82 OAuth2TokenService::OAuth2TokenService() {
83 }
84
85 OAuth2TokenService::~OAuth2TokenService() {
86 }
87
88 void OAuth2TokenService::Initialize(Profile* profile) {
89 DCHECK(profile);
90 profile_ = profile;
91 getter_ = profile->GetRequestContext();
92 content::Source<TokenService> token_service_source(
93 TokenServiceFactory::GetForProfile(profile));
94 registrar_.Add(this,
95 chrome::NOTIFICATION_TOKENS_CLEARED,
96 token_service_source);
97 registrar_.Add(this,
98 chrome::NOTIFICATION_TOKEN_AVAILABLE,
99 token_service_source);
100 registrar_.Add(this,
101 chrome::NOTIFICATION_TOKEN_LOADING_FINISHED,
102 token_service_source);
103 }
104
105 OAuth2TokenService::Request* OAuth2TokenService::StartRequest(
106 const std::vector<std::string>& scopes,
107 OAuth2AccessTokenConsumer* consumer) {
108 std::set<std::string> scopes_set(scopes.begin(), scopes.end());
109 RequestImpl* request =
110 new RequestImpl(profile_, getter_, scopes_set, consumer);
111 scoped_refptr<CancelableRequest<RequestCallbackType> > cancellable_request(
112 new CancelableRequest<RequestCallbackType>(
113 base::Bind(&RequestImpl::FetchWithTokens,
114 base::Unretained(request))));
115 AddRequest(cancellable_request, request);
116 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
117 RequestImpl::GetTokens(cancellable_request, profile_, scopes_set);
118 } else {
119 BrowserThread::PostTask(BrowserThread::UI,
120 FROM_HERE,
121 base::Bind(&RequestImpl::GetTokens,
122 cancellable_request,
123 profile_,
124 scopes_set));
125 }
126 return request;
127 }
128
129 void OAuth2TokenService::ClearCache() {
130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
131 tokens_cache_.clear();
132 }
133
134 OAuth2TokenService::CacheEntry const* OAuth2TokenService::GetCacheEntry(
135 const std::set<std::string>& scopes) {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137 TokensCache::iterator token_iterator = tokens_cache_.find(scopes);
138 if (token_iterator == tokens_cache_.end())
139 return NULL;
140 if (token_iterator->second.expiration_date <= base::Time::Now()) {
141 tokens_cache_.erase(token_iterator);
142 return NULL;
143 }
144 return &token_iterator->second;
145 }
146
147 void OAuth2TokenService::RegisterCacheEntry(
148 const std::set<std::string>& scopes,
149 const std::string& access_token,
150 const base::Time& expiration_date) {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152 CacheEntry& token = tokens_cache_[scopes];
153 token.access_token = access_token;
154 token.expiration_date = expiration_date;
155 }
156
157 void OAuth2TokenService::Observe(int type,
158 const content::NotificationSource& source,
159 const content::NotificationDetails& details) {
160 DCHECK(type == chrome::NOTIFICATION_TOKENS_CLEARED ||
161 type == chrome::NOTIFICATION_TOKEN_AVAILABLE ||
162 type == chrome::NOTIFICATION_TOKEN_LOADING_FINISHED);
163 if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) {
164 TokenService::TokenAvailableDetails* tok_details =
165 content::Details<TokenService::TokenAvailableDetails>(details).ptr();
166 if (tok_details->service() != GaiaConstants::kGaiaOAuth2LoginRefreshToken)
167 return;
168 }
169 // The GaiaConstants::kGaiaOAuth2LoginRefreshToken token is used to create
170 // OAuth2 access tokens. If this token either changes or is cleared, any
171 // available tokens must be invalidated.
172 ClearCache();
173 }
174
175 OAuth2TokenService::RequestImpl::RequestImpl(
176 Profile* profile,
177 net::URLRequestContextGetter* getter,
178 const std::set<std::string>& scopes,
179 OAuth2AccessTokenConsumer* consumer)
180 : profile_(profile),
181 getter_(getter),
182 scopes_(scopes),
183 consumer_(consumer) {
184 }
185
186 OAuth2TokenService::RequestImpl::~RequestImpl() {
187 }
188
189 // static
190 void OAuth2TokenService::RequestImpl::GetTokens(
191 CancelableRequest<RequestCallbackType>* request,
192 Profile* profile,
193 std::set<std::string> scopes) {
194 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
195 if (request->canceled())
196 return;
197 Tokens tokens;
198 TokenService* token_service = TokenServiceFactory::GetForProfile(profile);
199 if (!token_service || !token_service->HasOAuthLoginToken()) {
200 tokens.error =
201 GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP);
202 } else {
203 OAuth2TokenService* oauth2_token_service =
204 OAuth2TokenServiceFactory::GetForProfile(profile);
205 DCHECK(oauth2_token_service);
206 CacheEntry const* cache_entry = oauth2_token_service->GetCacheEntry(scopes);
207 if (cache_entry) {
208 tokens.access_token = cache_entry->access_token;
209 tokens.expiration_date = cache_entry->expiration_date;
210 } else {
211 tokens.refresh_token = token_service->GetOAuth2LoginRefreshToken();
212 }
213 }
214 request->ForwardResult(tokens);
215 }
216
217 // static
218 void OAuth2TokenService::RequestImpl::RegisterCacheEntry(
219 Profile* profile,
220 const std::set<std::string>& scopes,
221 const std::string& access_token,
222 const base::Time& expiration_date) {
223 OAuth2TokenService* oauth2_token_service =
224 OAuth2TokenServiceFactory::GetForProfile(profile);
225 if (!oauth2_token_service)
226 return;
227 oauth2_token_service->RegisterCacheEntry(scopes,
228 access_token,
229 expiration_date);
230 }
231
232 void OAuth2TokenService::RequestImpl::OnGetTokenSuccess(
233 const std::string& access_token,
234 const base::Time& expiration_date) {
235 fetcher_.reset();
236 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
237 OAuth2TokenService* oauth2_token_service =
238 OAuth2TokenServiceFactory::GetForProfile(profile_);
239 if (oauth2_token_service) {
240 oauth2_token_service->RegisterCacheEntry(scopes_,
241 access_token,
242 expiration_date);
243 }
244 } else {
245 BrowserThread::PostTask(
246 BrowserThread::UI,
247 FROM_HERE,
248 base::Bind(&OAuth2TokenService::RequestImpl::RegisterCacheEntry,
249 base::Unretained(profile_),
250 scopes_,
251 access_token,
252 expiration_date));
253 }
254 consumer_->OnGetTokenSuccess(access_token, expiration_date);
255 }
256
257 void OAuth2TokenService::RequestImpl::OnGetTokenFailure(
258 const GoogleServiceAuthError& error) {
259 fetcher_.reset();
260 consumer_->OnGetTokenFailure(error);
261 }
262
263 void OAuth2TokenService::RequestImpl::FetchWithTokens(Tokens tokens) {
264 if (tokens.error.state() != GoogleServiceAuthError::NONE) {
265 consumer_->OnGetTokenFailure(tokens.error);
266 return;
267 }
268 if (tokens.access_token.length()) {
269 consumer_->OnGetTokenSuccess(tokens.access_token, tokens.expiration_date);
270 return;
271 }
272 DCHECK(tokens.refresh_token.length());
273 fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_));
274 fetcher_->Start(GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
275 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
276 tokens.refresh_token,
277 std::vector<std::string>(scopes_.begin(), scopes_.end()));
278 }
OLDNEW
« no previous file with comments | « chrome/browser/signin/oauth2_token_service.h ('k') | chrome/browser/signin/oauth2_token_service_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698