google_service_auth_error.h revision 58537e28ecd584eab876aee8be7156509866d23a
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Use of this source code is governed by a BSD-style license that can be
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// found in the LICENSE file.
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// A GoogleServiceAuthError is immutable, plain old data representing an
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// error from an attempt to authenticate with a Google service.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// It could be from Google Accounts itself, or any service using Google
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Accounts (e.g expired credentials).  It may contain additional data such as
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// captcha or OTP challenges.
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// A GoogleServiceAuthError without additional data is just a State, defined
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// below. A case could be made to have this relation implicit, to allow raising
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// error events concisely by doing OnAuthError(GoogleServiceAuthError::NONE),
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// for example. But the truth is this class is ever so slightly more than a
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// transparent wrapper around 'State' due to additional Captcha data
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// (e.g consider operator=), and this would violate the style guide. Thus,
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// you must explicitly use the constructor when all you have is a State.
189c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek// The good news is the implementation nests the enum inside a class, so you
19eb50ed88c2aa040fac08bf2a50bde4dd3da6eb19Chris Lattner// may forward declare and typedef GoogleServiceAuthError to something shorter
205d75de0f821023f4ed4815825bf3aea8a0b5e40dChris Lattner// in the comfort of your own translation unit.
216137dc99ef0c2b14050631367057758b0d596cb3Ted Kremenek
22adc4eeb08042a35ae914fc557ffec0cef3df2374Chris Lattner#ifndef GOOGLE_APIS_GAIA_GOOGLE_SERVICE_AUTH_ERROR_H_
23c7229c338c21ef26b01ef3ecf9eec4fd373fa9ecChris Lattner#define GOOGLE_APIS_GAIA_GOOGLE_SERVICE_AUTH_ERROR_H_
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
25cc1a875f94630e58d24a55577ffbf0e89b7da8c7Chris Lattner#include <string>
26caaa7df2c78bbd40197823034c0275f3dcbd63e7Ted Kremenek
270ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek#include "url/gurl.h"
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace base {
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass DictionaryValue;
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass GoogleServiceAuthError {
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer public:
355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // These enumerations are referenced by integer value in HTML login code and
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // in UMA histograms. Do not change the numeric values.
385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //
395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum State {
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // The user is authenticated.
416137dc99ef0c2b14050631367057758b0d596cb3Ted Kremenek    NONE = 0,
42e5956bd2730c051835f9acd9e957c5d79f99e7c3Chris Lattner
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // The credentials supplied to GAIA were either invalid, or the locally
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // cached credentials have expired.
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    INVALID_GAIA_CREDENTIALS = 1,
465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // The GAIA user is not authorized to use the service.
48836040f9eafe862fb1607df5c30cd3df0c22c832Chris Lattner    USER_NOT_SIGNED_UP = 2,
495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Could not connect to server to verify credentials. This could be in
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // response to either failure to connect to GAIA or failure to connect to
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // the service needing GAIA tokens during authentication.
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CONNECTION_FAILED = 3,
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
556137dc99ef0c2b14050631367057758b0d596cb3Ted Kremenek    // The user needs to satisfy a CAPTCHA challenge to unlock their account.
566137dc99ef0c2b14050631367057758b0d596cb3Ted Kremenek    // If no other information is available, this can be resolved by visiting
576137dc99ef0c2b14050631367057758b0d596cb3Ted Kremenek    // https://accounts.google.com/DisplayUnlockCaptcha. Otherwise, captcha()
586137dc99ef0c2b14050631367057758b0d596cb3Ted Kremenek    // will provide details about the associated challenge.
590ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek    CAPTCHA_REQUIRED = 4,
600ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek
610ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek    // The user account has been deleted.
620ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek    ACCOUNT_DELETED = 5,
635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // The user account has been disabled.
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ACCOUNT_DISABLED = 6,
665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // The service is not available; try again later.
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SERVICE_UNAVAILABLE = 7,
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // The password is valid but we need two factor to get a token.
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    TWO_FACTOR = 8,
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // The requestor of the authentication step cancelled the request
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // prior to completion.
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    REQUEST_CANCELED = 9,
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // The user has provided a HOSTED account, when this service requires
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // a GOOGLE account.
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    HOSTED_NOT_ALLOWED = 10,
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Indicates the service responded to a request, but we cannot
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // interpret the response.
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    UNEXPECTED_SERVICE_RESPONSE = 11,
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Indicates the service responded and response carried details of the
865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // application error.
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SERVICE_ERROR = 12,
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // The number of known error states.
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    NUM_STATES = 13,
9168d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff  };
9268d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff
9368d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff  // Additional data for CAPTCHA_REQUIRED errors.
9468d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff  struct Captcha {
9568d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff    Captcha();
9668d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff    Captcha(const std::string& token,
9768d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff            const GURL& audio,
9829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff            const GURL& img,
992e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor            const GURL& unlock,
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            int width,
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            int height);
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ~Captcha();
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // For test only.
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator==(const Captcha &b) const;
1059c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek
1069c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek    std::string token;  // Globally identifies the specific CAPTCHA challenge.
107caaa7df2c78bbd40197823034c0275f3dcbd63e7Ted Kremenek    GURL audio_url;     // The CAPTCHA audio to use instead of image.
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    GURL image_url;     // The CAPTCHA image to show the user.
1099c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek    GURL unlock_url;    // Pretty unlock page containing above captcha.
1109c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek    int image_width;    // Width of captcha image.
1119c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek    int image_height;   // Height of capture image.
1129c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek  };
1139c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek
1149c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek  // Additional data for TWO_FACTOR errors.
1159c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek  struct SecondFactor {
1169c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek    SecondFactor();
1179c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek    SecondFactor(const std::string& token,
1189c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek                 const std::string& prompt,
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                 const std::string& alternate,
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                 int length);
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ~SecondFactor();
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // For test only.
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    bool operator==(const SecondFactor &b) const;
1246cfe7594a46b5d270142cfcb688a9c1a3a487a48Chris Lattner
1256cfe7594a46b5d270142cfcb688a9c1a3a487a48Chris Lattner    // Globally identifies the specific second-factor challenge.
126caaa7df2c78bbd40197823034c0275f3dcbd63e7Ted Kremenek    std::string token;
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // Localised prompt text, eg Enter the verification code sent to your
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // phone number ending in XXX.
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    std::string prompt_text;
1306cfe7594a46b5d270142cfcb688a9c1a3a487a48Chris Lattner    // Localized text describing an alternate option, eg Get a verification
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    // code in a text message.
1329c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek    std::string alternate_text;
1339c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek    // Character length for the challenge field.
1349c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek    int field_length;
1359c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek  };
1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1379c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek  // For test only.
1389c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek  bool operator==(const GoogleServiceAuthError &b) const;
1399c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek
1409c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek  // Construct a GoogleServiceAuthError from a State with no additional data.
1419c1b750c59d510e6c9eccb1f37bccc46ccfe6844Ted Kremenek  explicit GoogleServiceAuthError(State s);
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Construct a GoogleServiceAuthError from a network error.
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // It will be created with CONNECTION_FAILED set.
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static GoogleServiceAuthError FromConnectionError(int error);
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Construct a CAPTCHA_REQUIRED error with CAPTCHA challenge data from the
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // the ClientLogin endpoint.
149cc1a875f94630e58d24a55577ffbf0e89b7da8c7Chris Lattner  // TODO(rogerta): once ClientLogin is no longer used, may be able to get
150cc1a875f94630e58d24a55577ffbf0e89b7da8c7Chris Lattner  // rid of this function.
151cc1a875f94630e58d24a55577ffbf0e89b7da8c7Chris Lattner  static GoogleServiceAuthError FromClientLoginCaptchaChallenge(
152cc1a875f94630e58d24a55577ffbf0e89b7da8c7Chris Lattner      const std::string& captcha_token,
1530ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek      const GURL& captcha_image_url,
1540ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek      const GURL& captcha_unlock_url);
1550ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek
1560ea76727ae91bca918a8414ed85b530eddcfedebTed Kremenek  // Construct a SERVICE_ERROR error, e.g. invalid client ID, with an
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // |error_message| which provides more information about the service error.
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static GoogleServiceAuthError FromServiceError(
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      const std::string& error_message);
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Construct an UNEXPECTED_SERVICE_RESPONSE error, with an |error_message|
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // detailing the problems with the response.
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static GoogleServiceAuthError FromUnexpectedServiceResponse(
1649594acf32de2939b15eafa8fe818607bfc56bf66Chris Lattner      const std::string& error_message);
165aa39197431a0a0b1326ecf6b3be6a11f6e2f8503Chris Lattner
166aa39197431a0a0b1326ecf6b3be6a11f6e2f8503Chris Lattner  // Provided for convenience for clients needing to reset an instance to NONE.
167aa39197431a0a0b1326ecf6b3be6a11f6e2f8503Chris Lattner  // (avoids err_ = GoogleServiceAuthError(GoogleServiceAuthError::NONE), due
16853b0dabbe52219a8057659b90539837394ef0fa1Chris Lattner  // to explicit class and State enum relation. Note: shouldn't be inlined!
1696cfe7594a46b5d270142cfcb688a9c1a3a487a48Chris Lattner  static GoogleServiceAuthError AuthErrorNone();
1706cfe7594a46b5d270142cfcb688a9c1a3a487a48Chris Lattner
1716cfe7594a46b5d270142cfcb688a9c1a3a487a48Chris Lattner  // The error information.
1726cfe7594a46b5d270142cfcb688a9c1a3a487a48Chris Lattner  State state() const;
1739e0ed0bd5a3a7bac73973980ff32132a7724e674Argyrios Kyrtzidis  const Captcha& captcha() const;
174e671e1bc73615eda155059a772266ed2882d758cChris Lattner  const SecondFactor& second_factor() const;
17503db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis  int network_error() const;
17603db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis  const std::string& token() const;
17703db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis  const std::string& error_message() const;
17803db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis
17903db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis  // Returns info about this object in a dictionary.  Caller takes
18003db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis  // ownership of returned dictionary.
18103db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis  base::DictionaryValue* ToValue() const;
18203db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis
18303db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis  // Returns a message describing the error.
18403db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis  std::string ToString() const;
18503db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis
186a9e274c01ebae45629d93aaa07be450fb77dd3cbArgyrios Kyrtzidis private:
187a9e274c01ebae45629d93aaa07be450fb77dd3cbArgyrios Kyrtzidis  GoogleServiceAuthError(State s, int error);
188a9e274c01ebae45629d93aaa07be450fb77dd3cbArgyrios Kyrtzidis
189a9e274c01ebae45629d93aaa07be450fb77dd3cbArgyrios Kyrtzidis  // Construct a GoogleServiceAuthError from |state| and |error_message|.
190a9e274c01ebae45629d93aaa07be450fb77dd3cbArgyrios Kyrtzidis  GoogleServiceAuthError(State state, const std::string& error_message);
19103db1b31dd926409b7defc1c90b66549464652c0Argyrios Kyrtzidis
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  explicit GoogleServiceAuthError(const std::string& error_message);
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
19472b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek  GoogleServiceAuthError(State s, const std::string& captcha_token,
19517d527b051fbc3927b8a1b4ce4607a9b2ed445eeChris Lattner                         const GURL& captcha_audio_url,
19672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek                         const GURL& captcha_image_url,
1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                         const GURL& captcha_unlock_url,
1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                         int image_width,
199836040f9eafe862fb1607df5c30cd3df0c22c832Chris Lattner                         int image_height);
2007c175fb196a2bc3dbc86ea3865c713e1875f3f6dChris Lattner
2017c175fb196a2bc3dbc86ea3865c713e1875f3f6dChris Lattner  GoogleServiceAuthError(State s, const std::string& captcha_token,
2027c175fb196a2bc3dbc86ea3865c713e1875f3f6dChris Lattner                         const std::string& prompt_text,
2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                         const std::string& alternate_text,
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                         int field_length);
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  State state_;
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Captcha captcha_;
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SecondFactor second_factor_;
2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  int network_error_;
21029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff  std::string error_message_;
21132fca722dd974b8202d0fb9c71b6c185c0767da6Chris Lattner};
212880dcf21dfdb3ff763c60195b6794bab0d913095Ted Kremenek
213337edcdbec05316b407d0d64865c88ff8597d910Ted Kremenek#endif  // GOOGLE_APIS_GAIA_GOOGLE_SERVICE_AUTH_ERROR_H_
214880dcf21dfdb3ff763c60195b6794bab0d913095Ted Kremenek