Add user service and controller
All checks were successful
Game Ideas build for PR / build_blazor_app (pull_request) Successful in 50s
All checks were successful
Game Ideas build for PR / build_blazor_app (pull_request) Successful in 50s
This commit is contained in:
@@ -7,4 +7,7 @@ public interface IUserGateway
|
|||||||
{
|
{
|
||||||
Task<UserListDto> GetUsers(UserFilterParams filterParams, int currentPage);
|
Task<UserListDto> GetUsers(UserFilterParams filterParams, int currentPage);
|
||||||
Task<IEnumerable<RoleDto>> GetRoles();
|
Task<IEnumerable<RoleDto>> GetRoles();
|
||||||
|
Task<string> CreateUser(UserDto user);
|
||||||
|
Task<string> UpdateUser(UserDto user);
|
||||||
|
Task<string> DeleteUser(string userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,32 @@ namespace GameIdeas.BlazorApp.Pages.Users.Gateways;
|
|||||||
|
|
||||||
public class UserGateway(IHttpClientService httpClient) : IUserGateway
|
public class UserGateway(IHttpClientService httpClient) : IUserGateway
|
||||||
{
|
{
|
||||||
|
public async Task<string> CreateUser(UserDto user)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await httpClient.PostAsync<string>(Endpoints.User.Create, user)
|
||||||
|
?? throw new InvalidOperationException(ResourcesKey.ErrorCreateUser);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw new UserCreationException(ResourcesKey.ErrorCreateUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> DeleteUser(string userId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await httpClient.DeleteAsync<string>(Endpoints.User.Delete(userId))
|
||||||
|
?? throw new InvalidOperationException(ResourcesKey.ErrorDeleteUser);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw new UserCreationException(ResourcesKey.ErrorDeleteUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<RoleDto>> GetRoles()
|
public async Task<IEnumerable<RoleDto>> GetRoles()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -42,4 +68,17 @@ public class UserGateway(IHttpClientService httpClient) : IUserGateway
|
|||||||
throw new UserNotFoundException(ResourcesKey.ErrorFetchUsers);
|
throw new UserNotFoundException(ResourcesKey.ErrorFetchUsers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<string> UpdateUser(UserDto user)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return await httpClient.PutAsync<string>(Endpoints.User.Update(user.Id ?? string.Empty), user)
|
||||||
|
?? throw new InvalidOperationException(ResourcesKey.ErrorUpdateUser);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw new UserCreationException(ResourcesKey.ErrorUpdateUser);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,5 +25,9 @@ public static class Endpoints
|
|||||||
{
|
{
|
||||||
public static string Fetch(UserFilterDto filter) => $"api/User?{UrlHelper.BuildUrlParams(filter)}";
|
public static string Fetch(UserFilterDto filter) => $"api/User?{UrlHelper.BuildUrlParams(filter)}";
|
||||||
public const string Roles = "api/User/Roles";
|
public const string Roles = "api/User/Roles";
|
||||||
|
public const string Create = "api/User/Create";
|
||||||
|
public static string Delete(string userId) => $"api/User/Delete/{userId}";
|
||||||
|
public static string Update(string userId) => $"api/User/Update/{userId}";
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
namespace GameIdeas.BlazorApp.Shared.Exceptions;
|
||||||
|
|
||||||
|
public class UserCreationException(string message) : Exception(message);
|
||||||
@@ -58,6 +58,9 @@ public class Translations (TranslationService translationService)
|
|||||||
public string ErrorFetchUsers => translationService.Translate(nameof(ErrorFetchUsers));
|
public string ErrorFetchUsers => translationService.Translate(nameof(ErrorFetchUsers));
|
||||||
public string ErrorFetchRoles => translationService.Translate(nameof(ErrorFetchRoles));
|
public string ErrorFetchRoles => translationService.Translate(nameof(ErrorFetchRoles));
|
||||||
public string MissingField => translationService.Translate(nameof(MissingField));
|
public string MissingField => translationService.Translate(nameof(MissingField));
|
||||||
|
public string ErrorCreateUser => translationService.Translate(nameof(ErrorCreateUser));
|
||||||
|
public string ErrorUpdateUser => translationService.Translate(nameof(ErrorUpdateUser));
|
||||||
|
public string ErrorDeleteUser => translationService.Translate(nameof(ErrorDeleteUser));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ResourcesKey
|
public static class ResourcesKey
|
||||||
@@ -124,4 +127,7 @@ public static class ResourcesKey
|
|||||||
public static string ErrorFetchUsers => _instance?.ErrorFetchUsers ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchUsers is not initialized.");
|
public static string ErrorFetchUsers => _instance?.ErrorFetchUsers ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchUsers is not initialized.");
|
||||||
public static string ErrorFetchRoles => _instance?.ErrorFetchRoles ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchRoles is not initialized.");
|
public static string ErrorFetchRoles => _instance?.ErrorFetchRoles ?? throw new InvalidOperationException("ResourcesKey.ErrorFetchRoles is not initialized.");
|
||||||
public static string MissingField => _instance?.MissingField ?? throw new InvalidOperationException("ResourcesKey.MissingField is not initialized.");
|
public static string MissingField => _instance?.MissingField ?? throw new InvalidOperationException("ResourcesKey.MissingField is not initialized.");
|
||||||
|
public static string ErrorCreateUser => _instance?.ErrorCreateUser ?? throw new InvalidOperationException("ResourcesKey.ErrorCreateUser is not initialized.");
|
||||||
|
public static string ErrorUpdateUser => _instance?.ErrorUpdateUser ?? throw new InvalidOperationException("ResourcesKey.ErrorUpdateUser is not initialized.");
|
||||||
|
public static string ErrorDeleteUser => _instance?.ErrorDeleteUser ?? throw new InvalidOperationException("ResourcesKey.ErrorDeleteUser is not initialized.");
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,8 @@ namespace GameIdeas.WebAPI.Controllers;
|
|||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
public class UserController(
|
public class UserController(
|
||||||
IUserService userService,
|
IUserReadService userReadService,
|
||||||
|
IUserWriteService userWriteService,
|
||||||
ILoggerFactory loggerFactory) : Controller
|
ILoggerFactory loggerFactory) : Controller
|
||||||
{
|
{
|
||||||
private readonly ILogger<UserController> logger = loggerFactory.CreateLogger<UserController>();
|
private readonly ILogger<UserController> logger = loggerFactory.CreateLogger<UserController>();
|
||||||
@@ -20,7 +21,7 @@ public class UserController(
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Ok(await userService.Login(model));
|
return Ok(await userReadService.Login(model));
|
||||||
}
|
}
|
||||||
catch (UserInvalidException e)
|
catch (UserInvalidException e)
|
||||||
{
|
{
|
||||||
@@ -45,7 +46,7 @@ public class UserController(
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Ok(await userService.GetRoles());
|
return Ok(await userReadService.GetRoles());
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -60,7 +61,7 @@ public class UserController(
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Ok(await userService.GetUsers(filter));
|
return Ok(await userReadService.GetUsers(filter));
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
@@ -68,4 +69,49 @@ public class UserController(
|
|||||||
return StatusCode(500, e.Message);
|
return StatusCode(500, e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = GlobalConstants.ADMINISTRATOR)]
|
||||||
|
[HttpPost("Create")]
|
||||||
|
public async Task<ActionResult<string>> CreateUser([FromBody] UserDto user)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Created("/Create", await userWriteService.CreateUser(user));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.LogError(e, "Internal error while create user");
|
||||||
|
return StatusCode(500, e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = GlobalConstants.ADMINISTRATOR)]
|
||||||
|
[HttpPut("Update/{userId}")]
|
||||||
|
public async Task<ActionResult<string>> UpdateUser(string userId, [FromBody] UserDto user)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Created("/Update", await userWriteService.UpdateUser(userId, user));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.LogError(e, "Internal error while update user");
|
||||||
|
return StatusCode(500, e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(Roles = GlobalConstants.ADMINISTRATOR)]
|
||||||
|
[HttpDelete("Delete/{userId}")]
|
||||||
|
public async Task<ActionResult<string>> DeleteUser(string userId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Created("/Delete", await userWriteService.DeleteUser(userId));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.LogError(e, "Internal error while delete user");
|
||||||
|
return StatusCode(500, e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
"RequestFailedStatusFormat": "Erreur lors de la réponse, code {0}",
|
"RequestFailedStatusFormat": "Erreur lors de la réponse, code {0}",
|
||||||
"ErrorFetchCategories": "Erreur lors de la récupération des catégories",
|
"ErrorFetchCategories": "Erreur lors de la récupération des catégories",
|
||||||
"PlaceholderAdd": "Ajouter un nouveau",
|
"PlaceholderAdd": "Ajouter un nouveau",
|
||||||
"ErrorCreateGame": "Erreur lors de la Création d'un jeu",
|
"ErrorCreateGame": "Erreur lors de la création d'un jeu",
|
||||||
"InvalidTitle": "Le titre est incorrect",
|
"InvalidTitle": "Le titre est incorrect",
|
||||||
"InvalidInterest": "L'interêt est incorrect",
|
"InvalidInterest": "L'interêt est incorrect",
|
||||||
"Unknown": "Inconnu",
|
"Unknown": "Inconnu",
|
||||||
@@ -53,5 +53,8 @@
|
|||||||
"Roles": "Rôles",
|
"Roles": "Rôles",
|
||||||
"ErrorFetchUsers": "Erreur lors de la récupération des utilisateurs",
|
"ErrorFetchUsers": "Erreur lors de la récupération des utilisateurs",
|
||||||
"ErrorFetchRoles": "Erreur lors de la récupération des rôles",
|
"ErrorFetchRoles": "Erreur lors de la récupération des rôles",
|
||||||
"MissingField": "Un champs est manquant"
|
"MissingField": "Un champs est manquant",
|
||||||
|
"ErrorCreateUser": "Erreur lors de la création d'un utilisateur",
|
||||||
|
"ErrorUpdateUser": "Erreur lors de la mise à jour d'un utilisateur",
|
||||||
|
"ErrorDeleteUser": "Erreur lors de la suppression d'un utilisateur"
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,8 @@ services.AddAuthorization();
|
|||||||
services.AddSingleton<TranslationService>();
|
services.AddSingleton<TranslationService>();
|
||||||
services.AddSingleton<Translations>();
|
services.AddSingleton<Translations>();
|
||||||
|
|
||||||
services.AddScoped<IUserService, UserService>();
|
services.AddScoped<IUserReadService, UserReadService>();
|
||||||
|
services.AddScoped<IUserWriteService, UserWriteService>();
|
||||||
services.AddScoped<IGameReadService, GameReadService>();
|
services.AddScoped<IGameReadService, GameReadService>();
|
||||||
services.AddScoped<IGameWriteService, GameWriteService>();
|
services.AddScoped<IGameWriteService, GameWriteService>();
|
||||||
services.AddScoped<ICategoryService, CategoryService>();
|
services.AddScoped<ICategoryService, CategoryService>();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace GameIdeas.WebAPI.Services.Users;
|
namespace GameIdeas.WebAPI.Services.Users;
|
||||||
|
|
||||||
public interface IUserService
|
public interface IUserReadService
|
||||||
{
|
{
|
||||||
Task<TokenDto> Login(UserDto user);
|
Task<TokenDto> Login(UserDto user);
|
||||||
Task<IEnumerable<RoleDto>> GetRoles();
|
Task<IEnumerable<RoleDto>> GetRoles();
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
using GameIdeas.Shared.Dto;
|
||||||
|
|
||||||
|
namespace GameIdeas.WebAPI.Services.Users;
|
||||||
|
|
||||||
|
public interface IUserWriteService
|
||||||
|
{
|
||||||
|
Task<string> CreateUser(UserDto user);
|
||||||
|
Task<string> UpdateUser(string userId, UserDto user);
|
||||||
|
Task<string> DeleteUser(string userId);
|
||||||
|
}
|
||||||
@@ -14,10 +14,10 @@ using System.Text;
|
|||||||
|
|
||||||
namespace GameIdeas.WebAPI.Services.Users;
|
namespace GameIdeas.WebAPI.Services.Users;
|
||||||
|
|
||||||
public class UserService(
|
public class UserReadService(
|
||||||
UserManager<User> userManager,
|
UserManager<User> userManager,
|
||||||
GameIdeasContext context,
|
GameIdeasContext context,
|
||||||
IMapper mapper) : IUserService
|
IMapper mapper) : IUserReadService
|
||||||
{
|
{
|
||||||
public async Task<IEnumerable<RoleDto>> GetRoles()
|
public async Task<IEnumerable<RoleDto>> GetRoles()
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using GameIdeas.Resources;
|
||||||
|
using GameIdeas.Shared.Dto;
|
||||||
|
using GameIdeas.Shared.Model;
|
||||||
|
using GameIdeas.WebAPI.Exceptions;
|
||||||
|
using Microsoft.AspNetCore.Identity;
|
||||||
|
|
||||||
|
namespace GameIdeas.WebAPI.Services.Users;
|
||||||
|
|
||||||
|
public class UserWriteService(
|
||||||
|
UserManager<User> userManager) : IUserWriteService
|
||||||
|
{
|
||||||
|
public async Task<string> CreateUser(UserDto user)
|
||||||
|
{
|
||||||
|
if (user.Username == null ||
|
||||||
|
user.Password == null ||
|
||||||
|
user.Role == null)
|
||||||
|
{
|
||||||
|
throw new UserInvalidException(ResourcesKey.MissingField);
|
||||||
|
}
|
||||||
|
|
||||||
|
User userToCreate = new() { UserName = user.Username };
|
||||||
|
|
||||||
|
var result = await userManager.CreateAsync(userToCreate, user.Password);
|
||||||
|
|
||||||
|
if (result.Succeeded)
|
||||||
|
{
|
||||||
|
await userManager.AddToRoleAsync(userToCreate, user.Role.Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new UserInvalidException(string.Join("; ", result.Errors));
|
||||||
|
}
|
||||||
|
|
||||||
|
return userToCreate.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> DeleteUser(string userId)
|
||||||
|
{
|
||||||
|
if (userId == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(ResourcesKey.MissingField);
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = await userManager.FindByIdAsync(userId)
|
||||||
|
?? throw new UserInvalidException("User not found");
|
||||||
|
|
||||||
|
await userManager.DeleteAsync(user);
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> UpdateUser(string userId, UserDto user)
|
||||||
|
{
|
||||||
|
if (userId == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(ResourcesKey.MissingField);
|
||||||
|
}
|
||||||
|
|
||||||
|
var userToUpdate = await userManager.FindByIdAsync(userId)
|
||||||
|
?? throw new UserInvalidException("User not found");
|
||||||
|
|
||||||
|
if (user.Username != null)
|
||||||
|
{
|
||||||
|
userToUpdate.UserName = user.Username;
|
||||||
|
await userManager.UpdateAsync(userToUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.Password != null)
|
||||||
|
{
|
||||||
|
await userManager.RemovePasswordAsync(userToUpdate);
|
||||||
|
await userManager.AddPasswordAsync(userToUpdate, user.Password);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user.Role != null)
|
||||||
|
{
|
||||||
|
var roles = await userManager.GetRolesAsync(userToUpdate);
|
||||||
|
await userManager.RemoveFromRolesAsync(userToUpdate, roles);
|
||||||
|
await userManager.AddToRoleAsync(userToUpdate, user.Role.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return userToUpdate.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user