google_service_auth_error.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/string_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stringprintf.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::Captcha::Captcha() : image_width(0), image_height(0) {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::Captcha::Captcha(
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& token, const GURL& audio, const GURL& img,
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& unlock, int width, int height)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : token(token), audio_url(audio), image_url(img), unlock_url(unlock),
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      image_width(width), image_height(height) {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::Captcha::~Captcha() {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GoogleServiceAuthError::Captcha::operator==(const Captcha& b) const {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (token == b.token &&
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          audio_url == b.audio_url &&
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          image_url == b.image_url &&
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          unlock_url == b.unlock_url &&
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          image_width == b.image_width &&
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          image_height == b.image_height);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::SecondFactor::SecondFactor() : field_length(0) {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::SecondFactor::SecondFactor(
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& token, const std::string& prompt,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& alternate, int length)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : token(token), prompt_text(prompt), alternate_text(alternate),
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      field_length(length) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::SecondFactor::~SecondFactor() {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GoogleServiceAuthError::SecondFactor::operator==(
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SecondFactor& b) const {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (token == b.token &&
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          prompt_text == b.prompt_text &&
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          alternate_text == b.alternate_text &&
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          field_length == b.field_length);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GoogleServiceAuthError::operator==(
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GoogleServiceAuthError& b) const {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (state_ == b.state_ &&
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          network_error_ == b.network_error_ &&
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          captcha_ == b.captcha_ &&
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          second_factor_ == b.second_factor_);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::GoogleServiceAuthError(State s)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : state_(s),
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      network_error_(0) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the caller has no idea, then we just set it to a generic failure.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (s == CONNECTION_FAILED) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    network_error_ = net::ERR_FAILED;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::GoogleServiceAuthError(const std::string& error_message)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : state_(INVALID_GAIA_CREDENTIALS),
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      network_error_(0),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      error_message_(error_message) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GoogleServiceAuthError::FromConnectionError(int error) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GoogleServiceAuthError(CONNECTION_FAILED, error);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError GoogleServiceAuthError::FromClientLoginCaptchaChallenge(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& captcha_token,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& captcha_image_url,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& captcha_unlock_url) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GoogleServiceAuthError(CAPTCHA_REQUIRED, captcha_token, GURL(),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                captcha_image_url, captcha_unlock_url, 0, 0);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError GoogleServiceAuthError::FromCaptchaChallenge(
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& captcha_token,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& captcha_audio_url,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& captcha_image_url,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int image_width,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int image_height) {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GoogleServiceAuthError(CAPTCHA_REQUIRED, captcha_token,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               captcha_audio_url, captcha_image_url,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               GURL(), image_width, image_height);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError GoogleServiceAuthError::FromSecondFactorChallenge(
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& captcha_token,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& prompt_text,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& alternate_text,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int field_length) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GoogleServiceAuthError(TWO_FACTOR, captcha_token, prompt_text,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               alternate_text, field_length);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError GoogleServiceAuthError::FromClientOAuthError(
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Value> value(base::JSONReader::Read(data));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GoogleServiceAuthError(CONNECTION_FAILED, 0);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cause;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dict->GetStringWithoutPathExpansion("cause", &cause))
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GoogleServiceAuthError(CONNECTION_FAILED, 0);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The explanation field is optional.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string explanation;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dict->GetStringWithoutPathExpansion("explanation", &explanation))
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    explanation.clear();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GoogleServiceAuthError(explanation);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError GoogleServiceAuthError::None() {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GoogleServiceAuthError(NONE);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::State GoogleServiceAuthError::state() const {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return state_;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GoogleServiceAuthError::Captcha& GoogleServiceAuthError::captcha() const {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return captcha_;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GoogleServiceAuthError::SecondFactor&
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::second_factor() const {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return second_factor_;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int GoogleServiceAuthError::network_error() const {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return network_error_;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string& GoogleServiceAuthError::token() const {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (state_) {
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CAPTCHA_REQUIRED:
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return captcha_.token;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TWO_FACTOR:
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return second_factor_.token;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return EmptyString();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string& GoogleServiceAuthError::error_message() const {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return error_message_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* GoogleServiceAuthError::ToValue() const {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DictionaryValue* value = new DictionaryValue();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string state_str;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (state_) {
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define STATE_CASE(x) case x: state_str = #x; break
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(NONE);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(INVALID_GAIA_CREDENTIALS);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(USER_NOT_SIGNED_UP);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(CONNECTION_FAILED);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(CAPTCHA_REQUIRED);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(ACCOUNT_DELETED);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(ACCOUNT_DISABLED);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(SERVICE_UNAVAILABLE);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(TWO_FACTOR);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(REQUEST_CANCELED);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    STATE_CASE(HOSTED_NOT_ALLOWED);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef STATE_CASE
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  value->SetString("state", state_str);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state_ == CAPTCHA_REQUIRED) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* captcha_value = new DictionaryValue();
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value->Set("captcha", captcha_value);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    captcha_value->SetString("token", captcha_.token);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    captcha_value->SetString("audioUrl", captcha_.audio_url.spec());
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    captcha_value->SetString("imageUrl", captcha_.image_url.spec());
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    captcha_value->SetString("unlockUrl", captcha_.unlock_url.spec());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    captcha_value->SetInteger("imageWidth", captcha_.image_width);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    captcha_value->SetInteger("imageHeight", captcha_.image_height);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (state_ == CONNECTION_FAILED) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value->SetString("networkError", net::ErrorToString(network_error_));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (state_ == TWO_FACTOR) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* two_factor_value = new DictionaryValue();
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value->Set("two_factor", two_factor_value);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    two_factor_value->SetString("token", second_factor_.token);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    two_factor_value->SetString("promptText", second_factor_.prompt_text);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    two_factor_value->SetString("alternateText", second_factor_.alternate_text);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    two_factor_value->SetInteger("fieldLength", second_factor_.field_length);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return value;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GoogleServiceAuthError::ToString() const {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (state_) {
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NONE:
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "";
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case INVALID_GAIA_CREDENTIALS:
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Invalid credentials.";
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case USER_NOT_SIGNED_UP:
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Not authorized.";
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CONNECTION_FAILED:
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return base::StringPrintf("Connection failed (%d).", network_error_);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CAPTCHA_REQUIRED:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return base::StringPrintf("CAPTCHA required (%s).",
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                captcha_.token.c_str());
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ACCOUNT_DELETED:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Account deleted.";
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ACCOUNT_DISABLED:
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Account disabled.";
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SERVICE_UNAVAILABLE:
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Service unavailable; try again later.";
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case TWO_FACTOR:
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return base::StringPrintf("2-step verification required (%s).",
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                second_factor_.token.c_str());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case REQUEST_CANCELED:
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Request canceled.";
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case HOSTED_NOT_ALLOWED:
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Google account required.";
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return std::string();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::GoogleServiceAuthError(State s, int error)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : state_(s),
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      network_error_(error) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::GoogleServiceAuthError(
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State s,
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& captcha_token,
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& captcha_audio_url,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& captcha_image_url,
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& captcha_unlock_url,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int image_width,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int image_height)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : state_(s),
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      captcha_(captcha_token, captcha_audio_url, captcha_image_url,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               captcha_unlock_url, image_width, image_height),
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      network_error_(0) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GoogleServiceAuthError::GoogleServiceAuthError(
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State s,
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& captcha_token,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& prompt_text,
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& alternate_text,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int field_length)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : state_(s),
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      second_factor_(captcha_token, prompt_text, alternate_text, field_length),
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      network_error_(0) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
286