Home | History | Annotate | Download | only in gaia
      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 
     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 GoogleServiceAuthError::SecondFactor::SecondFactor() : field_length(0) {
     39 }
     40 
     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 
     48 GoogleServiceAuthError::SecondFactor::~SecondFactor() {
     49 }
     50 
     51 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 
     59 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 
     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 
     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 GoogleServiceAuthError::GoogleServiceAuthError(const std::string& error_message)
     85     : state_(INVALID_GAIA_CREDENTIALS),
     86       network_error_(0),
     87       error_message_(error_message) {
     88 }
     89 
     90 // static
     91 GoogleServiceAuthError
     92     GoogleServiceAuthError::FromConnectionError(int error) {
     93   return GoogleServiceAuthError(CONNECTION_FAILED, error);
     94 }
     95 
     96 // static
     97 GoogleServiceAuthError 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
    106 GoogleServiceAuthError GoogleServiceAuthError::FromServiceError(
    107     const std::string& error_message) {
    108   return GoogleServiceAuthError(SERVICE_ERROR, error_message);
    109 }
    110 
    111 // static
    112 GoogleServiceAuthError GoogleServiceAuthError::FromUnexpectedServiceResponse(
    113     const std::string& error_message) {
    114   return GoogleServiceAuthError(UNEXPECTED_SERVICE_RESPONSE, error_message);
    115 }
    116 
    117 // static
    118 GoogleServiceAuthError GoogleServiceAuthError::AuthErrorNone() {
    119   return GoogleServiceAuthError(NONE);
    120 }
    121 
    122 GoogleServiceAuthError::State GoogleServiceAuthError::state() const {
    123   return state_;
    124 }
    125 
    126 const GoogleServiceAuthError::Captcha& GoogleServiceAuthError::captcha() const {
    127   return captcha_;
    128 }
    129 
    130 const GoogleServiceAuthError::SecondFactor&
    131 GoogleServiceAuthError::second_factor() const {
    132   return second_factor_;
    133 }
    134 
    135 int GoogleServiceAuthError::network_error() const {
    136   return network_error_;
    137 }
    138 
    139 const 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 
    153 const std::string& GoogleServiceAuthError::error_message() const {
    154   return error_message_;
    155 }
    156 
    157 base::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 
    206 std::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 
    244 GoogleServiceAuthError::GoogleServiceAuthError(State s, int error)
    245     : state_(s),
    246       network_error_(error) {
    247 }
    248 
    249 GoogleServiceAuthError::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 
    263 GoogleServiceAuthError::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