google_service_auth_error.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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
16GoogleServiceAuthError::Captcha::Captcha() : image_width(0), image_height(0) {
17}
18
19GoogleServiceAuthError::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
26GoogleServiceAuthError::Captcha::~Captcha() {
27}
28
29bool 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
38GoogleServiceAuthError::SecondFactor::SecondFactor() : field_length(0) {
39}
40
41GoogleServiceAuthError::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
48GoogleServiceAuthError::SecondFactor::~SecondFactor() {
49}
50
51bool 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
59bool 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
67GoogleServiceAuthError::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
76GoogleServiceAuthError::GoogleServiceAuthError(
77    State state,
78    const std::string& error_message)
79    : state_(state),
80      network_error_(0),
81      error_message_(error_message) {
82}
83
84GoogleServiceAuthError::GoogleServiceAuthError(const std::string& error_message)
85    : state_(INVALID_GAIA_CREDENTIALS),
86      network_error_(0),
87      error_message_(error_message) {
88}
89
90// static
91GoogleServiceAuthError
92    GoogleServiceAuthError::FromConnectionError(int error) {
93  return GoogleServiceAuthError(CONNECTION_FAILED, error);
94}
95
96// static
97GoogleServiceAuthError GoogleServiceAuthError::FromClientLoginCaptchaChallenge(
98    const std::string& captcha_token,
99    const GURL& captcha_image_url,
100    const GURL& captcha_unlock_url) {
101  return GoogleServiceAuthError(CAPTCHA_REQUIRED, captcha_token, GURL(),
102                                captcha_image_url, captcha_unlock_url, 0, 0);
103}
104
105// static
106GoogleServiceAuthError GoogleServiceAuthError::FromServiceError(
107    const std::string& error_message) {
108  return GoogleServiceAuthError(SERVICE_ERROR, error_message);
109}
110
111// static
112GoogleServiceAuthError GoogleServiceAuthError::FromUnexpectedServiceResponse(
113    const std::string& error_message) {
114  return GoogleServiceAuthError(UNEXPECTED_SERVICE_RESPONSE, error_message);
115}
116
117// static
118GoogleServiceAuthError GoogleServiceAuthError::AuthErrorNone() {
119  return GoogleServiceAuthError(NONE);
120}
121
122GoogleServiceAuthError::State GoogleServiceAuthError::state() const {
123  return state_;
124}
125
126const GoogleServiceAuthError::Captcha& GoogleServiceAuthError::captcha() const {
127  return captcha_;
128}
129
130const GoogleServiceAuthError::SecondFactor&
131GoogleServiceAuthError::second_factor() const {
132  return second_factor_;
133}
134
135int GoogleServiceAuthError::network_error() const {
136  return network_error_;
137}
138
139const std::string& GoogleServiceAuthError::token() const {
140  switch (state_) {
141    case CAPTCHA_REQUIRED:
142      return captcha_.token;
143      break;
144    case TWO_FACTOR:
145      return second_factor_.token;
146      break;
147    default:
148      NOTREACHED();
149  }
150  return base::EmptyString();
151}
152
153const std::string& GoogleServiceAuthError::error_message() const {
154  return error_message_;
155}
156
157base::DictionaryValue* GoogleServiceAuthError::ToValue() const {
158  base::DictionaryValue* value = new base::DictionaryValue();
159  std::string state_str;
160  switch (state_) {
161#define STATE_CASE(x) case x: state_str = #x; break
162    STATE_CASE(NONE);
163    STATE_CASE(INVALID_GAIA_CREDENTIALS);
164    STATE_CASE(USER_NOT_SIGNED_UP);
165    STATE_CASE(CONNECTION_FAILED);
166    STATE_CASE(CAPTCHA_REQUIRED);
167    STATE_CASE(ACCOUNT_DELETED);
168    STATE_CASE(ACCOUNT_DISABLED);
169    STATE_CASE(SERVICE_UNAVAILABLE);
170    STATE_CASE(TWO_FACTOR);
171    STATE_CASE(REQUEST_CANCELED);
172    STATE_CASE(HOSTED_NOT_ALLOWED);
173    STATE_CASE(UNEXPECTED_SERVICE_RESPONSE);
174    STATE_CASE(SERVICE_ERROR);
175#undef STATE_CASE
176    default:
177      NOTREACHED();
178      break;
179  }
180  value->SetString("state", state_str);
181  if (!error_message_.empty()) {
182    value->SetString("errorMessage", error_message_);
183  }
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);
202  }
203  return value;
204}
205
206std::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    default:
239      NOTREACHED();
240      return std::string();
241  }
242}
243
244GoogleServiceAuthError::GoogleServiceAuthError(State s, int error)
245    : state_(s),
246      network_error_(error) {
247}
248
249GoogleServiceAuthError::GoogleServiceAuthError(
250    State s,
251    const std::string& captcha_token,
252    const GURL& captcha_audio_url,
253    const GURL& captcha_image_url,
254    const GURL& captcha_unlock_url,
255    int image_width,
256    int image_height)
257    : state_(s),
258      captcha_(captcha_token, captcha_audio_url, captcha_image_url,
259               captcha_unlock_url, image_width, image_height),
260      network_error_(0) {
261}
262
263GoogleServiceAuthError::GoogleServiceAuthError(
264    State s,
265    const std::string& captcha_token,
266    const std::string& prompt_text,
267    const std::string& alternate_text,
268    int field_length)
269    : state_(s),
270      second_factor_(captcha_token, prompt_text, alternate_text, field_length),
271      network_error_(0) {
272}
273