Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / chrome / service / cloud_print / cloud_print_auth.cc
blobb52ba0cabb9f1fafc35b733224f751a5c61a2819
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.
5 #include "chrome/service/cloud_print/cloud_print_auth.h"
7 #include "base/bind.h"
8 #include "base/metrics/histogram.h"
9 #include "base/strings/string_util.h"
10 #include "chrome/common/cloud_print/cloud_print_constants.h"
11 #include "chrome/common/cloud_print/cloud_print_helpers.h"
12 #include "chrome/service/cloud_print/cloud_print_token_store.h"
13 #include "chrome/service/net/service_url_request_context_getter.h"
14 #include "chrome/service/service_process.h"
15 #include "google_apis/gaia/gaia_urls.h"
17 namespace cloud_print {
19 namespace {
21 enum CloudPrintAuthEvent {
22 AUTH_EVENT_ROBO_CREATE,
23 AUTH_EVENT_ROBO_SUCCEEDED,
24 AUTH_EVENT_ROBO_FAILED,
25 AUTH_EVENT_ROBO_JSON_ERROR,
26 AUTH_EVENT_ROBO_AUTH_ERROR,
27 AUTH_EVENT_AUTH_WITH_TOKEN,
28 AUTH_EVENT_AUTH_WITH_CODE,
29 AUTH_EVENT_TOKEN_RESPONSE,
30 AUTH_EVENT_REFRESH_REQUEST,
31 AUTH_EVENT_REFRESH_RESPONSE,
32 AUTH_EVENT_AUTH_ERROR,
33 AUTH_EVENT_NET_ERROR,
34 AUTH_EVENT_MAX
37 } // namespace
39 CloudPrintAuth::CloudPrintAuth(
40 Client* client,
41 const GURL& cloud_print_server_url,
42 const gaia::OAuthClientInfo& oauth_client_info,
43 const std::string& proxy_id)
44 : client_(client),
45 oauth_client_info_(oauth_client_info),
46 cloud_print_server_url_(cloud_print_server_url),
47 proxy_id_(proxy_id) {
48 DCHECK(client);
51 void CloudPrintAuth::AuthenticateWithToken(
52 const std::string& cloud_print_token) {
53 VLOG(1) << "CP_AUTH: Authenticating with token";
55 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_ROBO_CREATE,
56 AUTH_EVENT_MAX);
58 client_login_token_ = cloud_print_token;
60 // We need to get the credentials of the robot here.
61 GURL get_authcode_url = GetUrlForGetAuthCode(cloud_print_server_url_,
62 oauth_client_info_.client_id,
63 proxy_id_);
64 request_ = CloudPrintURLFetcher::Create();
65 request_->StartGetRequest(CloudPrintURLFetcher::REQUEST_AUTH_CODE,
66 get_authcode_url, this,
67 kCloudPrintAuthMaxRetryCount, std::string());
70 void CloudPrintAuth::AuthenticateWithRobotToken(
71 const std::string& robot_oauth_refresh_token,
72 const std::string& robot_email) {
73 VLOG(1) << "CP_AUTH: Authenticating with robot token";
75 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_AUTH_WITH_TOKEN,
76 AUTH_EVENT_MAX);
78 robot_email_ = robot_email;
79 refresh_token_ = robot_oauth_refresh_token;
80 RefreshAccessToken();
83 void CloudPrintAuth::AuthenticateWithRobotAuthCode(
84 const std::string& robot_oauth_auth_code,
85 const std::string& robot_email) {
86 VLOG(1) << "CP_AUTH: Authenticating with robot auth code";
88 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_AUTH_WITH_CODE,
89 AUTH_EVENT_MAX);
91 robot_email_ = robot_email;
92 // Now that we have an auth code we need to get the refresh and access tokens.
93 oauth_client_.reset(new gaia::GaiaOAuthClient(
94 g_service_process->GetServiceURLRequestContextGetter()));
95 oauth_client_->GetTokensFromAuthCode(oauth_client_info_,
96 robot_oauth_auth_code,
97 kCloudPrintAuthMaxRetryCount,
98 this);
101 void CloudPrintAuth::RefreshAccessToken() {
102 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_REFRESH_REQUEST,
103 AUTH_EVENT_MAX);
104 oauth_client_.reset(new gaia::GaiaOAuthClient(
105 g_service_process->GetServiceURLRequestContextGetter()));
106 std::vector<std::string> empty_scope_list; // (Use scope from refresh token.)
107 oauth_client_->RefreshToken(oauth_client_info_,
108 refresh_token_,
109 empty_scope_list,
110 kCloudPrintAuthMaxRetryCount,
111 this);
114 void CloudPrintAuth::OnGetTokensResponse(const std::string& refresh_token,
115 const std::string& access_token,
116 int expires_in_seconds) {
117 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_TOKEN_RESPONSE,
118 AUTH_EVENT_MAX);
119 refresh_token_ = refresh_token;
120 // After saving the refresh token, this is just like having just refreshed
121 // the access token. Just call OnRefreshTokenResponse.
122 OnRefreshTokenResponse(access_token, expires_in_seconds);
125 void CloudPrintAuth::OnRefreshTokenResponse(const std::string& access_token,
126 int expires_in_seconds) {
127 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_REFRESH_RESPONSE,
128 AUTH_EVENT_MAX);
129 client_->OnAuthenticationComplete(access_token, refresh_token_,
130 robot_email_, user_email_);
132 // Schedule a task to refresh the access token again when it is about to
133 // expire.
134 DCHECK(expires_in_seconds > kTokenRefreshGracePeriodSecs);
135 base::TimeDelta refresh_delay = base::TimeDelta::FromSeconds(
136 expires_in_seconds - kTokenRefreshGracePeriodSecs);
137 base::MessageLoop::current()->PostDelayedTask(
138 FROM_HERE,
139 base::Bind(&CloudPrintAuth::RefreshAccessToken, this),
140 refresh_delay);
143 void CloudPrintAuth::OnOAuthError() {
144 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_AUTH_ERROR,
145 AUTH_EVENT_MAX);
146 // Notify client about authentication error.
147 client_->OnInvalidCredentials();
150 void CloudPrintAuth::OnNetworkError(int response_code) {
151 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent", AUTH_EVENT_NET_ERROR,
152 AUTH_EVENT_MAX);
153 // Since we specify infinite retries on network errors, this should never
154 // be called.
155 NOTREACHED() <<
156 "OnNetworkError invoked when not expected, response code is " <<
157 response_code;
160 CloudPrintURLFetcher::ResponseAction CloudPrintAuth::HandleJSONData(
161 const net::URLFetcher* source,
162 const GURL& url,
163 base::DictionaryValue* json_data,
164 bool succeeded) {
165 if (!succeeded) {
166 VLOG(1) << "CP_AUTH: Creating robot account failed";
167 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent",
168 AUTH_EVENT_ROBO_FAILED,
169 AUTH_EVENT_MAX);
170 client_->OnInvalidCredentials();
171 return CloudPrintURLFetcher::STOP_PROCESSING;
174 std::string auth_code;
175 if (!json_data->GetString(kOAuthCodeValue, &auth_code)) {
176 VLOG(1) << "CP_AUTH: Creating robot account returned invalid json response";
177 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent",
178 AUTH_EVENT_ROBO_JSON_ERROR,
179 AUTH_EVENT_MAX);
180 client_->OnInvalidCredentials();
181 return CloudPrintURLFetcher::STOP_PROCESSING;
184 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent",
185 AUTH_EVENT_ROBO_SUCCEEDED,
186 AUTH_EVENT_MAX);
188 json_data->GetString(kXMPPJidValue, &robot_email_);
189 // Now that we have an auth code we need to get the refresh and access tokens.
190 oauth_client_.reset(new gaia::GaiaOAuthClient(
191 g_service_process->GetServiceURLRequestContextGetter()));
192 oauth_client_->GetTokensFromAuthCode(oauth_client_info_,
193 auth_code,
194 kCloudPrintAPIMaxRetryCount,
195 this);
197 return CloudPrintURLFetcher::STOP_PROCESSING;
200 CloudPrintURLFetcher::ResponseAction CloudPrintAuth::OnRequestAuthError() {
201 VLOG(1) << "CP_AUTH: Creating robot account authentication error";
203 UMA_HISTOGRAM_ENUMERATION("CloudPrint.AuthEvent",
204 AUTH_EVENT_ROBO_AUTH_ERROR,
205 AUTH_EVENT_MAX);
207 // Notify client about authentication error.
208 client_->OnInvalidCredentials();
209 return CloudPrintURLFetcher::STOP_PROCESSING;
212 std::string CloudPrintAuth::GetAuthHeader() {
213 DCHECK(!client_login_token_.empty());
214 std::string header;
215 header = "Authorization: GoogleLogin auth=";
216 header += client_login_token_;
217 return header;
220 CloudPrintAuth::~CloudPrintAuth() {}
222 } // namespace cloud_print