Merged changes from endpoint-impl

This commit is contained in:
REDCODE
2024-10-10 23:37:08 +02:00
parent 48e42fdfff
commit 9595919d26
7 changed files with 113 additions and 67 deletions

View File

@@ -14,9 +14,23 @@ public class AssetController(
) : ControllerBase {
[HttpGet("{id}")]
public ActionResult<GetAssetDto> Get(Guid id) {
var accessLevel = authService.GetUserData(User)?.AccessLevel;
GetAssetDto asset = new GetAssetDto();
assetRepository.Find(id);
switch (accessLevel) {
case EAccessLevel.User: { break; }
case EAccessLevel.Curator:
case EAccessLevel.Admin: {
break;
}
}
return Ok(asset);
}
}
public class GetAssetDto {
}

View File

@@ -8,45 +8,45 @@ using Microsoft.AspNetCore.Mvc;
namespace Lactose.Controllers;
[ApiController]
[Route("api/[controller]")]
public class AuthController(ILogger<AuthController> logger,LactoseAuthService authService, IUserRepository userRepository, IPasswordHasher<User> passwordHasher) : ControllerBase{
public class AuthController(
ILogger<AuthController> logger,
LactoseAuthService authService,
IUserRepository userRepository,
IPasswordHasher<User> passwordHasher
) : ControllerBase {
//TODO: Reply with Authentication Result
[HttpPost("login")]
public ActionResult<string> Login([FromBody] CredentialsDto userDto) {
User? user = null;
if (userDto.Identifier.Contains('@')) {
//search for user in database (by email)
user = userRepository.FindByEmail(userDto.Identifier);
}else {
user = userRepository.FindByEmail(userDto.Identifier);
} else {
//search for user in database (by username)
user = userRepository.FindByUsername(userDto.Identifier);
}
if (user == null) {
return NotFound("User or Password was wrong");
}
if (user == null) { return NotFound("User or Password was wrong"); }
PasswordVerificationResult result = passwordHasher.VerifyHashedPassword(user, user.Password, userDto.Password);
switch(result) {
case PasswordVerificationResult.Failed:
return NotFound("User or Password was wrong");
switch (result) {
case PasswordVerificationResult.Failed: return NotFound("User or Password was wrong");
case PasswordVerificationResult.SuccessRehashNeeded:
user.Password = passwordHasher.HashPassword(user,userDto.Password);
user.Password = passwordHasher.HashPassword(user, userDto.Password);
userRepository.Save();
break;
case PasswordVerificationResult.Success:
break;
case PasswordVerificationResult.Success: break;
}
user.LastLogin = DateTime.Now;
userRepository.Save();
return authService.GenerateToken(user);
}
//TODO: Switch Guid reply with Authentication Result (giving a complete reason in case of failure or giving the authentication token)
[HttpPost("register")]
public ActionResult Register([FromBody] RegisterUserDto userDto) {
@@ -57,40 +57,40 @@ public class AuthController(ILogger<AuthController> logger,LactoseAuthService au
Email: {userDto.Email}
"""
);
if (userRepository.FindByEmail(userDto.Email)!=null || userRepository.FindByUsername(userDto.Username)!=null) {
if (userRepository.FindByEmail(userDto.Email) != null || userRepository.FindByUsername(userDto.Username) != null) {
return Conflict("User already exists");
}
var user = new User {
Username = userDto.Username,
Email = userDto.Email,
Username = userDto.Username,
Email = userDto.Email,
AccessLevel = EAccessLevel.User,
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now
CreatedAt = DateTime.Now,
UpdatedAt = DateTime.Now
};
user.Password = passwordHasher.HashPassword(user, userDto.Password);
userRepository.Insert(user);
userRepository.Save();
return Ok(user.Id);
}
[HttpPost()]
public ActionResult<LactoseAuthService> Check() {
// this.User;
var principal = this.User;
var identity = authService.GetUserData(this.User);
return Ok(identity);
}
[HttpPost("logout")]
public ActionResult Logout(){
var identity = authService.GetUserData(this.User);
public ActionResult Logout() {
var identity = authService.GetUserData(this.User);
if (identity == null) return Unauthorized();
authService.RevokeAccess(identity.Id);
return Ok();
}
}
}

View File

@@ -1,4 +1,3 @@
using Lactose.Dtos;
using Lactose.Mapper;
using Lactose.Models;
@@ -13,20 +12,22 @@ namespace Lactose.Controllers {
[ApiController]
[Authorize]
[Route("api/[controller]")]
public class UserController(ILogger<UserController> logger, LactoseAuthService authService, IUserRepository userRepository) : ControllerBase {
public class UserController(
ILogger<UserController> logger,
LactoseAuthService authService,
IUserRepository userRepository
) : ControllerBase {
[Authorize(Roles = "Admin")]
[HttpPost("create")]
public ActionResult<GetUserDto> Create([FromBody] CreateUserDto userDto){
if (ClaimsPrincipal.Current!=null) {
public ActionResult<GetUserDto> Create([FromBody] CreateUserDto userDto) {
if (ClaimsPrincipal.Current != null) {
logger.LogWarning(@"Anonymous User hasn't enough permissions to create a User. it shouldn't be here");
};
}
LactoseAuthenticatedUser? authenticatedUser = authService.GetUserData(User);
if (authenticatedUser != null && authenticatedUser.AccessLevel!=EAccessLevel.Admin) return Unauthorized();
if (authenticatedUser != null && authenticatedUser.AccessLevel != EAccessLevel.Admin) return Unauthorized();
logger.LogDebug(
$"""
Registering user:
@@ -41,31 +42,30 @@ namespace Lactose.Controllers {
Email = userDto.Email,
Password = userDto.Password
};
user.AccessLevel = userDto.AccessLevel ?? EAccessLevel.User;
//TODO: Optimize search on code or against database through the repository
if (userRepository.GetAll().Any(x => x.Email==user.Email))
return Conflict("Email already exists");
if (userRepository.GetAll().Any(x => x.Username==user.Username))
return Conflict("Username already exists");
if (userRepository.GetAll().Any(x => x.Email == user.Email)) return Conflict("Email already exists");
if (userRepository.GetAll().Any(x => x.Username == user.Username)) return Conflict("Username already exists");
userRepository.Insert(user);
userRepository.Save();
return Ok(user.Id);
}
[HttpGet("{id}")]
public ActionResult<GetUserDto> Get(Guid id) {
LactoseAuthenticatedUser? authenticatedUser = authService.GetUserData(User);
if (authenticatedUser==null) {
if (authenticatedUser == null) {
logger.LogWarning(@"Anonymous User hasn't enough permissions to create a User. it shouldn't be here");
return Unauthorized("Unauthorized");
}
//TODO: Lower level of access should fill less information of users
logger.LogDebug($"Sending user with id {id}");
@@ -90,11 +90,10 @@ namespace Lactose.Controllers {
[HttpPost("update")]
public ActionResult<GetUserDto> Update([FromBody] UpdateUserDto userDto) {
//TODO: Check for logged user permission to create a privileged account after implementing the auth middleware
EAccessLevel permissionLevel = EAccessLevel.Admin;
bool hasPermission = true;
bool hasPermission = true;
logger.LogDebug(
$"""
Editing user:
@@ -115,12 +114,11 @@ namespace Lactose.Controllers {
user.Email = userDto.Email;
user.Password = userDto.Password;
if (permissionLevel == EAccessLevel.Admin)
{
if (permissionLevel == EAccessLevel.Admin) {
if (user.BannedAt != null) user.BannedAt = userDto.IsBanned ? DateTime.Now : null;
user.AccessLevel = userDto.AccessLevel;
}
user.Username = userDto.Username;
user.Email = userDto.Email;
user.Password = userDto.Password;
@@ -131,12 +129,10 @@ namespace Lactose.Controllers {
[HttpDelete("{id}")]
public ActionResult<Guid> Delete(Guid id) {
//TODO: Check for logged user permission to create a privileged account after implementing the auth middleware
EAccessLevel permissionLevel = EAccessLevel.Admin;
bool hasPermission = true;
bool hasPermission = true;
logger.LogDebug($"Deleting user: {id}");
User? user = userRepository.Find(id);

View File

@@ -7,5 +7,4 @@ public class RegisterUserDto {
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public RegisterUserDto() {}
}

View File

@@ -3,10 +3,14 @@ using Lactose.Types;
namespace Lactose.Dtos;
public class UpdateUserDto {
public Guid Id { get; set; }
public string Username { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public bool IsBanned { get; set; }
public EAccessLevel AccessLevel { get; set; }
public Guid Id { get; set; }
public string? Username { get; set; } = string.Empty;
public string? Email { get; set; } = string.Empty;
public string? Password { get; set; } = string.Empty;
public bool? IsBanned { get; set; }
public bool? IsDeleted { get; set; }
public EAccessLevel? AccessLevel { get; set; }
}

View File

@@ -3,12 +3,43 @@ using Lactose.Models;
namespace Lactose.Repositories;
public interface IUserRepository : IDisposable {
/// <summary>
/// Return the list of all users
/// </summary>
/// <returns></returns>
IEnumerable<User> GetAll();
/// <summary>
/// Insert a new uer
/// </summary>
/// <param name="user"></param>
void Insert(User user);
/// <summary>
/// Saves all the changes to the Model
/// </summary>
void Save();
/// <summary>
/// Get the user from the database.
/// </summary>
/// <param name="id"></param>
/// <returns>Returns the user if exist</returns>
User? Find(Guid id);
/// <summary>
/// Find a user by email, expects that the email is unique
/// </summary>
/// <param name="email"></param>
/// <returns>Returns the user if found </returns>
User? FindByEmail(string email);
/// <summary>
/// Find a user by username, expects that the username is unique
/// </summary>
/// <param name="username"></param>
/// <returns>Returns the user if found </returns>
User? FindByUsername(string username);
/// <summary>
/// Delete a user from the database.
/// </summary>
/// <param name="user"></param>
void Delete(User user);
}

View File

@@ -17,4 +17,6 @@ public class UserRepository(LactoseDbContext context) : IUserRepository {
public User? FindByEmail(string email) => context.Users.FirstOrDefault(u => u.Email == email);
public User? FindByUsername(string username) => context.Users.FirstOrDefault(u => u.Username == username);
public void Delete(User user) => context.Users.Remove(user);
}