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 { /// /// The EF implementation of this interface /// /// public class UserRepository : IUserRepository { private readonly BankDbContext bankDbContext; /// /// Initializes a new instance of the class. /// /// The bank database context. public UserRepository(BankDbContext bankDbContext) { this.bankDbContext = bankDbContext; } /// public async Task 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; } /// public async Task 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; } /// public async Task RetrieveUser(int userId) { return await bankDbContext.Users.FirstOrDefaultAsync(u => u.Id == userId); } /// /// Hashes the password. /// /// The salt to apply. /// The password to hash. /// The hashed and salted password 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; } } }