google_service_auth_error.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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/string_util.h"
12#include "base/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
38
39GoogleServiceAuthError::SecondFactor::SecondFactor() : field_length(0) {
40}
41
42GoogleServiceAuthError::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
49GoogleServiceAuthError::SecondFactor::~SecondFactor() {
50}
51
52bool 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
61bool 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
69GoogleServiceAuthError::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
78GoogleServiceAuthError::GoogleServiceAuthError(const std::string& error_message)
79    : state_(INVALID_GAIA_CREDENTIALS),
80      network_error_(0),
81      error_message_(error_message) {
82}
83
84// static
85GoogleServiceAuthError
86    GoogleServiceAuthError::FromConnectionError(int error) {
87  return GoogleServiceAuthError(CONNECTION_FAILED, error);
88}
89
90// static
91GoogleServiceAuthError 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
99GoogleServiceAuthError GoogleServiceAuthError::AuthErrorNone() {
100  return GoogleServiceAuthError(NONE);
101}
102
103GoogleServiceAuthError::State GoogleServiceAuthError::state() const {
104  return state_;
105}
106
107const GoogleServiceAuthError::Captcha& GoogleServiceAuthError::captcha() const {
108  return captcha_;
109}
110
111const GoogleServiceAuthError::SecondFactor&
112GoogleServiceAuthError::second_factor() const {
113  return second_factor_;
114}
115
116int GoogleServiceAuthError::network_error() const {
117  return network_error_;
118}
119
120const std::string& GoogleServiceAuthError::token() const {
121  switch (state_) {
122    case CAPTCHA_REQUIRED:
123      return captcha_.token;
124      break;
125    case TWO_FACTOR:
126      return second_factor_.token;
127      break;
128    default:
129      NOTREACHED();
130  }
131  return EmptyString();
132}
133
134const std::string& GoogleServiceAuthError::error_message() const {
135  return error_message_;
136}
137
138DictionaryValue* GoogleServiceAuthError::ToValue() const {
139  DictionaryValue* value = new DictionaryValue();
140  std::string state_str;
141  switch (state_) {
142#define STATE_CASE(x) case x: state_str = #x; break
143    STATE_CASE(NONE);
144    STATE_CASE(INVALID_GAIA_CREDENTIALS);
145    STATE_CASE(USER_NOT_SIGNED_UP);
146    STATE_CASE(CONNECTION_FAILED);
147    STATE_CASE(CAPTCHA_REQUIRED);
148    STATE_CASE(ACCOUNT_DELETED);
149    STATE_CASE(ACCOUNT_DISABLED);
150    STATE_CASE(SERVICE_UNAVAILABLE);
151    STATE_CASE(TWO_FACTOR);
152    STATE_CASE(REQUEST_CANCELED);
153    STATE_CASE(HOSTED_NOT_ALLOWED);
154#undef STATE_CASE
155    default:
156      NOTREACHED();
157      break;
158  }
159  value->SetString("state", state_str);
160  if (state_ == CAPTCHA_REQUIRED) {
161    DictionaryValue* captcha_value = new DictionaryValue();
162    value->Set("captcha", captcha_value);
163    captcha_value->SetString("token", captcha_.token);
164    captcha_value->SetString("audioUrl", captcha_.audio_url.spec());
165    captcha_value->SetString("imageUrl", captcha_.image_url.spec());
166    captcha_value->SetString("unlockUrl", captcha_.unlock_url.spec());
167    captcha_value->SetInteger("imageWidth", captcha_.image_width);
168    captcha_value->SetInteger("imageHeight", captcha_.image_height);
169  } else if (state_ == CONNECTION_FAILED) {
170    value->SetString("networkError", net::ErrorToString(network_error_));
171  } else if (state_ == TWO_FACTOR) {
172    DictionaryValue* two_factor_value = new DictionaryValue();
173    value->Set("two_factor", two_factor_value);
174    two_factor_value->SetString("token", second_factor_.token);
175    two_factor_value->SetString("promptText", second_factor_.prompt_text);
176    two_factor_value->SetString("alternateText", second_factor_.alternate_text);
177    two_factor_value->SetInteger("fieldLength", second_factor_.field_length);
178  }
179  return value;
180}
181
182std::string GoogleServiceAuthError::ToString() const {
183  switch (state_) {
184    case NONE:
185      return std::string();
186    case INVALID_GAIA_CREDENTIALS:
187      return "Invalid credentials.";
188    case USER_NOT_SIGNED_UP:
189      return "Not authorized.";
190    case CONNECTION_FAILED:
191      return base::StringPrintf("Connection failed (%d).", network_error_);
192    case CAPTCHA_REQUIRED:
193      return base::StringPrintf("CAPTCHA required (%s).",
194                                captcha_.token.c_str());
195    case ACCOUNT_DELETED:
196      return "Account deleted.";
197    case ACCOUNT_DISABLED:
198      return "Account disabled.";
199    case SERVICE_UNAVAILABLE:
200      return "Service unavailable; try again later.";
201    case TWO_FACTOR:
202      return base::StringPrintf("2-step verification required (%s).",
203                                second_factor_.token.c_str());
204    case REQUEST_CANCELED:
205      return "Request canceled.";
206    case HOSTED_NOT_ALLOWED:
207      return "Google account required.";
208    default:
209      NOTREACHED();
210      return std::string();
211  }
212}
213
214GoogleServiceAuthError::GoogleServiceAuthError(State s, int error)
215    : state_(s),
216      network_error_(error) {
217}
218
219GoogleServiceAuthError::GoogleServiceAuthError(
220    State s,
221    const std::string& captcha_token,
222    const GURL& captcha_audio_url,
223    const GURL& captcha_image_url,
224    const GURL& captcha_unlock_url,
225    int image_width,
226    int image_height)
227    : state_(s),
228      captcha_(captcha_token, captcha_audio_url, captcha_image_url,
229               captcha_unlock_url, image_width, image_height),
230      network_error_(0) {
231}
232
233GoogleServiceAuthError::GoogleServiceAuthError(
234    State s,
235    const std::string& captcha_token,
236    const std::string& prompt_text,
237    const std::string& alternate_text,
238    int field_length)
239    : state_(s),
240      second_factor_(captcha_token, prompt_text, alternate_text, field_length),
241      network_error_(0) {
242}
243