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)// A GoogleServiceAuthError is immutable, plain old data representing an 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error from an attempt to authenticate with a Google service. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It could be from Google Accounts itself, or any service using Google 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Accounts (e.g expired credentials). It may contain additional data such as 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// captcha or OTP challenges. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A GoogleServiceAuthError without additional data is just a State, defined 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// below. A case could be made to have this relation implicit, to allow raising 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error events concisely by doing OnAuthError(GoogleServiceAuthError::NONE), 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for example. But the truth is this class is ever so slightly more than a 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// transparent wrapper around 'State' due to additional Captcha data 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (e.g consider operator=), and this would violate the style guide. Thus, 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// you must explicitly use the constructor when all you have is a State. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The good news is the implementation nests the enum inside a class, so you 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// may forward declare and typedef GoogleServiceAuthError to something shorter 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the comfort of your own translation unit. 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef GOOGLE_APIS_GAIA_GOOGLE_SERVICE_AUTH_ERROR_H_ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define GOOGLE_APIS_GAIA_GOOGLE_SERVICE_AUTH_ERROR_H_ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DictionaryValue; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GoogleServiceAuthError { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // These enumerations are referenced by integer value in HTML login code and 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // in UMA histograms. Do not change the numeric values. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum State { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The user is authenticated. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NONE = 0, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The credentials supplied to GAIA were either invalid, or the locally 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cached credentials have expired. 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INVALID_GAIA_CREDENTIALS = 1, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The GAIA user is not authorized to use the service. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) USER_NOT_SIGNED_UP = 2, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Could not connect to server to verify credentials. This could be in 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // response to either failure to connect to GAIA or failure to connect to 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the service needing GAIA tokens during authentication. 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CONNECTION_FAILED = 3, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The user needs to satisfy a CAPTCHA challenge to unlock their account. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If no other information is available, this can be resolved by visiting 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // https://accounts.google.com/DisplayUnlockCaptcha. Otherwise, captcha() 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will provide details about the associated challenge. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CAPTCHA_REQUIRED = 4, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The user account has been deleted. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ACCOUNT_DELETED = 5, 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The user account has been disabled. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ACCOUNT_DISABLED = 6, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The service is not available; try again later. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SERVICE_UNAVAILABLE = 7, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The password is valid but we need two factor to get a token. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TWO_FACTOR = 8, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The requestor of the authentication step cancelled the request 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // prior to completion. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REQUEST_CANCELED = 9, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The user has provided a HOSTED account, when this service requires 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a GOOGLE account. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HOSTED_NOT_ALLOWED = 10, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Indicates the service responded to a request, but we cannot 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // interpret the response. 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UNEXPECTED_SERVICE_RESPONSE = 11, 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Indicates the service responded and response carried details of the 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // application error. 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SERVICE_ERROR = 12, 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The number of known error states. 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NUM_STATES = 13, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Additional data for CAPTCHA_REQUIRED errors. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct Captcha { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Captcha(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Captcha(const std::string& token, 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& audio, 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& img, 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& unlock, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int width, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Captcha(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For test only. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator==(const Captcha &b) const; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string token; // Globally identifies the specific CAPTCHA challenge. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL audio_url; // The CAPTCHA audio to use instead of image. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL image_url; // The CAPTCHA image to show the user. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL unlock_url; // Pretty unlock page containing above captcha. 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int image_width; // Width of captcha image. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int image_height; // Height of capture image. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Additional data for TWO_FACTOR errors. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SecondFactor { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecondFactor(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecondFactor(const std::string& token, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& prompt, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& alternate, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int length); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~SecondFactor(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For test only. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator==(const SecondFactor &b) const; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Globally identifies the specific second-factor challenge. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string token; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Localised prompt text, eg Enter the verification code sent to your 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // phone number ending in XXX. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string prompt_text; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Localized text describing an alternate option, eg Get a verification 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // code in a text message. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string alternate_text; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Character length for the challenge field. 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int field_length; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For test only. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator==(const GoogleServiceAuthError &b) const; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a GoogleServiceAuthError from a State with no additional data. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit GoogleServiceAuthError(State s); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a GoogleServiceAuthError from a network error. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It will be created with CONNECTION_FAILED set. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static GoogleServiceAuthError FromConnectionError(int error); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Construct a CAPTCHA_REQUIRED error with CAPTCHA challenge data from the 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the ClientLogin endpoint. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rogerta): once ClientLogin is no longer used, may be able to get 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rid of this function. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static GoogleServiceAuthError FromClientLoginCaptchaChallenge( 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& captcha_token, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& captcha_image_url, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& captcha_unlock_url); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct a SERVICE_ERROR error, e.g. invalid client ID, with an 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |error_message| which provides more information about the service error. 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static GoogleServiceAuthError FromServiceError( 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& error_message); 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct an UNEXPECTED_SERVICE_RESPONSE error, with an |error_message| 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // detailing the problems with the response. 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch static GoogleServiceAuthError FromUnexpectedServiceResponse( 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& error_message); 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Provided for convenience for clients needing to reset an instance to NONE. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (avoids err_ = GoogleServiceAuthError(GoogleServiceAuthError::NONE), due 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to explicit class and State enum relation. Note: shouldn't be inlined! 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static GoogleServiceAuthError AuthErrorNone(); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The error information. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state() const; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Captcha& captcha() const; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SecondFactor& second_factor() const; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int network_error() const; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& token() const; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& error_message() const; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns info about this object in a dictionary. Caller takes 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ownership of returned dictionary. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::DictionaryValue* ToValue() const; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns a message describing the error. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string ToString() const; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GoogleServiceAuthError(State s, int error); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Construct a GoogleServiceAuthError from |state| and |error_message|. 190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GoogleServiceAuthError(State state, const std::string& error_message); 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GoogleServiceAuthError(State s, const std::string& captcha_token, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& captcha_audio_url, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& captcha_image_url, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& captcha_unlock_url, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int image_width, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int image_height); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state_; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Captcha captcha_; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SecondFactor second_factor_; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int network_error_; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string error_message_; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // GOOGLE_APIS_GAIA_GOOGLE_SERVICE_AUTH_ERROR_H_ 207