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