OLD | NEW |
| (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/common/net/gaia/google_service_auth_error.h" | |
6 | |
7 #include <string> | |
8 | |
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" | |
15 | |
16 GoogleServiceAuthError::Captcha::Captcha() : image_width(0), image_height(0) { | |
17 } | |
18 | |
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) { | |
24 } | |
25 | |
26 GoogleServiceAuthError::Captcha::~Captcha() { | |
27 } | |
28 | |
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); | |
36 } | |
37 | |
38 | |
39 GoogleServiceAuthError::SecondFactor::SecondFactor() : field_length(0) { | |
40 } | |
41 | |
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) { | |
47 } | |
48 | |
49 GoogleServiceAuthError::SecondFactor::~SecondFactor() { | |
50 } | |
51 | |
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); | |
58 } | |
59 | |
60 | |
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_); | |
67 } | |
68 | |
69 GoogleServiceAuthError::GoogleServiceAuthError(State s) | |
70 : state_(s), | |
71 network_error_(0) { | |
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; | |
75 } | |
76 } | |
77 | |
78 GoogleServiceAuthError::GoogleServiceAuthError(const std::string& error_message) | |
79 : state_(INVALID_GAIA_CREDENTIALS), | |
80 network_error_(0), | |
81 error_message_(error_message) { | |
82 } | |
83 | |
84 // static | |
85 GoogleServiceAuthError | |
86 GoogleServiceAuthError::FromConnectionError(int error) { | |
87 return GoogleServiceAuthError(CONNECTION_FAILED, error); | |
88 } | |
89 | |
90 // static | |
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); | |
97 } | |
98 | |
99 // static | |
100 GoogleServiceAuthError GoogleServiceAuthError::FromCaptchaChallenge( | |
101 const std::string& captcha_token, | |
102 const GURL& captcha_audio_url, | |
103 const GURL& captcha_image_url, | |
104 int image_width, | |
105 int image_height) { | |
106 return GoogleServiceAuthError(CAPTCHA_REQUIRED, captcha_token, | |
107 captcha_audio_url, captcha_image_url, | |
108 GURL(), image_width, image_height); | |
109 } | |
110 | |
111 // static | |
112 GoogleServiceAuthError GoogleServiceAuthError::FromSecondFactorChallenge( | |
113 const std::string& captcha_token, | |
114 const std::string& prompt_text, | |
115 const std::string& alternate_text, | |
116 int field_length) { | |
117 return GoogleServiceAuthError(TWO_FACTOR, captcha_token, prompt_text, | |
118 alternate_text, field_length); | |
119 } | |
120 | |
121 // static | |
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); | |
127 | |
128 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); | |
129 | |
130 std::string cause; | |
131 if (!dict->GetStringWithoutPathExpansion("cause", &cause)) | |
132 return GoogleServiceAuthError(CONNECTION_FAILED, 0); | |
133 | |
134 // The explanation field is optional. | |
135 std::string explanation; | |
136 if (!dict->GetStringWithoutPathExpansion("explanation", &explanation)) | |
137 explanation.clear(); | |
138 | |
139 return GoogleServiceAuthError(explanation); | |
140 } | |
141 | |
142 GoogleServiceAuthError GoogleServiceAuthError::None() { | |
143 return GoogleServiceAuthError(NONE); | |
144 } | |
145 | |
146 GoogleServiceAuthError::State GoogleServiceAuthError::state() const { | |
147 return state_; | |
148 } | |
149 | |
150 const GoogleServiceAuthError::Captcha& GoogleServiceAuthError::captcha() const { | |
151 return captcha_; | |
152 } | |
153 | |
154 const GoogleServiceAuthError::SecondFactor& | |
155 GoogleServiceAuthError::second_factor() const { | |
156 return second_factor_; | |
157 } | |
158 | |
159 int GoogleServiceAuthError::network_error() const { | |
160 return network_error_; | |
161 } | |
162 | |
163 const std::string& GoogleServiceAuthError::token() const { | |
164 switch (state_) { | |
165 case CAPTCHA_REQUIRED: | |
166 return captcha_.token; | |
167 break; | |
168 case TWO_FACTOR: | |
169 return second_factor_.token; | |
170 break; | |
171 default: | |
172 NOTREACHED(); | |
173 } | |
174 return EmptyString(); | |
175 } | |
176 | |
177 const std::string& GoogleServiceAuthError::error_message() const { | |
178 return error_message_; | |
179 } | |
180 | |
181 DictionaryValue* GoogleServiceAuthError::ToValue() const { | |
182 DictionaryValue* value = new DictionaryValue(); | |
183 std::string state_str; | |
184 switch (state_) { | |
185 #define STATE_CASE(x) case x: state_str = #x; break | |
186 STATE_CASE(NONE); | |
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); | |
197 #undef STATE_CASE | |
198 default: | |
199 NOTREACHED(); | |
200 break; | |
201 } | |
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); | |
221 } | |
222 return value; | |
223 } | |
224 | |
225 std::string GoogleServiceAuthError::ToString() const { | |
226 switch (state_) { | |
227 case NONE: | |
228 return ""; | |
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."; | |
244 case TWO_FACTOR: | |
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."; | |
251 default: | |
252 NOTREACHED(); | |
253 return std::string(); | |
254 } | |
255 } | |
256 | |
257 GoogleServiceAuthError::GoogleServiceAuthError(State s, int error) | |
258 : state_(s), | |
259 network_error_(error) { | |
260 } | |
261 | |
262 GoogleServiceAuthError::GoogleServiceAuthError( | |
263 State s, | |
264 const std::string& captcha_token, | |
265 const GURL& captcha_audio_url, | |
266 const GURL& captcha_image_url, | |
267 const GURL& captcha_unlock_url, | |
268 int image_width, | |
269 int image_height) | |
270 : state_(s), | |
271 captcha_(captcha_token, captcha_audio_url, captcha_image_url, | |
272 captcha_unlock_url, image_width, image_height), | |
273 network_error_(0) { | |
274 } | |
275 | |
276 GoogleServiceAuthError::GoogleServiceAuthError( | |
277 State s, | |
278 const std::string& captcha_token, | |
279 const std::string& prompt_text, | |
280 const std::string& alternate_text, | |
281 int field_length) | |
282 : state_(s), | |
283 second_factor_(captcha_token, prompt_text, alternate_text, field_length), | |
284 network_error_(0) { | |
285 } | |
OLD | NEW |