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 "google_apis/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/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/values.h"
14 #include "net/base/net_errors.h"
15
Captcha()16 GoogleServiceAuthError::Captcha::Captcha() : image_width(0), image_height(0) {
17 }
18
Captcha(const std::string & token,const GURL & audio,const GURL & img,const GURL & unlock,int width,int height)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
~Captcha()26 GoogleServiceAuthError::Captcha::~Captcha() {
27 }
28
operator ==(const Captcha & b) const29 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
SecondFactor()38 GoogleServiceAuthError::SecondFactor::SecondFactor() : field_length(0) {
39 }
40
SecondFactor(const std::string & token,const std::string & prompt,const std::string & alternate,int length)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) {
46 }
47
~SecondFactor()48 GoogleServiceAuthError::SecondFactor::~SecondFactor() {
49 }
50
operator ==(const SecondFactor & b) const51 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);
57 }
58
operator ==(const GoogleServiceAuthError & b) const59 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_);
65 }
66
GoogleServiceAuthError(State s)67 GoogleServiceAuthError::GoogleServiceAuthError(State s)
68 : state_(s),
69 network_error_(0) {
70 // If the caller has no idea, then we just set it to a generic failure.
71 if (s == CONNECTION_FAILED) {
72 network_error_ = net::ERR_FAILED;
73 }
74 }
75
GoogleServiceAuthError(State state,const std::string & error_message)76 GoogleServiceAuthError::GoogleServiceAuthError(
77 State state,
78 const std::string& error_message)
79 : state_(state),
80 network_error_(0),
81 error_message_(error_message) {
82 }
83
84 // static
85 GoogleServiceAuthError
FromConnectionError(int error)86 GoogleServiceAuthError::FromConnectionError(int error) {
87 return GoogleServiceAuthError(CONNECTION_FAILED, error);
88 }
89
90 // static
FromClientLoginCaptchaChallenge(const std::string & captcha_token,const GURL & captcha_image_url,const GURL & captcha_unlock_url)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
FromServiceError(const std::string & error_message)100 GoogleServiceAuthError GoogleServiceAuthError::FromServiceError(
101 const std::string& error_message) {
102 return GoogleServiceAuthError(SERVICE_ERROR, error_message);
103 }
104
105 // static
FromUnexpectedServiceResponse(const std::string & error_message)106 GoogleServiceAuthError GoogleServiceAuthError::FromUnexpectedServiceResponse(
107 const std::string& error_message) {
108 return GoogleServiceAuthError(UNEXPECTED_SERVICE_RESPONSE, error_message);
109 }
110
111 // static
AuthErrorNone()112 GoogleServiceAuthError GoogleServiceAuthError::AuthErrorNone() {
113 return GoogleServiceAuthError(NONE);
114 }
115
state() const116 GoogleServiceAuthError::State GoogleServiceAuthError::state() const {
117 return state_;
118 }
119
captcha() const120 const GoogleServiceAuthError::Captcha& GoogleServiceAuthError::captcha() const {
121 return captcha_;
122 }
123
124 const GoogleServiceAuthError::SecondFactor&
second_factor() const125 GoogleServiceAuthError::second_factor() const {
126 return second_factor_;
127 }
128
network_error() const129 int GoogleServiceAuthError::network_error() const {
130 return network_error_;
131 }
132
token() const133 const std::string& GoogleServiceAuthError::token() const {
134 switch (state_) {
135 case CAPTCHA_REQUIRED:
136 return captcha_.token;
137 break;
138 case TWO_FACTOR:
139 return second_factor_.token;
140 break;
141 default:
142 NOTREACHED();
143 }
144 return base::EmptyString();
145 }
146
error_message() const147 const std::string& GoogleServiceAuthError::error_message() const {
148 return error_message_;
149 }
150
ToValue() const151 base::DictionaryValue* GoogleServiceAuthError::ToValue() const {
152 base::DictionaryValue* value = new base::DictionaryValue();
153 std::string state_str;
154 switch (state_) {
155 #define STATE_CASE(x) case x: state_str = #x; break
156 STATE_CASE(NONE);
157 STATE_CASE(INVALID_GAIA_CREDENTIALS);
158 STATE_CASE(USER_NOT_SIGNED_UP);
159 STATE_CASE(CONNECTION_FAILED);
160 STATE_CASE(CAPTCHA_REQUIRED);
161 STATE_CASE(ACCOUNT_DELETED);
162 STATE_CASE(ACCOUNT_DISABLED);
163 STATE_CASE(SERVICE_UNAVAILABLE);
164 STATE_CASE(TWO_FACTOR);
165 STATE_CASE(REQUEST_CANCELED);
166 STATE_CASE(HOSTED_NOT_ALLOWED);
167 STATE_CASE(UNEXPECTED_SERVICE_RESPONSE);
168 STATE_CASE(SERVICE_ERROR);
169 #undef STATE_CASE
170 default:
171 NOTREACHED();
172 break;
173 }
174 value->SetString("state", state_str);
175 if (!error_message_.empty()) {
176 value->SetString("errorMessage", error_message_);
177 }
178 if (state_ == CAPTCHA_REQUIRED) {
179 base::DictionaryValue* captcha_value = new base::DictionaryValue();
180 value->Set("captcha", captcha_value);
181 captcha_value->SetString("token", captcha_.token);
182 captcha_value->SetString("audioUrl", captcha_.audio_url.spec());
183 captcha_value->SetString("imageUrl", captcha_.image_url.spec());
184 captcha_value->SetString("unlockUrl", captcha_.unlock_url.spec());
185 captcha_value->SetInteger("imageWidth", captcha_.image_width);
186 captcha_value->SetInteger("imageHeight", captcha_.image_height);
187 } else if (state_ == CONNECTION_FAILED) {
188 value->SetString("networkError", net::ErrorToString(network_error_));
189 } else if (state_ == TWO_FACTOR) {
190 base::DictionaryValue* two_factor_value = new base::DictionaryValue();
191 value->Set("two_factor", two_factor_value);
192 two_factor_value->SetString("token", second_factor_.token);
193 two_factor_value->SetString("promptText", second_factor_.prompt_text);
194 two_factor_value->SetString("alternateText", second_factor_.alternate_text);
195 two_factor_value->SetInteger("fieldLength", second_factor_.field_length);
196 }
197 return value;
198 }
199
ToString() const200 std::string GoogleServiceAuthError::ToString() const {
201 switch (state_) {
202 case NONE:
203 return std::string();
204 case INVALID_GAIA_CREDENTIALS:
205 return "Invalid credentials.";
206 case USER_NOT_SIGNED_UP:
207 return "Not authorized.";
208 case CONNECTION_FAILED:
209 return base::StringPrintf("Connection failed (%d).", network_error_);
210 case CAPTCHA_REQUIRED:
211 return base::StringPrintf("CAPTCHA required (%s).",
212 captcha_.token.c_str());
213 case ACCOUNT_DELETED:
214 return "Account deleted.";
215 case ACCOUNT_DISABLED:
216 return "Account disabled.";
217 case SERVICE_UNAVAILABLE:
218 return "Service unavailable; try again later.";
219 case TWO_FACTOR:
220 return base::StringPrintf("2-step verification required (%s).",
221 second_factor_.token.c_str());
222 case REQUEST_CANCELED:
223 return "Request canceled.";
224 case HOSTED_NOT_ALLOWED:
225 return "Google account required.";
226 case UNEXPECTED_SERVICE_RESPONSE:
227 return base::StringPrintf("Unexpected service response (%s)",
228 error_message_.c_str());
229 case SERVICE_ERROR:
230 return base::StringPrintf("Service responded with error: '%s'",
231 error_message_.c_str());
232 default:
233 NOTREACHED();
234 return std::string();
235 }
236 }
237
GoogleServiceAuthError(State s,int error)238 GoogleServiceAuthError::GoogleServiceAuthError(State s, int error)
239 : state_(s),
240 network_error_(error) {
241 }
242
GoogleServiceAuthError(State s,const std::string & captcha_token,const GURL & captcha_audio_url,const GURL & captcha_image_url,const GURL & captcha_unlock_url,int image_width,int image_height)243 GoogleServiceAuthError::GoogleServiceAuthError(
244 State s,
245 const std::string& captcha_token,
246 const GURL& captcha_audio_url,
247 const GURL& captcha_image_url,
248 const GURL& captcha_unlock_url,
249 int image_width,
250 int image_height)
251 : state_(s),
252 captcha_(captcha_token, captcha_audio_url, captcha_image_url,
253 captcha_unlock_url, image_width, image_height),
254 network_error_(0) {
255 }
256