Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / google_apis / gaia / google_service_auth_error.cc
blob76f4122a6aa1b55daeb2c0aa5e20d5908bed439c
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 "google_apis/gaia/google_service_auth_error.h"
7 #include <string>
9 #include "base/json/json_reader.h"
10 #include "base/logging.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/values.h"
14 #include "net/base/net_errors.h"
16 GoogleServiceAuthError::Captcha::Captcha() : image_width(0), image_height(0) {
19 GoogleServiceAuthError::Captcha::Captcha(
20 const std::string& token, const GURL& audio, const GURL& img,
21 const GURL& unlock, int width, int height)
22 : token(token), audio_url(audio), image_url(img), unlock_url(unlock),
23 image_width(width), image_height(height) {
26 GoogleServiceAuthError::Captcha::~Captcha() {
29 bool GoogleServiceAuthError::Captcha::operator==(const Captcha& b) const {
30 return (token == b.token &&
31 audio_url == b.audio_url &&
32 image_url == b.image_url &&
33 unlock_url == b.unlock_url &&
34 image_width == b.image_width &&
35 image_height == b.image_height);
38 GoogleServiceAuthError::SecondFactor::SecondFactor() : field_length(0) {
41 GoogleServiceAuthError::SecondFactor::SecondFactor(
42 const std::string& token, const std::string& prompt,
43 const std::string& alternate, int length)
44 : token(token), prompt_text(prompt), alternate_text(alternate),
45 field_length(length) {
48 GoogleServiceAuthError::SecondFactor::~SecondFactor() {
51 bool GoogleServiceAuthError::SecondFactor::operator==(
52 const SecondFactor& b) const {
53 return (token == b.token &&
54 prompt_text == b.prompt_text &&
55 alternate_text == b.alternate_text &&
56 field_length == b.field_length);
59 bool GoogleServiceAuthError::operator==(
60 const GoogleServiceAuthError& b) const {
61 return (state_ == b.state_ &&
62 network_error_ == b.network_error_ &&
63 captcha_ == b.captcha_ &&
64 second_factor_ == b.second_factor_);
67 bool GoogleServiceAuthError::operator!=(
68 const GoogleServiceAuthError& b) const {
69 return !(*this == b);
72 GoogleServiceAuthError::GoogleServiceAuthError(State s)
73 : state_(s),
74 network_error_(0) {
75 // If the caller has no idea, then we just set it to a generic failure.
76 if (s == CONNECTION_FAILED) {
77 network_error_ = net::ERR_FAILED;
81 GoogleServiceAuthError::GoogleServiceAuthError(
82 State state,
83 const std::string& error_message)
84 : state_(state),
85 network_error_(0),
86 error_message_(error_message) {
89 // static
90 GoogleServiceAuthError
91 GoogleServiceAuthError::FromConnectionError(int error) {
92 return GoogleServiceAuthError(CONNECTION_FAILED, error);
95 // static
96 GoogleServiceAuthError GoogleServiceAuthError::FromClientLoginCaptchaChallenge(
97 const std::string& captcha_token,
98 const GURL& captcha_image_url,
99 const GURL& captcha_unlock_url) {
100 return GoogleServiceAuthError(CAPTCHA_REQUIRED, captcha_token, GURL(),
101 captcha_image_url, captcha_unlock_url, 0, 0);
104 // static
105 GoogleServiceAuthError GoogleServiceAuthError::FromServiceError(
106 const std::string& error_message) {
107 return GoogleServiceAuthError(SERVICE_ERROR, error_message);
110 // static
111 GoogleServiceAuthError GoogleServiceAuthError::FromUnexpectedServiceResponse(
112 const std::string& error_message) {
113 return GoogleServiceAuthError(UNEXPECTED_SERVICE_RESPONSE, error_message);
116 // static
117 GoogleServiceAuthError GoogleServiceAuthError::AuthErrorNone() {
118 return GoogleServiceAuthError(NONE);
121 GoogleServiceAuthError::State GoogleServiceAuthError::state() const {
122 return state_;
125 const GoogleServiceAuthError::Captcha& GoogleServiceAuthError::captcha() const {
126 return captcha_;
129 const GoogleServiceAuthError::SecondFactor&
130 GoogleServiceAuthError::second_factor() const {
131 return second_factor_;
134 int GoogleServiceAuthError::network_error() const {
135 return network_error_;
138 const std::string& GoogleServiceAuthError::token() const {
139 switch (state_) {
140 case CAPTCHA_REQUIRED:
141 return captcha_.token;
142 break;
143 case TWO_FACTOR:
144 return second_factor_.token;
145 break;
146 default:
147 NOTREACHED();
149 return base::EmptyString();
152 const std::string& GoogleServiceAuthError::error_message() const {
153 return error_message_;
156 base::DictionaryValue* GoogleServiceAuthError::ToValue() const {
157 base::DictionaryValue* value = new base::DictionaryValue();
158 std::string state_str;
159 switch (state_) {
160 #define STATE_CASE(x) case x: state_str = #x; break
161 STATE_CASE(NONE);
162 STATE_CASE(INVALID_GAIA_CREDENTIALS);
163 STATE_CASE(USER_NOT_SIGNED_UP);
164 STATE_CASE(CONNECTION_FAILED);
165 STATE_CASE(CAPTCHA_REQUIRED);
166 STATE_CASE(ACCOUNT_DELETED);
167 STATE_CASE(ACCOUNT_DISABLED);
168 STATE_CASE(SERVICE_UNAVAILABLE);
169 STATE_CASE(TWO_FACTOR);
170 STATE_CASE(REQUEST_CANCELED);
171 STATE_CASE(HOSTED_NOT_ALLOWED);
172 STATE_CASE(UNEXPECTED_SERVICE_RESPONSE);
173 STATE_CASE(SERVICE_ERROR);
174 STATE_CASE(WEB_LOGIN_REQUIRED);
175 #undef STATE_CASE
176 default:
177 NOTREACHED();
178 break;
180 value->SetString("state", state_str);
181 if (!error_message_.empty()) {
182 value->SetString("errorMessage", error_message_);
184 if (state_ == CAPTCHA_REQUIRED) {
185 base::DictionaryValue* captcha_value = new base::DictionaryValue();
186 value->Set("captcha", captcha_value);
187 captcha_value->SetString("token", captcha_.token);
188 captcha_value->SetString("audioUrl", captcha_.audio_url.spec());
189 captcha_value->SetString("imageUrl", captcha_.image_url.spec());
190 captcha_value->SetString("unlockUrl", captcha_.unlock_url.spec());
191 captcha_value->SetInteger("imageWidth", captcha_.image_width);
192 captcha_value->SetInteger("imageHeight", captcha_.image_height);
193 } else if (state_ == CONNECTION_FAILED) {
194 value->SetString("networkError", net::ErrorToString(network_error_));
195 } else if (state_ == TWO_FACTOR) {
196 base::DictionaryValue* two_factor_value = new base::DictionaryValue();
197 value->Set("two_factor", two_factor_value);
198 two_factor_value->SetString("token", second_factor_.token);
199 two_factor_value->SetString("promptText", second_factor_.prompt_text);
200 two_factor_value->SetString("alternateText", second_factor_.alternate_text);
201 two_factor_value->SetInteger("fieldLength", second_factor_.field_length);
203 return value;
206 std::string GoogleServiceAuthError::ToString() const {
207 switch (state_) {
208 case NONE:
209 return std::string();
210 case INVALID_GAIA_CREDENTIALS:
211 return "Invalid credentials.";
212 case USER_NOT_SIGNED_UP:
213 return "Not authorized.";
214 case CONNECTION_FAILED:
215 return base::StringPrintf("Connection failed (%d).", network_error_);
216 case CAPTCHA_REQUIRED:
217 return base::StringPrintf("CAPTCHA required (%s).",
218 captcha_.token.c_str());
219 case ACCOUNT_DELETED:
220 return "Account deleted.";
221 case ACCOUNT_DISABLED:
222 return "Account disabled.";
223 case SERVICE_UNAVAILABLE:
224 return "Service unavailable; try again later.";
225 case TWO_FACTOR:
226 return base::StringPrintf("2-step verification required (%s).",
227 second_factor_.token.c_str());
228 case REQUEST_CANCELED:
229 return "Request canceled.";
230 case HOSTED_NOT_ALLOWED:
231 return "Google account required.";
232 case UNEXPECTED_SERVICE_RESPONSE:
233 return base::StringPrintf("Unexpected service response (%s)",
234 error_message_.c_str());
235 case SERVICE_ERROR:
236 return base::StringPrintf("Service responded with error: '%s'",
237 error_message_.c_str());
238 case WEB_LOGIN_REQUIRED:
239 return "Less secure apps may not authenticate with this account. "
240 "Please visit: "
241 "https://www.google.com/settings/security/lesssecureapps";
242 default:
243 NOTREACHED();
244 return std::string();
248 bool GoogleServiceAuthError::IsPersistentError() const {
249 if (state_ == GoogleServiceAuthError::NONE) return false;
250 return !IsTransientError();
253 bool GoogleServiceAuthError::IsTransientError() const {
254 switch (state_) {
255 // These are failures that are likely to succeed if tried again.
256 case GoogleServiceAuthError::CONNECTION_FAILED:
257 case GoogleServiceAuthError::SERVICE_UNAVAILABLE:
258 case GoogleServiceAuthError::REQUEST_CANCELED:
259 return true;
260 // Everything else will have the same result.
261 default:
262 return false;
266 GoogleServiceAuthError::GoogleServiceAuthError(State s, int error)
267 : state_(s),
268 network_error_(error) {
271 GoogleServiceAuthError::GoogleServiceAuthError(
272 State s,
273 const std::string& captcha_token,
274 const GURL& captcha_audio_url,
275 const GURL& captcha_image_url,
276 const GURL& captcha_unlock_url,
277 int image_width,
278 int image_height)
279 : state_(s),
280 captcha_(captcha_token, captcha_audio_url, captcha_image_url,
281 captcha_unlock_url, image_width, image_height),
282 network_error_(0) {