diff --git a/Moonlight.ApiServer/Http/Controllers/Admin/Users/UsersController.cs b/Moonlight.ApiServer/Http/Controllers/Admin/Users/UsersController.cs new file mode 100644 index 00000000..2e72b3af --- /dev/null +++ b/Moonlight.ApiServer/Http/Controllers/Admin/Users/UsersController.cs @@ -0,0 +1,81 @@ +using Microsoft.AspNetCore.Mvc; +using MoonCore.Exceptions; +using MoonCore.Extended.Abstractions; +using MoonCore.Extended.Helpers; +using MoonCore.Models; +using Moonlight.ApiServer.Database.Entities; +using Moonlight.Shared.Http.Requests.Admin.Users; +using Moonlight.Shared.Http.Responses.Admin.Users; + +namespace Moonlight.ApiServer.Http.Controllers.Admin.Users; + +[ApiController] +[Route("api/admin/users")] +public class UsersController : Controller +{ + private readonly CrudHelper CrudHelper; + private readonly DatabaseRepository UserRepository; + + public UsersController(CrudHelper crudHelper, DatabaseRepository userRepository) + { + CrudHelper = crudHelper; + UserRepository = userRepository; + } + + [HttpGet] + public async Task> Get([FromQuery] int page, [FromQuery] int pageSize = 50) + => await CrudHelper.Get(page, pageSize); + + [HttpGet("{id}")] + public async Task GetSingle(int id) + => await CrudHelper.GetSingle(id); + + [HttpPost] + public async Task Create([FromBody] CreateUserRequest request) + { + // Reformat values + request.Username = request.Username.ToLower().Trim(); + request.Email = request.Email.ToLower().Trim(); + + // Check for users with the same values + if (UserRepository.Get().Any(x => x.Username == request.Username)) + throw new HttpApiException("A user with that username already exists", 400); + + if (UserRepository.Get().Any(x => x.Email == request.Email)) + throw new HttpApiException("A user with that email address already exists", 400); + + request.Password = HashHelper.Hash(request.Password); + + return await CrudHelper.Create(request); + } + + [HttpPatch("{id}")] + public async Task Update([FromRoute] int id, [FromBody] UpdateUserRequest request) + { + var user = await CrudHelper.GetSingleModel(id); + + // Reformat values + request.Username = request.Username.ToLower().Trim(); + request.Email = request.Email.ToLower().Trim(); + + // Check for users with the same values + if (UserRepository.Get().Any(x => x.Username == request.Username && x.Id != user.Id)) + throw new HttpApiException("A user with that username already exists", 400); + + if (UserRepository.Get().Any(x => x.Email == request.Email && x.Id != user.Id)) + throw new HttpApiException("A user with that email address already exists", 400); + + // Perform hashing the password if required + if (!string.IsNullOrEmpty(request.Password)) + { + request.Password = HashHelper.Hash(request.Password); + user.TokenValidTimestamp = DateTime.UtcNow; // This change will get applied by the crud helper + } + + return await CrudHelper.Update(user, request); + } + + [HttpDelete("{id}")] + public async Task Delete([FromRoute] int id) + => await CrudHelper.Delete(id); +} \ No newline at end of file diff --git a/Moonlight.ApiServer/Moonlight.ApiServer.csproj b/Moonlight.ApiServer/Moonlight.ApiServer.csproj index cd92652b..58691412 100644 --- a/Moonlight.ApiServer/Moonlight.ApiServer.csproj +++ b/Moonlight.ApiServer/Moonlight.ApiServer.csproj @@ -13,7 +13,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/Moonlight.ApiServer/Program.cs b/Moonlight.ApiServer/Program.cs index 3ca36c66..0263b092 100644 --- a/Moonlight.ApiServer/Program.cs +++ b/Moonlight.ApiServer/Program.cs @@ -86,6 +86,7 @@ var databaseHelper = new DatabaseHelper( builder.Services.AddSingleton(databaseHelper); builder.Services.AddScoped(typeof(DatabaseRepository<>)); +builder.Services.AddScoped(typeof(CrudHelper<,>)); builder.Services.AddDbContext(); databaseHelper.AddDbContext(); diff --git a/Moonlight.Client/Moonlight.Client.csproj b/Moonlight.Client/Moonlight.Client.csproj index bc029be0..dd97f0d9 100644 --- a/Moonlight.Client/Moonlight.Client.csproj +++ b/Moonlight.Client/Moonlight.Client.csproj @@ -13,6 +13,7 @@ + diff --git a/Moonlight.Client/UI/Partials/AppHeader.razor b/Moonlight.Client/UI/Partials/AppHeader.razor index e4171b6a..7c7c299b 100644 --- a/Moonlight.Client/UI/Partials/AppHeader.razor +++ b/Moonlight.Client/UI/Partials/AppHeader.razor @@ -62,7 +62,7 @@ From: "transform opacity-100 scale-100" To: "transform opacity-0 scale-95" --> -