530 lines
18 KiB
C++
530 lines
18 KiB
C++
/*
|
|
* Copyright 2016 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef FIREBASE_AUTH_SRC_INCLUDE_FIREBASE_AUTH_USER_H_
|
|
#define FIREBASE_AUTH_SRC_INCLUDE_FIREBASE_AUTH_USER_H_
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "firebase/auth/credential.h"
|
|
#include "firebase/auth/types.h"
|
|
#include "firebase/future.h"
|
|
#include "firebase/internal/common.h"
|
|
#include "firebase/variant.h"
|
|
|
|
namespace firebase {
|
|
namespace auth {
|
|
|
|
// Predeclarations.
|
|
class Auth;
|
|
struct AuthData;
|
|
struct AuthResult;
|
|
class FederatedAuthProvider;
|
|
|
|
/// @brief Interface implemented by each identity provider.
|
|
class UserInfoInterface {
|
|
public:
|
|
virtual ~UserInfoInterface();
|
|
|
|
/// Gets the unique Firebase user ID for the user.
|
|
///
|
|
/// @note The user's ID, unique to the Firebase project.
|
|
/// Do NOT use this value to authenticate with your backend server, if you
|
|
/// have one.
|
|
/// @if cpp_examples
|
|
/// Use User::GetToken() instead.
|
|
/// @endif
|
|
/// <SWIG>
|
|
/// @if swig_examples
|
|
/// Use User.Token instead.
|
|
/// @endif
|
|
/// @xmlonly
|
|
/// <csproperty name="UserId">
|
|
/// Gets the unique Firebase user ID for the user.
|
|
///
|
|
/// @note The user's ID, unique to the Firebase project.
|
|
/// Do NOT use this value to authenticate with your backend server, if you
|
|
/// have one. Use User.Token instead.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string uid() const;
|
|
|
|
/// Gets email associated with the user, if any.
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="Email">
|
|
/// Gets email associated with the user, if any.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string email() const;
|
|
|
|
/// Gets the display name associated with the user, if any.
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="DisplayName">
|
|
/// Gets the display name associated with the user, if any.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string display_name() const;
|
|
|
|
/// Gets the photo url associated with the user, if any.
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="PhotoUrl">
|
|
/// Gets the photo url associated with the user, if any.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string photo_url() const;
|
|
|
|
/// Gets the provider ID for the user (For example, "Facebook").
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="ProviderId">
|
|
/// Gets the provider ID for the user (For example, \"Facebook\").
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string provider_id() const;
|
|
|
|
/// Gets the phone number for the user, in E.164 format.
|
|
virtual std::string phone_number() const;
|
|
|
|
private:
|
|
friend class User;
|
|
std::string uid_;
|
|
std::string email_;
|
|
std::string display_name_;
|
|
std::string photo_url_;
|
|
std::string provider_id_;
|
|
std::string phone_number_;
|
|
};
|
|
|
|
/// @brief Additional user data returned from an identity provider.
|
|
struct AdditionalUserInfo {
|
|
/// The provider identifier.
|
|
std::string provider_id;
|
|
|
|
/// The name of the user.
|
|
std::string user_name;
|
|
|
|
/// Additional identity-provider specific information.
|
|
/// Most likely a hierarchical key-value mapping, like a parsed JSON file.
|
|
/// Note we use map instead of unordered_map to support older compilers.
|
|
std::map<Variant, Variant> profile;
|
|
|
|
/// On a nonce-based credential link failure where the user has already linked
|
|
/// to the provider, the Firebase auth service may provide an updated
|
|
/// Credential. If is_valid returns true on this credential, then it may be
|
|
/// passed to a new firebase::auth::Auth::SignInWithCredential request to sign
|
|
/// the user in with the provider.
|
|
Credential updated_credential;
|
|
};
|
|
|
|
/// @brief Metadata corresponding to a Firebase user.
|
|
struct UserMetadata {
|
|
UserMetadata() : last_sign_in_timestamp(0), creation_timestamp(0) {}
|
|
|
|
/// The last sign in UTC timestamp in milliseconds.
|
|
/// See https://en.wikipedia.org/wiki/Unix_time for details of UTC.
|
|
uint64_t last_sign_in_timestamp;
|
|
|
|
/// The Firebase user creation UTC timestamp in milliseconds.
|
|
uint64_t creation_timestamp;
|
|
};
|
|
|
|
/// @brief Firebase user account object.
|
|
///
|
|
/// This class allows you to manipulate the profile of a user, link to and
|
|
/// unlink from authentication providers, and refresh authentication tokens.
|
|
class User : public UserInfoInterface {
|
|
public:
|
|
// Default constructor - creates an invalid user.
|
|
User();
|
|
|
|
/// Parameters to the UpdateUserProfile() function.
|
|
///
|
|
/// For fields you don't want to update, pass NULL.
|
|
/// For fields you want to reset, pass "".
|
|
struct UserProfile {
|
|
/// Construct a UserProfile with no display name or photo URL.
|
|
UserProfile() : display_name(NULL), photo_url(NULL) {}
|
|
|
|
/// User display name.
|
|
const char* display_name;
|
|
|
|
/// User photo URI.
|
|
const char* photo_url;
|
|
};
|
|
|
|
/// Copy constructor.
|
|
User(const User&);
|
|
|
|
/// Assignment operator.
|
|
User& operator=(const User&);
|
|
|
|
/// Equality operator.
|
|
bool operator==(const User&) const;
|
|
|
|
/// Inequality operator.
|
|
bool operator!=(const User&) const;
|
|
|
|
~User();
|
|
|
|
/// Returns whether this User object represents a valid user. Could be false
|
|
/// on Users contained with AuthResult structures from failed Auth
|
|
/// operations.
|
|
bool is_valid() const;
|
|
|
|
/// The Java Web Token (JWT) that can be used to identify the user to
|
|
/// the backend.
|
|
///
|
|
/// If a current ID token is still believed to be valid (i.e. it has not yet
|
|
/// expired), that token will be returned immediately.
|
|
/// A developer may set the optional force_refresh flag to get a new ID token,
|
|
/// whether or not the existing token has expired. For example, a developer
|
|
/// may use this when they have discovered that the token is invalid for some
|
|
/// other reason.
|
|
Future<std::string> GetToken(bool force_refresh);
|
|
|
|
#if defined(INTERNAL_EXPERIMENTAL) || defined(SWIG)
|
|
/// A "thread safer" version of GetToken.
|
|
/// If called by two threads simultaneously, GetToken can return the same
|
|
/// pending Future twice. This creates problems if both threads try to set
|
|
/// the OnCompletion callback, unaware that there's another copy.
|
|
/// GetTokenThreadSafe returns a proxy to the Future if it's still pending,
|
|
/// allowing each proxy to have their own callback.
|
|
Future<std::string> GetTokenThreadSafe(bool force_refresh);
|
|
#endif // defined(INTERNAL_EXPERIMENTAL) || defined(SWIG)
|
|
|
|
/// Get results of the most recent call to GetToken.
|
|
Future<std::string> GetTokenLastResult() const;
|
|
|
|
/// Gets the third party profile data associated with this user returned by
|
|
/// the authentication server, if any.
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="ProviderData">
|
|
/// Gets the third party profile data associated with this user returned by
|
|
/// the authentication server, if any.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
std::vector<UserInfoInterface> provider_data() const;
|
|
|
|
/// @deprecated This is a deprecated method. Please use
|
|
/// SendEmailVerificationBeforeUpdatingEmail(email) instead.
|
|
///
|
|
/// Sets the email address for the user.
|
|
///
|
|
/// May fail if there is already an email/password-based account for the same
|
|
/// email address.
|
|
FIREBASE_DEPRECATED Future<void> UpdateEmail(const char* email);
|
|
|
|
/// @deprecated
|
|
///
|
|
/// Get results of the most recent call to UpdateEmail.
|
|
FIREBASE_DEPRECATED Future<void> UpdateEmailLastResult() const;
|
|
|
|
/// Attempts to change the password for the current user.
|
|
///
|
|
/// For an account linked to an Identity Provider (IDP) with no password,
|
|
/// this will result in the account becoming an email/password-based account
|
|
/// while maintaining the IDP link. May fail if the password is invalid,
|
|
/// if there is a conflicting email/password-based account, or if the token
|
|
/// has expired.
|
|
/// To retrieve fresh tokens,
|
|
/// @if cpp_examples
|
|
/// call Reauthenticate.
|
|
/// @endif
|
|
/// <SWIG>
|
|
/// @if swig_examples
|
|
/// call ReauthenticateAsync.
|
|
/// @endif
|
|
/// </SWIG>
|
|
Future<void> UpdatePassword(const char* password);
|
|
|
|
/// Get results of the most recent call to UpdatePassword.
|
|
Future<void> UpdatePasswordLastResult() const;
|
|
|
|
/// Convenience function for ReauthenticateAndRetrieveData that discards
|
|
/// the returned AdditionalUserInfo data.
|
|
Future<void> Reauthenticate(const Credential& credential);
|
|
|
|
/// Get results of the most recent call to Reauthenticate.
|
|
Future<void> ReauthenticateLastResult() const;
|
|
|
|
/// Reauthenticate using a credential.
|
|
///
|
|
/// @if cpp_examples
|
|
/// Some APIs (for example, UpdatePassword, Delete) require that
|
|
/// the token used to invoke them be from a recent login attempt.
|
|
/// This API takes an existing credential for the user and retrieves fresh
|
|
/// tokens, ensuring that the operation can proceed. Developers can call
|
|
/// this method prior to calling UpdatePassword() to ensure success.
|
|
/// @endif
|
|
/// <SWIG>
|
|
/// @if swig_examples
|
|
/// Some APIs (for example, UpdatePasswordAsync, DeleteAsync)
|
|
/// require that the token used to invoke them be from a recent login attempt.
|
|
/// This API takes an existing credential for the user and retrieves fresh
|
|
/// tokens, ensuring that the operation can proceed. Developers can call
|
|
/// this method prior to calling UpdatePasswordAsync() to ensure success.
|
|
/// @endif
|
|
/// </SWIG>
|
|
///
|
|
/// Data from the Identity Provider used to sign-in is returned in the
|
|
/// AdditionalUserInfo inside the returned AuthResult.
|
|
///
|
|
/// Returns an error if the existing credential is not for this user
|
|
/// or if sign-in with that credential failed.
|
|
///
|
|
/// @note: The current user may be signed out if this operation fails on
|
|
/// Android and desktop platforms.
|
|
Future<AuthResult> ReauthenticateAndRetrieveData(
|
|
const Credential& credential);
|
|
|
|
/// Get results of the most recent call to ReauthenticateAndRetrieveData.
|
|
Future<AuthResult> ReauthenticateAndRetrieveDataLastResult() const;
|
|
|
|
/// @brief Re-authenticates the user with a federated auth provider.
|
|
///
|
|
/// @param[in] provider Contains information on the auth provider to
|
|
/// authenticate with.
|
|
/// @return A Future<AuthResult> with the result of the re-authentication
|
|
/// request.
|
|
/// @note: This operation is supported only on iOS, tvOS and Android
|
|
/// platforms. On other platforms this method will return a Future with a
|
|
/// preset error code: kAuthErrorUnimplemented.
|
|
Future<AuthResult> ReauthenticateWithProvider(
|
|
FederatedAuthProvider* provider) const;
|
|
|
|
/// Initiates email verification for the user.
|
|
Future<void> SendEmailVerification();
|
|
|
|
/// Get results of the most recent call to SendEmailVerification.
|
|
Future<void> SendEmailVerificationLastResult() const;
|
|
|
|
/// Send an email to verify the ownership of the account, then update
|
|
/// to the new email.
|
|
Future<void> SendEmailVerificationBeforeUpdatingEmail(const char* email);
|
|
|
|
/// Get results of the most recent call to
|
|
/// SendEmailVerificationBeforeUpdatingEmail.
|
|
Future<void> SendEmailVerificationBeforeUpdatingEmailLastResult() const;
|
|
|
|
/// Updates a subset of user profile information.
|
|
Future<void> UpdateUserProfile(const UserProfile& profile);
|
|
|
|
/// Get results of the most recent call to UpdateUserProfile.
|
|
Future<void> UpdateUserProfileLastResult() const;
|
|
|
|
/// Links the user with the given 3rd party credentials.
|
|
///
|
|
/// For example, a Facebook login access token, a Twitter token/token-secret
|
|
/// pair.
|
|
///
|
|
/// Status will be an error if the token is invalid, expired, or otherwise
|
|
/// not accepted by the server as well as if the given 3rd party
|
|
/// user id is already linked with another user account or if the current user
|
|
/// is already linked with another id from the same provider.
|
|
///
|
|
/// Data from the Identity Provider used to sign-in is returned in the
|
|
/// AdditionalUserInfo inside AuthResult.
|
|
Future<AuthResult> LinkWithCredential(const Credential& credential);
|
|
|
|
/// Get results of the most recent call to LinkWithCredential.
|
|
Future<AuthResult> LinkWithCredentialLastResult() const;
|
|
|
|
///
|
|
/// @param[in] provider Contains information on the auth provider to link
|
|
/// with.
|
|
/// @return A Future<AuthResult> with the user data result of the link
|
|
/// request.
|
|
///
|
|
/// @note: This operation is supported only on iOS, tvOS and Android
|
|
/// platforms. On other platforms this method will return a Future with a
|
|
/// preset error code: kAuthErrorUnimplemented.
|
|
Future<AuthResult> LinkWithProvider(FederatedAuthProvider* provider) const;
|
|
|
|
/// Unlinks the current user from the provider specified.
|
|
/// Status will be an error if the user is not linked to the given provider.
|
|
Future<AuthResult> Unlink(const char* provider);
|
|
|
|
/// Get results of the most recent call to Unlink.
|
|
Future<AuthResult> UnlinkLastResult() const;
|
|
|
|
/// Updates the currently linked phone number on the user.
|
|
/// This is useful when a user wants to change their phone number. It is a
|
|
/// shortcut to calling Unlink(phone_credential.provider().c_str())
|
|
/// and then LinkWithCredential(phone_credential). `credential`
|
|
/// must have been created with PhoneAuthProvider.
|
|
Future<User> UpdatePhoneNumberCredential(
|
|
const PhoneAuthCredential& credential);
|
|
|
|
/// Get results of the most recent call to
|
|
/// UpdatePhoneNumberCredential.
|
|
Future<User> UpdatePhoneNumberCredentialLastResult() const;
|
|
|
|
/// Refreshes the data for this user.
|
|
///
|
|
/// For example, the attached providers, email address, display name, etc.
|
|
Future<void> Reload();
|
|
|
|
/// Get results of the most recent call to Reload.
|
|
Future<void> ReloadLastResult() const;
|
|
|
|
/// Deletes the user account.
|
|
Future<void> Delete();
|
|
|
|
/// Get results of the most recent call to Delete.
|
|
Future<void> DeleteLastResult() const;
|
|
|
|
/// Gets the metadata for this user account.
|
|
UserMetadata metadata() const;
|
|
|
|
/// Returns true if the email address associated with this user has been
|
|
/// verified.
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="IsEmailVerified">
|
|
/// True if the email address associated with this user has been verified.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
bool is_email_verified() const;
|
|
|
|
/// Returns true if user signed in anonymously.
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="IsAnonymous">
|
|
/// True if user signed in anonymously.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
bool is_anonymous() const;
|
|
|
|
/// Gets the unique Firebase user ID for the user.
|
|
///
|
|
/// @note The user's ID, unique to the Firebase project.
|
|
/// Do NOT use this value to authenticate with your backend server, if you
|
|
/// have one.
|
|
/// @if cpp_examples
|
|
/// Use User::GetToken() instead.
|
|
/// @endif
|
|
/// <SWIG>
|
|
/// @if swig_examples
|
|
/// Use User.Token instead.
|
|
/// @endif
|
|
/// @xmlonly
|
|
/// <csproperty name="UserId">
|
|
/// Gets the unique Firebase user ID for the user.
|
|
///
|
|
/// @note The user's ID, unique to the Firebase project.
|
|
/// Do NOT use this value to authenticate with your backend server, if you
|
|
/// have one. Use User.Token instead.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string uid() const;
|
|
|
|
/// Gets email associated with the user, if any.
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="Email">
|
|
/// Gets email associated with the user, if any.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string email() const;
|
|
|
|
/// Gets the display name associated with the user, if any.
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="DisplayName">
|
|
/// Gets the display name associated with the user, if any.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string display_name() const;
|
|
|
|
/// Gets the photo url associated with the user, if any.
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="PhotoUrl">
|
|
/// Gets the photo url associated with the user, if any.
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string photo_url() const;
|
|
|
|
/// Gets the provider ID for the user (For example, "Facebook").
|
|
/// <SWIG>
|
|
/// @xmlonly
|
|
/// <csproperty name="ProviderId">
|
|
/// Gets the provider ID for the user (For example, \"Facebook\").
|
|
/// </csproperty>
|
|
/// @endxmlonly
|
|
/// </SWIG>
|
|
virtual std::string provider_id() const;
|
|
|
|
/// Gets the phone number for the user, in E.164 format.
|
|
virtual std::string phone_number() const;
|
|
|
|
private:
|
|
friend struct AuthData;
|
|
// Only exists in AuthData. Access via Auth::CurrentUser().
|
|
explicit User(AuthData* auth_data) : auth_data_(auth_data) {}
|
|
|
|
#if defined(INTERNAL_EXPERIMENTAL)
|
|
// Doxygen should not make docs for this function.
|
|
/// @cond FIREBASE_APP_INTERNAL
|
|
friend class IdTokenRefreshThread;
|
|
friend class IdTokenRefreshListener;
|
|
friend class Auth;
|
|
Future<std::string> GetTokenInternal(const bool force_refresh,
|
|
const int future_identifier);
|
|
/// @endcond
|
|
#endif // defined(INTERNAL_EXPERIMENTAL)
|
|
|
|
// Use the pimpl mechanism to hide data details in the cpp files.
|
|
AuthData* auth_data_;
|
|
};
|
|
|
|
/// @brief The result of operations that can affect authentication state.
|
|
struct AuthResult {
|
|
/// Identity-provider specific information for the user, if the provider is
|
|
/// one of Facebook, GitHub, Google, or Twitter.
|
|
AdditionalUserInfo additional_user_info;
|
|
|
|
/// A Credential instance for the recently signed-in user. This is not
|
|
/// supported on desktop platforms.
|
|
Credential credential;
|
|
|
|
/// The currently signed-in User, or an invalid User if there isn't
|
|
/// one (i.e. if the user is signed-out then is_valid() will return false).
|
|
User user;
|
|
};
|
|
|
|
} // namespace auth
|
|
} // namespace firebase
|
|
|
|
#endif // FIREBASE_AUTH_SRC_INCLUDE_FIREBASE_AUTH_USER_H_
|