feat(API): Adds Password hashing
This commit is contained in:
@@ -2,6 +2,8 @@ using Lactose.Dtos;
|
||||
using Lactose.Models;
|
||||
using Lactose.Repositories;
|
||||
using Lactose.Services;
|
||||
using Lactose.Types;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Lactose.Controllers;
|
||||
@@ -10,7 +12,7 @@ namespace Lactose.Controllers;
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
|
||||
public class AuthController(ILogger<AuthController> logger,LactoseAuthenticationService authService, IUserRepository userRepository) : ControllerBase{
|
||||
public class AuthController(ILogger<AuthController> logger,LactoseAuthenticationService authService, IUserRepository userRepository, PasswordHasher<User> passwordHasher) : ControllerBase{
|
||||
|
||||
//TODO: Reply with Authentication Result
|
||||
[HttpPost("login")]
|
||||
@@ -28,8 +30,18 @@ public class AuthController(ILogger<AuthController> logger,LactoseAuthentication
|
||||
return NotFound("User or Password was wrong");
|
||||
}
|
||||
|
||||
//check password with
|
||||
PasswordVerificationResult result = passwordHasher.VerifyHashedPassword(user, user.Password, userDto.Password);
|
||||
|
||||
switch(result) {
|
||||
case PasswordVerificationResult.Failed:
|
||||
return NotFound("User or Password was wrong");
|
||||
case PasswordVerificationResult.SuccessRehashNeeded:
|
||||
user.Password = passwordHasher.HashPassword(user,userDto.Password);
|
||||
userRepository.Save();
|
||||
break;
|
||||
case PasswordVerificationResult.Success:
|
||||
break;
|
||||
}
|
||||
return authService.GenerateToken(user);
|
||||
}
|
||||
|
||||
@@ -45,16 +57,19 @@ public class AuthController(ILogger<AuthController> logger,LactoseAuthentication
|
||||
);
|
||||
|
||||
if (userRepository.FindByEmail(userDto.Email)!=null || userRepository.FindByUsername(userDto.Username)!=null) {
|
||||
//search for user in database (by email)
|
||||
return Conflict("User already exists");
|
||||
}
|
||||
|
||||
var user = new User {
|
||||
Username = userDto.Username,
|
||||
Email = userDto.Email,
|
||||
Password = userDto.Password
|
||||
AccessLevel = EAccessLevel.User,
|
||||
CreatedAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now
|
||||
};
|
||||
|
||||
user.Password = passwordHasher.HashPassword(user, userDto.Password);
|
||||
|
||||
userRepository.Insert(user);
|
||||
userRepository.Save();
|
||||
return Ok(user.Id);
|
||||
@@ -63,6 +78,7 @@ public class AuthController(ILogger<AuthController> logger,LactoseAuthentication
|
||||
[HttpPost()]
|
||||
public ActionResult<LactoseAuthenticationService> Check() {
|
||||
// this.User;
|
||||
|
||||
var principal = this.User;
|
||||
var identity = authService.GetUserData(this.User);
|
||||
return Ok(identity);
|
||||
@@ -70,6 +86,9 @@ public class AuthController(ILogger<AuthController> logger,LactoseAuthentication
|
||||
|
||||
[HttpPost("logout")]
|
||||
public ActionResult Logout(){
|
||||
return Unauthorized();
|
||||
var identity = authService.GetUserData(this.User);
|
||||
if (identity == null) return Unauthorized();
|
||||
authService.RevokeAccess(identity.Id);
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,15 @@
|
||||
using Lactose.Configuration;
|
||||
using Lactose.Models;
|
||||
using Lactose.Types;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Security.Claims;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
|
||||
namespace Lactose.Services;
|
||||
|
||||
public class LactoseAuthenticationService(ILogger<LactoseAuthenticationService> logger,IOptions<SignKeyConfiguration> keyOption) {
|
||||
|
||||
|
||||
public string GenerateToken(User user) {
|
||||
var handler = new JwtSecurityTokenHandler();
|
||||
|
||||
@@ -64,7 +60,10 @@ public class LactoseAuthenticationService(ILogger<LactoseAuthenticationService>
|
||||
email,
|
||||
(EAccessLevel)Enum.Parse(typeof(EAccessLevel),eAccessLevel)
|
||||
);
|
||||
}
|
||||
|
||||
public void RevokeAccess(Guid id) {
|
||||
//Revoke access for user
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
using Lactose.Models;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace Lactose.Services;
|
||||
|
||||
public class PasswordHasher(PasswordHasher<string> passwordHasher) : IPasswordHasher<User> {
|
||||
public string HashPassword(User user, string password) {
|
||||
string salt = GetSalt(user);
|
||||
return passwordHasher.HashPassword(salt, password);
|
||||
}
|
||||
|
||||
static string GetSalt(User user) {
|
||||
return user.Password.Substring(user.Password.LastIndexOf('.'));
|
||||
}
|
||||
|
||||
public PasswordVerificationResult VerifyHashedPassword(User user, string hashedPassword, string providedPassword) {
|
||||
string salt = GetSalt(user);
|
||||
return passwordHasher.HashPassword(salt, providedPassword) == hashedPassword?
|
||||
PasswordVerificationResult.Success : PasswordVerificationResult.Failed;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user