92 lines
3.2 KiB
C#
92 lines
3.2 KiB
C#
using IO.Swagger.Models.db;
|
|
using IO.Swagger.Models.RequestDto;
|
|
using IO.Swagger.Services;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
|
using System;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace IO.Swagger.Repositories
|
|
{
|
|
/// <summary>
|
|
/// The EF implementation of this interface
|
|
/// </summary>
|
|
/// <seealso cref="IUserRepository" />
|
|
public class UserRepository : IUserRepository
|
|
{
|
|
private readonly BankDbContext bankDbContext;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="UserRepository"/> class.
|
|
/// </summary>
|
|
/// <param name="bankDbContext">The bank database context.</param>
|
|
public UserRepository(BankDbContext bankDbContext)
|
|
{
|
|
this.bankDbContext = bankDbContext;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public async Task<User> RegisterUser(AuthRegisterBody request)
|
|
{
|
|
request.Email = request.Email.ToLower();
|
|
if (await bankDbContext.Users.CountAsync((User u) => u.Email == request.Email) > 0)
|
|
return null;
|
|
|
|
// Generate a random salt
|
|
byte[] saltBytes = RandomNumberGenerator.GetBytes(16);
|
|
string salt = Convert.ToBase64String(saltBytes);
|
|
// Hash the password along with the salt
|
|
string hashedPassword = HashPassword(salt, request.Password);
|
|
|
|
// Create and insert the user
|
|
User newUser = new()
|
|
{
|
|
PasswordHash = hashedPassword,
|
|
Salt = salt,
|
|
Email = request.Email,
|
|
FirstName = request.FirstName,
|
|
LastName = request.LastName
|
|
};
|
|
|
|
_ = await bankDbContext.Users.AddAsync(newUser);
|
|
_ = await bankDbContext.SaveChangesAsync();
|
|
return newUser;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public async Task<User> LoginUser(AuthLoginBody request)
|
|
{
|
|
request.Email = request.Email.ToLower();
|
|
User user = await bankDbContext.Users.FirstOrDefaultAsync(u => u.Email.Equals(request.Email));
|
|
if (user == null)
|
|
return null;
|
|
|
|
string hashedPassword = HashPassword(user.Salt, request.Password);
|
|
return hashedPassword != user.PasswordHash ? null : user;
|
|
}
|
|
|
|
/// <inheritdoc/>
|
|
public async Task<User> RetrieveUser(int userId)
|
|
{
|
|
return await bankDbContext.Users.FirstOrDefaultAsync(u => u.Id == userId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hashes the password.
|
|
/// </summary>
|
|
/// <param name="salt">The salt to apply.</param>
|
|
/// <param name="password">The password to hash.</param>
|
|
/// <returns>The hashed and salted password</returns>
|
|
private static string HashPassword(string salt, string password)
|
|
{
|
|
string saltedPassword = password + salt;
|
|
byte[] passwordBytes = Encoding.UTF8.GetBytes(saltedPassword);
|
|
byte[] hashedBytes = SHA256.HashData(passwordBytes);
|
|
string hashedPassword = Convert.ToBase64String(hashedBytes);
|
|
return hashedPassword;
|
|
}
|
|
}
|
|
}
|