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"
9 #include "base/json/json_reader.h"
10 #include "base/logging.h"
11 #include "base/string_util.h"
12 #include "base/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
);
39 GoogleServiceAuthError::SecondFactor::SecondFactor() : field_length(0) {
42 GoogleServiceAuthError::SecondFactor::SecondFactor(
43 const std::string
& token
, const std::string
& prompt
,
44 const std::string
& alternate
, int length
)
45 : token(token
), prompt_text(prompt
), alternate_text(alternate
),
46 field_length(length
) {
49 GoogleServiceAuthError::SecondFactor::~SecondFactor() {
52 bool GoogleServiceAuthError::SecondFactor::operator==(
53 const SecondFactor
& b
) const {
54 return (token
== b
.token
&&
55 prompt_text
== b
.prompt_text
&&
56 alternate_text
== b
.alternate_text
&&
57 field_length
== b
.field_length
);
61 bool GoogleServiceAuthError::operator==(
62 const GoogleServiceAuthError
& b
) const {
63 return (state_
== b
.state_
&&
64 network_error_
== b
.network_error_
&&
65 captcha_
== b
.captcha_
&&
66 second_factor_
== b
.second_factor_
);
69 GoogleServiceAuthError::GoogleServiceAuthError(State s
)
72 // If the caller has no idea, then we just set it to a generic failure.
73 if (s
== CONNECTION_FAILED
) {
74 network_error_
= net::ERR_FAILED
;
78 GoogleServiceAuthError::GoogleServiceAuthError(const std::string
& error_message
)
79 : state_(INVALID_GAIA_CREDENTIALS
),
81 error_message_(error_message
) {
85 GoogleServiceAuthError
86 GoogleServiceAuthError::FromConnectionError(int error
) {
87 return GoogleServiceAuthError(CONNECTION_FAILED
, error
);
91 GoogleServiceAuthError
GoogleServiceAuthError::FromClientLoginCaptchaChallenge(
92 const std::string
& captcha_token
,
93 const GURL
& captcha_image_url
,
94 const GURL
& captcha_unlock_url
) {
95 return GoogleServiceAuthError(CAPTCHA_REQUIRED
, captcha_token
, GURL(),
96 captcha_image_url
, captcha_unlock_url
, 0, 0);
100 GoogleServiceAuthError
GoogleServiceAuthError::FromCaptchaChallenge(
101 const std::string
& captcha_token
,
102 const GURL
& captcha_audio_url
,
103 const GURL
& captcha_image_url
,
106 return GoogleServiceAuthError(CAPTCHA_REQUIRED
, captcha_token
,
107 captcha_audio_url
, captcha_image_url
,
108 GURL(), image_width
, image_height
);
112 GoogleServiceAuthError
GoogleServiceAuthError::FromSecondFactorChallenge(
113 const std::string
& captcha_token
,
114 const std::string
& prompt_text
,
115 const std::string
& alternate_text
,
117 return GoogleServiceAuthError(TWO_FACTOR
, captcha_token
, prompt_text
,
118 alternate_text
, field_length
);
122 GoogleServiceAuthError
GoogleServiceAuthError::FromClientOAuthError(
123 const std::string
& data
) {
124 scoped_ptr
<base::Value
> value(base::JSONReader::Read(data
));
125 if (!value
.get() || value
->GetType() != base::Value::TYPE_DICTIONARY
)
126 return GoogleServiceAuthError(CONNECTION_FAILED
, 0);
128 DictionaryValue
* dict
= static_cast<DictionaryValue
*>(value
.get());
131 if (!dict
->GetStringWithoutPathExpansion("cause", &cause
))
132 return GoogleServiceAuthError(CONNECTION_FAILED
, 0);
134 // The explanation field is optional.
135 std::string explanation
;
136 if (!dict
->GetStringWithoutPathExpansion("explanation", &explanation
))
139 return GoogleServiceAuthError(explanation
);
142 GoogleServiceAuthError
GoogleServiceAuthError::AuthErrorNone() {
143 return GoogleServiceAuthError(NONE
);
146 GoogleServiceAuthError::State
GoogleServiceAuthError::state() const {
150 const GoogleServiceAuthError::Captcha
& GoogleServiceAuthError::captcha() const {
154 const GoogleServiceAuthError::SecondFactor
&
155 GoogleServiceAuthError::second_factor() const {
156 return second_factor_
;
159 int GoogleServiceAuthError::network_error() const {
160 return network_error_
;
163 const std::string
& GoogleServiceAuthError::token() const {
165 case CAPTCHA_REQUIRED
:
166 return captcha_
.token
;
169 return second_factor_
.token
;
174 return EmptyString();
177 const std::string
& GoogleServiceAuthError::error_message() const {
178 return error_message_
;
181 DictionaryValue
* GoogleServiceAuthError::ToValue() const {
182 DictionaryValue
* value
= new DictionaryValue();
183 std::string state_str
;
185 #define STATE_CASE(x) case x: state_str = #x; break
187 STATE_CASE(INVALID_GAIA_CREDENTIALS
);
188 STATE_CASE(USER_NOT_SIGNED_UP
);
189 STATE_CASE(CONNECTION_FAILED
);
190 STATE_CASE(CAPTCHA_REQUIRED
);
191 STATE_CASE(ACCOUNT_DELETED
);
192 STATE_CASE(ACCOUNT_DISABLED
);
193 STATE_CASE(SERVICE_UNAVAILABLE
);
194 STATE_CASE(TWO_FACTOR
);
195 STATE_CASE(REQUEST_CANCELED
);
196 STATE_CASE(HOSTED_NOT_ALLOWED
);
202 value
->SetString("state", state_str
);
203 if (state_
== CAPTCHA_REQUIRED
) {
204 DictionaryValue
* captcha_value
= new DictionaryValue();
205 value
->Set("captcha", captcha_value
);
206 captcha_value
->SetString("token", captcha_
.token
);
207 captcha_value
->SetString("audioUrl", captcha_
.audio_url
.spec());
208 captcha_value
->SetString("imageUrl", captcha_
.image_url
.spec());
209 captcha_value
->SetString("unlockUrl", captcha_
.unlock_url
.spec());
210 captcha_value
->SetInteger("imageWidth", captcha_
.image_width
);
211 captcha_value
->SetInteger("imageHeight", captcha_
.image_height
);
212 } else if (state_
== CONNECTION_FAILED
) {
213 value
->SetString("networkError", net::ErrorToString(network_error_
));
214 } else if (state_
== TWO_FACTOR
) {
215 DictionaryValue
* two_factor_value
= new DictionaryValue();
216 value
->Set("two_factor", two_factor_value
);
217 two_factor_value
->SetString("token", second_factor_
.token
);
218 two_factor_value
->SetString("promptText", second_factor_
.prompt_text
);
219 two_factor_value
->SetString("alternateText", second_factor_
.alternate_text
);
220 two_factor_value
->SetInteger("fieldLength", second_factor_
.field_length
);
225 std::string
GoogleServiceAuthError::ToString() const {
228 return std::string();
229 case INVALID_GAIA_CREDENTIALS
:
230 return "Invalid credentials.";
231 case USER_NOT_SIGNED_UP
:
232 return "Not authorized.";
233 case CONNECTION_FAILED
:
234 return base::StringPrintf("Connection failed (%d).", network_error_
);
235 case CAPTCHA_REQUIRED
:
236 return base::StringPrintf("CAPTCHA required (%s).",
237 captcha_
.token
.c_str());
238 case ACCOUNT_DELETED
:
239 return "Account deleted.";
240 case ACCOUNT_DISABLED
:
241 return "Account disabled.";
242 case SERVICE_UNAVAILABLE
:
243 return "Service unavailable; try again later.";
245 return base::StringPrintf("2-step verification required (%s).",
246 second_factor_
.token
.c_str());
247 case REQUEST_CANCELED
:
248 return "Request canceled.";
249 case HOSTED_NOT_ALLOWED
:
250 return "Google account required.";
253 return std::string();
257 GoogleServiceAuthError::GoogleServiceAuthError(State s
, int error
)
259 network_error_(error
) {
262 GoogleServiceAuthError::GoogleServiceAuthError(
264 const std::string
& captcha_token
,
265 const GURL
& captcha_audio_url
,
266 const GURL
& captcha_image_url
,
267 const GURL
& captcha_unlock_url
,
271 captcha_(captcha_token
, captcha_audio_url
, captcha_image_url
,
272 captcha_unlock_url
, image_width
, image_height
),
276 GoogleServiceAuthError::GoogleServiceAuthError(
278 const std::string
& captcha_token
,
279 const std::string
& prompt_text
,
280 const std::string
& alternate_text
,
283 second_factor_(captcha_token
, prompt_text
, alternate_text
, field_length
),