Add project files.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
namespace MyOffice.Web.Identity.Repositories;
|
||||
|
||||
using System.Security.Cryptography;
|
||||
using Domain;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
public class PasswordHasher : IPasswordHasher<ApplicationUser<Guid>>
|
||||
{
|
||||
public string HashPassword(ApplicationUser<Guid> user, string password)
|
||||
{
|
||||
byte[] salt;
|
||||
salt = RandomNumberGenerator.GetBytes(16);
|
||||
|
||||
var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 100000);
|
||||
var hash = pbkdf2.GetBytes(20);
|
||||
|
||||
var hashBytes = new byte[36];
|
||||
Array.Copy(salt, 0, hashBytes, 0, 16);
|
||||
Array.Copy(hash, 0, hashBytes, 16, 20);
|
||||
|
||||
var passwordHash = Convert.ToBase64String(hashBytes);
|
||||
|
||||
return passwordHash;
|
||||
}
|
||||
|
||||
private bool IsValidHash(string password, string passwordHash)
|
||||
{
|
||||
/* Fetch the stored value */
|
||||
/* Extract the bytes */
|
||||
var hashBytes = Convert.FromBase64String(passwordHash);
|
||||
/* Get the salt */
|
||||
var salt = new byte[16];
|
||||
Array.Copy(hashBytes, 0, salt, 0, 16);
|
||||
/* Compute the hash on the password the user entered */
|
||||
var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 100000);
|
||||
var hash = pbkdf2.GetBytes(20);
|
||||
/* Compare the results */
|
||||
for (var i = 0; i < 20; i++)
|
||||
if (hashBytes[i + 16] != hash[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public PasswordVerificationResult VerifyHashedPassword(
|
||||
ApplicationUser<Guid> user,
|
||||
string hashedPassword,
|
||||
string providedPassword
|
||||
)
|
||||
{
|
||||
if (IsValidHash(providedPassword, hashedPassword)) return PasswordVerificationResult.Success;
|
||||
|
||||
return PasswordVerificationResult.Failed;
|
||||
}
|
||||
}
|
||||
|
||||
public class AppUserManager : UserManager<ApplicationUser<Guid>>
|
||||
{
|
||||
public AppUserManager(
|
||||
IUserStore<ApplicationUser<Guid>> store,
|
||||
IOptions<IdentityOptions> optionsAccessor,
|
||||
IPasswordHasher<ApplicationUser<Guid>> passwordHasher,
|
||||
IEnumerable<IUserValidator<ApplicationUser<Guid>>> userValidators,
|
||||
IEnumerable<IPasswordValidator<ApplicationUser<Guid>>> passwordValidators,
|
||||
ILookupNormalizer keyNormalizer,
|
||||
IdentityErrorDescriber errors,
|
||||
IServiceProvider services,
|
||||
ILogger<UserManager<ApplicationUser<Guid>>> logger) :
|
||||
base(
|
||||
store,
|
||||
optionsAccessor,
|
||||
passwordHasher,
|
||||
userValidators,
|
||||
passwordValidators,
|
||||
keyNormalizer,
|
||||
errors,
|
||||
services,
|
||||
logger
|
||||
)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
namespace MyOffice.Web.Identity.Repositories;
|
||||
|
||||
using Domain;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
public class RoleStore : IRoleStore<ApplicationRole>
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public Task<IdentityResult> CreateAsync(ApplicationRole role, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<IdentityResult> UpdateAsync(ApplicationRole role, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<IdentityResult> DeleteAsync(ApplicationRole role, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<string> GetRoleIdAsync(ApplicationRole role, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<string> GetRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SetRoleNameAsync(ApplicationRole role, string roleName, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<string> GetNormalizedRoleNameAsync(ApplicationRole role, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SetNormalizedRoleNameAsync(ApplicationRole role, string normalizedName,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<ApplicationRole> FindByIdAsync(string roleId, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<ApplicationRole> FindByNameAsync(string normalizedRoleName, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
namespace MyOffice.Web.Identity.Repositories;
|
||||
|
||||
using Data.Models.Users;
|
||||
using Data.Repositories.Users;
|
||||
using Domain;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
public class UserStore :
|
||||
IUserStore<ApplicationUser<Guid>>,
|
||||
IUserPasswordStore<ApplicationUser<Guid>>,
|
||||
IUserEmailStore<ApplicationUser<Guid>>
|
||||
{
|
||||
private readonly IUserRepository _userRepository;
|
||||
|
||||
public UserStore(
|
||||
IUserRepository userRepository
|
||||
)
|
||||
{
|
||||
_userRepository = userRepository;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public Task<string> GetUserIdAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(user.Id.ToString());
|
||||
}
|
||||
|
||||
public Task<string> GetUserNameAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(user.UserName);
|
||||
}
|
||||
|
||||
public Task SetUserNameAsync(ApplicationUser<Guid> user, string userName, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<string> GetNormalizedUserNameAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SetNormalizedUserNameAsync(ApplicationUser<Guid> user, string normalizedName,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
user.UserName = normalizedName;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public async Task<IdentityResult> CreateAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await _userRepository.AddUserAsync(new User
|
||||
{
|
||||
Id = user.Id,
|
||||
UserName = user.UserName,
|
||||
Email = user.Email,
|
||||
PasswordHash = user.PasswordHash,
|
||||
FirstName = user.FirstName,
|
||||
LastName = user.LastName,
|
||||
FullName = user.FullName,
|
||||
IsEmailConfirmed = user.IsEmailConfirmed
|
||||
});
|
||||
|
||||
return result == 1 ? IdentityResult.Success : IdentityResult.Failed();
|
||||
}
|
||||
|
||||
public async Task<IdentityResult> UpdateAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
var userDb = new User
|
||||
{
|
||||
Id = user.Id,
|
||||
UserName = user.UserName,
|
||||
Email = user.Email,
|
||||
PasswordHash = user.PasswordHash,
|
||||
FirstName = user.FirstName,
|
||||
LastName = user.LastName,
|
||||
FullName = user.FullName,
|
||||
IsEmailConfirmed = user.IsEmailConfirmed
|
||||
};
|
||||
|
||||
var result = await _userRepository.UpdateUserAsync(userDb);
|
||||
return result == 1 ? IdentityResult.Success : IdentityResult.Failed();
|
||||
}
|
||||
|
||||
public Task<IdentityResult> DeleteAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<ApplicationUser<Guid>> FindByIdAsync(string userId, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = await _userRepository.GetUserAsync(Guid.Parse(userId));
|
||||
if (user == null)
|
||||
{
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
return null;
|
||||
#pragma warning restore CS8603 // Possible null reference return.
|
||||
}
|
||||
|
||||
return new ApplicationUser<Guid>
|
||||
{
|
||||
Id = user.Id,
|
||||
UserName = user.UserName,
|
||||
Email = user.Email,
|
||||
PasswordHash = user.PasswordHash,
|
||||
FirstName = user.FirstName,
|
||||
LastName = user.LastName,
|
||||
FullName = user.FullName,
|
||||
IsEmailConfirmed = user.IsEmailConfirmed
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<ApplicationUser<Guid>> FindByNameAsync(string normalizedUserName,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var user = await _userRepository.GetByUserUserNameAsync(normalizedUserName);
|
||||
if (user == null)
|
||||
{
|
||||
#pragma warning disable CS8603 // Possible null reference return.
|
||||
return null;
|
||||
#pragma warning restore CS8603 // Possible null reference return.
|
||||
}
|
||||
|
||||
return new ApplicationUser<Guid>
|
||||
{
|
||||
Id = user.Id,
|
||||
UserName = user.UserName,
|
||||
Email = user.Email,
|
||||
PasswordHash = user.PasswordHash,
|
||||
FirstName = user.FirstName,
|
||||
LastName = user.LastName,
|
||||
FullName = user.FullName,
|
||||
IsEmailConfirmed = user.IsEmailConfirmed
|
||||
};
|
||||
}
|
||||
|
||||
public Task SetPasswordHashAsync(ApplicationUser<Guid> user, string passwordHash,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
user.PasswordHash = passwordHash;
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<string> GetPasswordHashAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(user.PasswordHash);
|
||||
}
|
||||
|
||||
public Task<bool> HasPasswordAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SetEmailAsync(ApplicationUser<Guid> user, string email, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<string> GetEmailAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(user.Email);
|
||||
}
|
||||
|
||||
public Task<bool> GetEmailConfirmedAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task SetEmailConfirmedAsync(ApplicationUser<Guid> user, bool confirmed, CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<ApplicationUser<Guid>> FindByEmailAsync(string normalizedEmail, CancellationToken cancellationToken)
|
||||
{
|
||||
return FindByNameAsync(normalizedEmail, cancellationToken);
|
||||
}
|
||||
|
||||
public Task<string?> GetNormalizedEmailAsync(ApplicationUser<Guid> user, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(user?.Email);
|
||||
}
|
||||
|
||||
public Task SetNormalizedEmailAsync(ApplicationUser<Guid> user, string normalizedEmail,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user