feat(API): Adds Password hashing

This commit is contained in:
MrFastwind
2024-10-07 15:16:57 +02:00
parent 79d47257f3
commit 37dbac2611
3 changed files with 29 additions and 32 deletions

View File

@@ -2,6 +2,8 @@ using Lactose.Dtos;
using Lactose.Models; using Lactose.Models;
using Lactose.Repositories; using Lactose.Repositories;
using Lactose.Services; using Lactose.Services;
using Lactose.Types;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
namespace Lactose.Controllers; namespace Lactose.Controllers;
@@ -10,7 +12,7 @@ namespace Lactose.Controllers;
[ApiController] [ApiController]
[Route("api/[controller]")] [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 //TODO: Reply with Authentication Result
[HttpPost("login")] [HttpPost("login")]
@@ -28,8 +30,18 @@ public class AuthController(ILogger<AuthController> logger,LactoseAuthentication
return NotFound("User or Password was wrong"); 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); 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) { if (userRepository.FindByEmail(userDto.Email)!=null || userRepository.FindByUsername(userDto.Username)!=null) {
//search for user in database (by email)
return Conflict("User already exists"); return Conflict("User already exists");
} }
var user = new User { var user = new User {
Username = userDto.Username, Username = userDto.Username,
Email = userDto.Email, 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.Insert(user);
userRepository.Save(); userRepository.Save();
return Ok(user.Id); return Ok(user.Id);
@@ -63,6 +78,7 @@ public class AuthController(ILogger<AuthController> logger,LactoseAuthentication
[HttpPost()] [HttpPost()]
public ActionResult<LactoseAuthenticationService> Check() { public ActionResult<LactoseAuthenticationService> Check() {
// this.User; // this.User;
var principal = this.User; var principal = this.User;
var identity = authService.GetUserData(this.User); var identity = authService.GetUserData(this.User);
return Ok(identity); return Ok(identity);
@@ -70,6 +86,9 @@ public class AuthController(ILogger<AuthController> logger,LactoseAuthentication
[HttpPost("logout")] [HttpPost("logout")]
public ActionResult Logout(){ public ActionResult Logout(){
return Unauthorized(); var identity = authService.GetUserData(this.User);
if (identity == null) return Unauthorized();
authService.RevokeAccess(identity.Id);
return Ok();
} }
} }

View File

@@ -1,19 +1,15 @@
using Lactose.Configuration; using Lactose.Configuration;
using Lactose.Models; using Lactose.Models;
using Lactose.Types; using Lactose.Types;
using Microsoft.AspNetCore.Authentication;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt; using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims; using System.Security.Claims;
using System.Security.Principal;
using System.Text;
namespace Lactose.Services; namespace Lactose.Services;
public class LactoseAuthenticationService(ILogger<LactoseAuthenticationService> logger,IOptions<SignKeyConfiguration> keyOption) { public class LactoseAuthenticationService(ILogger<LactoseAuthenticationService> logger,IOptions<SignKeyConfiguration> keyOption) {
public string GenerateToken(User user) { public string GenerateToken(User user) {
var handler = new JwtSecurityTokenHandler(); var handler = new JwtSecurityTokenHandler();
@@ -64,7 +60,10 @@ public class LactoseAuthenticationService(ILogger<LactoseAuthenticationService>
email, email,
(EAccessLevel)Enum.Parse(typeof(EAccessLevel),eAccessLevel) (EAccessLevel)Enum.Parse(typeof(EAccessLevel),eAccessLevel)
); );
}
public void RevokeAccess(Guid id) {
//Revoke access for user
} }
} }

View File

@@ -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;
}
}