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

Side by Side Diff: remoting/host/oauth_token_getter.cc

Issue 141063009: Separate access token caching logic from signaling connector. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months 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.
Sergey Ulanov 2014/02/08 03:16:36 ditto
rmsousa 2014/02/10 23:07:39 Done.
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 "remoting/host/oauth_token_getter.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/strings/string_util.h"
10 #include "google_apis/google_api_keys.h"
11 #include "net/url_request/url_request_context_getter.h"
12 #include "remoting/base/logging.h"
13
14 namespace remoting {
15
16 namespace {
17
18 // Maximum number of retries on network/500 errors.
19 const int kMaxRetries = 3;
20
21 // Time when we we try to update OAuth token before its expiration.
22 const int kTokenUpdateTimeBeforeExpirySeconds = 60;
23
24 } // namespace
25
26 OAuthTokenGetter::OAuthCredentials::OAuthCredentials(
27 const std::string& login_value,
Sergey Ulanov 2014/02/08 03:16:36 remove _value suffix for this and the next field o
rmsousa 2014/02/10 23:07:39 Done.
28 const std::string& refresh_token_value,
29 bool is_service_account)
30 : login(login_value),
31 refresh_token(refresh_token_value),
32 is_service_account(is_service_account) {
33 }
34
35 OAuthTokenGetter::Callbacks::Callbacks(const TokenCallback& on_access_token,
36 const base::Closure& on_network_error,
37 const base::Closure& on_auth_error)
38 : on_access_token(on_access_token),
39 on_network_error(on_network_error),
40 on_auth_error(on_auth_error) {
41 }
42
43 OAuthTokenGetter::Callbacks::~Callbacks() {
44 }
Sergey Ulanov 2014/02/08 03:16:36 nit: } can be moved to the previous line.
rmsousa 2014/02/10 23:07:39 Class removed
45
46 OAuthTokenGetter::OAuthTokenGetter(
47 scoped_ptr<OAuthCredentials> oauth_credentials,
48 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter)
49 : oauth_credentials_(oauth_credentials.Pass()),
50 gaia_oauth_client_(
51 new gaia::GaiaOAuthClient(url_request_context_getter)),
52 url_request_context_getter_(url_request_context_getter),
53 refreshing_oauth_token_(false) {
54 }
55
56 OAuthTokenGetter::~OAuthTokenGetter() {
57 }
Sergey Ulanov 2014/02/08 03:16:36 same here
rmsousa 2014/02/10 23:07:39 Done.
58
59 void OAuthTokenGetter::OnGetTokensResponse(const std::string& user_email,
60 const std::string& access_token,
61 int expires_seconds) {
62 NOTREACHED();
63 }
64
65 void OAuthTokenGetter::OnRefreshTokenResponse(
66 const std::string& access_token,
67 int expires_seconds) {
68 DCHECK(CalledOnValidThread());
69 DCHECK(oauth_credentials_.get());
70 HOST_LOG << "Received OAuth token.";
71
72 oauth_access_token_ = access_token;
73 auth_token_expiry_time_ = base::Time::Now() +
74 base::TimeDelta::FromSeconds(expires_seconds) -
75 base::TimeDelta::FromSeconds(kTokenUpdateTimeBeforeExpirySeconds);
76
77 gaia_oauth_client_->GetUserEmail(access_token, kMaxRetries, this);
78 }
79
80 void OAuthTokenGetter::OnGetUserEmailResponse(const std::string& user_email) {
81 DCHECK(CalledOnValidThread());
82 DCHECK(oauth_credentials_.get());
83 HOST_LOG << "Received user info.";
84
85 if (user_email != oauth_credentials_->login) {
86 LOG(ERROR) << "OAuth token and email address do not refer to "
87 "the same account.";
88 OnOAuthError();
89 return;
90 }
91
92 refreshing_oauth_token_ = false;
93
94 // Now that we've refreshed the token and verified that it's for the correct
95 // user account, try to connect using the new token.
96 while (!pending_callbacks_.empty()) {
97 Callbacks callbacks = pending_callbacks_.front();
98 pending_callbacks_.pop();
99 callbacks.on_access_token.Run(user_email, oauth_access_token_);
Sergey Ulanov 2014/02/08 03:16:36 Each callback handler may call this class again an
rmsousa 2014/02/10 23:07:39 Good point. Done.
100 }
101 }
102
103 void OAuthTokenGetter::OnOAuthError() {
104 DCHECK(CalledOnValidThread());
105 LOG(ERROR) << "OAuth: invalid credentials.";
106 refreshing_oauth_token_ = false;
107 while (!pending_callbacks_.empty()) {
Sergey Ulanov 2014/02/08 03:16:36 If you use single callback for all results then th
rmsousa 2014/02/10 23:07:39 Done.
108 Callbacks callbacks = pending_callbacks_.front();
109 pending_callbacks_.pop();
110 callbacks.on_auth_error.Run();
111 }
112 }
113
114 void OAuthTokenGetter::OnNetworkError(int response_code) {
115 DCHECK(CalledOnValidThread());
116 LOG(ERROR) << "Network error when trying to update OAuth token: "
117 << response_code;
118 refreshing_oauth_token_ = false;
119 while (!pending_callbacks_.empty()) {
120 Callbacks callbacks = pending_callbacks_.front();
121 pending_callbacks_.pop();
122 callbacks.on_network_error.Run();
123 }
124 }
125
126 void OAuthTokenGetter::CallWithToken(const TokenCallback& on_access_token,
127 const base::Closure& on_network_error,
128 const base::Closure& on_auth_error) {
129 DCHECK(CalledOnValidThread());
130 bool need_new_auth_token = oauth_credentials_.get() &&
131 (auth_token_expiry_time_.is_null() ||
132 base::Time::Now() >= auth_token_expiry_time_);
133 if (need_new_auth_token) {
134 pending_callbacks_.push(
135 Callbacks(on_access_token, on_network_error, on_auth_error));
136 if (!refreshing_oauth_token_)
137 RefreshOAuthToken();
138 } else {
139 on_access_token.Run(oauth_credentials_->login, oauth_access_token_);
140 }
141 }
142
143 void OAuthTokenGetter::RefreshOAuthToken() {
144 DCHECK(CalledOnValidThread());
145 HOST_LOG << "Refreshing OAuth token.";
146 DCHECK(!refreshing_oauth_token_);
147
148 // Service accounts use different API keys, as they use the client app flow.
149 google_apis::OAuth2Client oauth2_client;
150 if (oauth_credentials_->is_service_account) {
151 oauth2_client = google_apis::CLIENT_REMOTING_HOST;
152 } else {
153 oauth2_client = google_apis::CLIENT_REMOTING;
154 }
155
156 gaia::OAuthClientInfo client_info = {
157 google_apis::GetOAuth2ClientID(oauth2_client),
158 google_apis::GetOAuth2ClientSecret(oauth2_client),
159 // Redirect URL is only used when getting tokens from auth code. It
160 // is not required when getting access tokens.
161 ""
162 };
163
164 refreshing_oauth_token_ = true;
165 std::vector<std::string> empty_scope_list; // (Use scope from refresh token.)
Sergey Ulanov 2014/02/08 03:16:36 nit: remove parentheses
rmsousa 2014/02/10 23:07:39 Done.
166 gaia_oauth_client_->RefreshToken(
167 client_info, oauth_credentials_->refresh_token, empty_scope_list,
168 kMaxRetries, this);
169 }
170
171 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698