using System.Security.Claims;
using Microsoft.AspNetCore.Identity;
namespace Umbraco.Cms.Core.Security;
///
/// A user manager for Umbraco (either back office users or front-end members)
///
/// The type of user
public interface IUmbracoUserManager : IDisposable
where TUser : UmbracoIdentityUser
{
///
/// Gets the user id of a user
///
/// The user
/// A representing the result of the asynchronous operation.
Task GetUserIdAsync(TUser user);
///
/// Get the from a
///
/// The
/// A representing the result of the asynchronous operation.
Task GetUserAsync(ClaimsPrincipal principal);
///
/// Get the user id from the
///
/// the
/// Returns the user id from the
string? GetUserId(ClaimsPrincipal principal);
///
/// Gets the external logins for the user
///
/// A representing the result of the asynchronous operation.
Task> GetLoginsAsync(TUser user);
///
/// Deletes a user
///
/// A representing the result of the asynchronous operation.
Task DeleteAsync(TUser user);
///
/// Finds a user by the external login provider
///
/// A representing the result of the asynchronous operation.
Task FindByLoginAsync(string loginProvider, string providerKey);
///
/// Finds and returns a user, if any, who has the specified .
///
/// The user ID to search for.
///
/// The that represents the asynchronous operation, containing the user matching the specified
/// if it exists.
///
Task FindByIdAsync(string userId);
///
/// Generates a password reset token for the specified , using
/// the configured password reset token provider.
///
/// The user to generate a password reset token for.
///
/// The that represents the asynchronous operation,
/// containing a password reset token for the specified .
///
Task GeneratePasswordResetTokenAsync(TUser user);
///
/// This is a special method that will reset the password but will raise the Password Changed event instead of the
/// reset event
///
///
/// We use this because in the back office the only way an admin can change another user's password without first
/// knowing their password
/// is to generate a token and reset it, however, when we do this we want to track a password change, not a password
/// reset
///
Task ChangePasswordWithResetAsync(string userId, string token, string newPassword);
///
/// Validates that an email confirmation token matches the specified .
///
/// The user to validate the token against.
/// The email confirmation token to validate.
///
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
Task ConfirmEmailAsync(TUser user, string token);
///
/// Gets the user, if any, associated with the normalized value of the specified email address.
/// Note: Its recommended that identityOptions.User.RequireUniqueEmail be set to true when using this method, otherwise
/// the store may throw if there are users with duplicate emails.
///
/// The email address to return the user for.
///
/// The task object containing the results of the asynchronous lookup operation, the user, if any, associated with a
/// normalized value of the specified email address.
///
Task FindByEmailAsync(string email);
///
/// Resets the 's password to the specified after
/// validating the given password reset .
///
/// The user whose password should be reset.
/// The password reset token to verify.
/// The new password to set if reset token verification succeeds.
///
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
Task ResetPasswordAsync(TUser user, string token, string newPassword);
///
/// Override to check the user approval value as well as the user lock out date, by default this only checks the user's
/// locked out date
///
///
/// In the ASP.NET Identity world, there is only one value for being locked out, in Umbraco we have 2 so when checking
/// this for Umbraco we need to check both values
///
Task IsLockedOutAsync(TUser user);
///
/// Locks out a user until the specified end date has passed. Setting a end date in the past immediately unlocks a
/// user.
///
/// The user whose lockout date should be set.
///
/// The after which the 's lockout should
/// end.
///
///
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
Task SetLockoutEndDateAsync(TUser user, DateTimeOffset? lockoutEnd);
///
/// Gets a flag indicating whether the email address for the specified has been verified, true
/// if the email address is verified otherwise
/// false.
///
/// The user whose email confirmation status should be returned.
///
/// The task object containing the results of the asynchronous operation, a flag indicating whether the email address
/// for the specified
/// has been confirmed or not.
///
Task IsEmailConfirmedAsync(TUser user);
///
/// Updates the specified in the backing store.
///
/// The user to update.
///
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
Task UpdateAsync(TUser user);
///
/// Returns a flag indicating whether the specified is valid for
/// the given and .
///
/// The user to validate the token against.
/// The token provider used to generate the token.
/// The purpose the token should be generated for.
/// The token to validate
///
/// The that represents the asynchronous operation, returning true if the
/// is valid, otherwise false.
///
Task VerifyUserTokenAsync(TUser user, string tokenProvider, string purpose, string token);
///
/// Adds the to the specified only if the user
/// does not already have a password.
///
/// The user whose password should be set.
/// The password to set.
///
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
Task AddPasswordAsync(TUser user, string password);
///
/// Returns a flag indicating whether the given is valid for the
/// specified .
///
/// The user whose password should be validated.
/// The password to validate
///
/// The that represents the asynchronous operation, containing true if
/// the specified matches the one store for the ,
/// otherwise false.
///
Task CheckPasswordAsync(TUser user, string? password);
///
/// Changes a user's password after confirming the specified is correct,
/// as an asynchronous operation.
///
/// The user whose password should be set.
/// The current password to validate before changing.
/// The new password to set for the specified .
///
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
Task ChangePasswordAsync(TUser user, string currentPassword, string newPassword);
///
/// Used to validate a user's session
///
/// Returns true if the session is valid, otherwise false
Task ValidateSessionIdAsync(string? userId, string? sessionId);
///
/// Creates the specified in the backing store with no password,
/// as an asynchronous operation.
///
/// The user to create.
///
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
Task CreateAsync(TUser user);
///
/// Gets a list of role names the specified user belongs to.
///
/// The user whose role names to retrieve.
/// The Task that represents the asynchronous operation, containing a list of role names.
Task> GetRolesAsync(TUser user);
///
/// Removes the specified user from the named roles.
///
/// The user to remove from the named roles.
/// The name of the roles to remove the user from.
/// The Task that represents the asynchronous operation, containing the IdentityResult of the operation.
Task RemoveFromRolesAsync(TUser user, IEnumerable roles);
///
/// Add the specified user to the named roles
///
/// The user to add to the named roles
/// The name of the roles to add the user to.
/// The Task that represents the asynchronous operation, containing the IdentityResult of the operation
Task AddToRolesAsync(TUser user, IEnumerable roles);
///
/// Creates the specified in the backing store with a password,
/// as an asynchronous operation.
///
/// The user to create.
/// The password to add to the user.
///
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
Task CreateAsync(TUser user, string password);
///
/// Generate a password for a user based on the current password validator
///
/// A generated password
string GeneratePassword();
///
/// Used to validate the password without an identity user
/// Validation code is based on the default ValidatePasswordAsync code
/// Should return if validation is successful
///
/// The password.
/// A representing whether validation was successful.
Task ValidatePasswordAsync(string? password);
///
/// Generates an email confirmation token for the specified user.
///
/// The user to generate an email confirmation token for.
///
/// The that represents the asynchronous operation, an email confirmation token.
///
Task GenerateEmailConfirmationTokenAsync(TUser user);
///
/// Finds and returns a user, if any, who has the specified user name.
///
/// The user name to search for.
///
/// The that represents the asynchronous operation, containing the user matching the specified
/// if it exists.
///
Task FindByNameAsync(string userName);
///
/// Increments the access failed count for the user as an asynchronous operation.
/// If the failed access account is greater than or equal to the configured maximum number of attempts,
/// the user will be locked out for the configured lockout time span.
///
/// The user whose failed access count to increment.
///
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
Task AccessFailedAsync(TUser user);
///
/// Returns a flag indicating whether the specified has two factor authentication enabled or
/// not,
/// as an asynchronous operation.
///
/// The user whose two factor authentication enabled status should be retrieved.
///
/// The that represents the asynchronous operation, true if the specified
/// has two factor authentication enabled, otherwise false.
///
Task GetTwoFactorEnabledAsync(TUser user);
///
/// Gets a list of valid two factor token providers for the specified ,
/// as an asynchronous operation.
///
/// The user the whose two factor authentication providers will be returned.
///
/// The that represents result of the asynchronous operation, a list of two
/// factor authentication providers for the specified user.
///
Task> GetValidTwoFactorProvidersAsync(TUser user);
///
/// Verifies the specified two factor authentication against the .
///
/// The user the token is supposed to be for.
/// The provider which will verify the token.
/// The token to verify.
///
/// The that represents result of the asynchronous operation, true if the token is valid,
/// otherwise false.
///
Task VerifyTwoFactorTokenAsync(TUser user, string tokenProvider, string token);
///
/// Adds an external Microsoft.AspNetCore.Identity.UserLoginInfo to the specified user.
///
/// The user to add the login to.
/// The external Microsoft.AspNetCore.Identity.UserLoginInfo to add to the specified user.
///
/// The System.Threading.Tasks.Task that represents the asynchronous operation, containing the
/// Microsoft.AspNetCore.Identity.IdentityResult of the operation.
///
Task AddLoginAsync(TUser user, UserLoginInfo login);
///
/// Attempts to remove the provided external login information from the specified user. and returns a flag indicating
/// whether the removal succeed or not.
///
/// The user to remove the login information from.
/// The login provide whose information should be removed.
/// The key given by the external login provider for the specified user.
///
/// The System.Threading.Tasks.Task that represents the asynchronous operation, containing the
/// Microsoft.AspNetCore.Identity.IdentityResult of the operation.
///
Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey);
///
/// Resets the access failed count for the user
///
/// A representing the result of the asynchronous operation.
Task ResetAccessFailedCountAsync(TUser user);
///
/// Generates a two factor token for the user
///
/// A representing the result of the asynchronous operation.
Task GenerateTwoFactorTokenAsync(TUser user, string tokenProvider);
///
/// Gets the email address for the specified user.
///
/// The user whose email should be returned.
///
/// The task object containing the results of the asynchronous operation, the email address for the specified
/// user.
///
Task GetEmailAsync(TUser user);
///
/// Gets the telephone number, if any, for the specified user.
///
/// The user whose telephone number should be retrieved.
///
/// The System.Threading.Tasks.Task that represents the asynchronous operation, containing the user's telephone
/// number, if any.
///
///
/// A user can only support a phone number if the BackOfficeUserStore is replaced with another that implements
/// IUserPhoneNumberStore
///
Task GetPhoneNumberAsync(TUser user);
///
/// Validates that a user's credentials are correct without actually logging them in.
///
/// The user name.
/// The password.
/// True if the credentials are valid.
Task ValidateCredentialsAsync(string username, string password);
}