diff --git a/src/HigiaServer.API/Endpoints/AuthenticationEndpoint.cs b/src/HigiaServer.API/Endpoints/AuthenticationEndpoint.cs index 258b9bb..2b012e0 100644 --- a/src/HigiaServer.API/Endpoints/AuthenticationEndpoint.cs +++ b/src/HigiaServer.API/Endpoints/AuthenticationEndpoint.cs @@ -1,12 +1,11 @@ -using System.Security.Claims; using AutoMapper; - using HigiaServer.Application.Contracts.Requests; using HigiaServer.Application.Contracts.Responses; using HigiaServer.Application.Errors; using HigiaServer.Application.Repositories; using HigiaServer.Application.Services; using HigiaServer.Domain.Entities; +using Microsoft.AspNetCore.Authentication; namespace HigiaServer.API.Endpoints; @@ -45,23 +44,14 @@ public static IEndpointRouteBuilder AddAuthenticationEndpoint(this IEndpointRout # region private methods private static async Task HandleRegister( - HttpContext context, RegisterRequest request, IUserRepository repository, IMapper mapper, IJwtTokenService jwtTokenService ) { - if (!context.User!.Identity!.IsAuthenticated) - { - throw new UnauthenticatedException(); - } - if (context.User.FindFirstValue(ClaimTypes.Role) != "admin") - { - throw new UnauthorizedAccessException(); - } - - if (await repository.GetUserByEmail(request.Email) != null) throw new DuplicateEmailException(request.Email); + if (await repository.GetUserByEmail(request.Email) != null) + throw new DuplicateEmailException(request.Email); request.Password = BCrypt.Net.BCrypt.HashPassword(request.Password); var user = mapper.Map(request); @@ -85,8 +75,8 @@ IJwtTokenService jwtTokenService { if (await repository.GetUserByEmail(request.Email) is not { } user) throw new EmailGivenNotFoundException(request.Email); - - if (!BCrypt.Net.BCrypt.Verify(request.Password, user.Password)) throw new InvalidPasswordException(); + if (!BCrypt.Net.BCrypt.Verify(request.Password, user.Password)) + throw new InvalidPasswordException(); var authResponse = new AuthenticationResponse( mapper.Map(user), diff --git a/src/HigiaServer.API/Endpoints/TaskEndpoint.cs b/src/HigiaServer.API/Endpoints/TaskEndpoint.cs index 33370cb..cb20ee4 100644 --- a/src/HigiaServer.API/Endpoints/TaskEndpoint.cs +++ b/src/HigiaServer.API/Endpoints/TaskEndpoint.cs @@ -12,10 +12,10 @@ public static class TaskEndpoint { public static IEndpointRouteBuilder AddTaskEndpoint(this IEndpointRouteBuilder app) { - var taskEndpoint = app.MapGroup("higia-server/api/tasks").WithTags("Tasks"); + var authEndpoint = app.MapGroup("higia-server/api/tasks").WithTags("Tasks"); // add task - taskEndpoint.MapPost("/", HandleAddTask) + authEndpoint.MapPost("/", HandleAddTask) .WithName("Add new task") .Produces(StatusCodes.Status201Created) .WithOpenApi(x => @@ -25,7 +25,7 @@ public static IEndpointRouteBuilder AddTaskEndpoint(this IEndpointRouteBuilder a }); // get task by id - taskEndpoint.MapGet("/{taskId:guid}", HandleGetTask) + authEndpoint.MapGet("/{taskId:guid}", HandleGetTask) .WithName("Get task by id") .Produces() .WithOpenApi(x => @@ -35,7 +35,7 @@ public static IEndpointRouteBuilder AddTaskEndpoint(this IEndpointRouteBuilder a }); // update status - taskEndpoint.MapPatch("/{taskId:guid}/{status}", HandleUpdateTaskStatus) + authEndpoint.MapPatch("/{taskId:guid}/{status}", HandleUpdateTaskStatus) .WithName("Update Task Status") .WithOpenApi(x => { @@ -44,7 +44,7 @@ public static IEndpointRouteBuilder AddTaskEndpoint(this IEndpointRouteBuilder a }); // update task info - taskEndpoint.MapPut("/{taskId:guid}/info", HandleUpdateTaskInformation) + authEndpoint.MapPut("/{taskId:guid}/info", HandleUpdateTaskInformation) .WithName("Update Task") .WithOpenApi(x => { @@ -53,7 +53,7 @@ public static IEndpointRouteBuilder AddTaskEndpoint(this IEndpointRouteBuilder a }); // add collaborator to task - taskEndpoint.MapPatch("/{taskId:guid}/collaborators/{collaboratorId:guid}", HandleAddCollaboratorToTask) + authEndpoint.MapPatch("/{taskId:guid}/collaborators/{collaboratorId:guid}", HandleAddCollaboratorToTask) .WithName("Add collaborator to task") .WithOpenApi(x => { @@ -62,7 +62,7 @@ public static IEndpointRouteBuilder AddTaskEndpoint(this IEndpointRouteBuilder a }); // delete task - taskEndpoint.MapDelete("/{taskId:guid}", HandleDeleteTask) + authEndpoint.MapDelete("/{taskId:guid}", HandleDeleteTask) .WithName("Delete task by id") .WithOpenApi(x => { @@ -71,7 +71,7 @@ public static IEndpointRouteBuilder AddTaskEndpoint(this IEndpointRouteBuilder a }); // remove collaborator from task - taskEndpoint.MapPatch("/{taskId:guid}/{collaboratorId:guid}", HandleRemoveCollaboratorToTask) + authEndpoint.MapPatch("/{taskId:guid}/{collaboratorId:guid}", HandleRemoveCollaboratorToTask) .WithName("Remove collaborator to task") .WithOpenApi(x => { @@ -79,8 +79,6 @@ public static IEndpointRouteBuilder AddTaskEndpoint(this IEndpointRouteBuilder a return x; }); - - return app; } @@ -95,19 +93,19 @@ private static async Task HandleRemoveCollaboratorToTask( { CheckAuthorizationAsAdministrator(context); if (await taskRepository.GetTaskById(taskId) is not { } task) - return Results.BadRequest(new BaseResponse("The request could not be continued because no matching tasks were found", false)); + return Results.BadRequest(new BaseSuccessResponse("The request could not be continued because no matching tasks were found", false)); if (await userRepository.GetUserById(collaboratorId) is not { } collaborator) - return Results.BadRequest(new BaseResponse("The request could not be continued because no matching collaborator were found", false)); + return Results.BadRequest(new BaseSuccessResponse("The request could not be continued because no matching collaborator were found", false)); if (!task.Collaborators.Any(c => c.Id == collaboratorId!)) - return Results.BadRequest(new BaseResponse("Unable to update task because no matching task was found", false)); + return Results.BadRequest(new BaseSuccessResponse("Unable to update task because no matching task was found", false)); context.Response.Headers.Location = $"{context.Request.Scheme}://{context.Request.Host}/{context.Request.Path}/{task.Id}"; task.RemoveCollaboratorFromTask(collaborator); taskRepository.UpdateTask(task); - return Results.Ok(new BaseResponse("Collaborator successfully removed from task")); + return Results.Ok(new BaseSuccessResponse("Collaborator successfully removed from task")); } private static async Task HandleDeleteTask( @@ -118,11 +116,11 @@ private static async Task HandleDeleteTask( CheckAuthorizationAsAdministrator(context); if (await taskRepository.GetTaskById(taskId) is not { } task) { - return Results.BadRequest(new BaseResponse("The request could not be continued because no matching tasks were found", false)); + return Results.BadRequest(new BaseSuccessResponse("The request could not be continued because no matching tasks were found", false)); } taskRepository.DeleteTask(taskId); - return Results.Ok(new BaseResponse("task deleted successfully")); + return Results.Ok(new BaseSuccessResponse("task deleted successfully")); } private static async Task HandleAddCollaboratorToTask( @@ -134,19 +132,19 @@ private static async Task HandleAddCollaboratorToTask( UpdateTaskRequest request) { CheckAuthorizationAsAdministrator(context); - if (await taskRepository.GetTaskById(taskId) is not { } task) - return Results.BadRequest(new BaseResponse("Unable to update task because no matching task was found", false)); + { + return Results.BadRequest(new BaseSuccessResponse("Unable to update task because no matching task was found", false)); + } if (await userRepository.GetUserById(collaboratorId) is not { } collaborator) - return Results.BadRequest(new BaseResponse($"Collaborator with id {collaboratorId} was not found!", false)); - - if (collaborator.IsAdmin) - return Results.BadRequest(new BaseResponse("Only collaborators can be added to the task.", false)); + { + return Results.BadRequest(new BaseSuccessResponse($"Collaborator with id {collaboratorId} was not found!", false)); + } if (task.Collaborators.Contains(collaborator)) { - return Results.BadRequest(new BaseResponse( + return Results.BadRequest(new BaseSuccessResponse( $"The collaborator with id {collaboratorId} is already participating in this task", false )); @@ -157,7 +155,7 @@ private static async Task HandleAddCollaboratorToTask( context.Response.Headers.Location = $"{context.Request.Scheme}://{context.Request.Host}/{context.Request.Path}/{task.Id}"; - return Results.Ok(new BaseResponse("collaborator successfully added to task")); + return Results.Ok(new BaseSuccessResponse("collaborator successfully added to task")); } private static async Task HandleUpdateTaskInformation( @@ -169,7 +167,7 @@ private static async Task HandleUpdateTaskInformation( CheckAuthorizationAsAdministrator(context); if (await taskRepository.GetTaskById(taskId) is not { } task) { - return Results.BadRequest(new BaseResponse("Unable to update task because no matching task was found", false)); + return Results.BadRequest(new BaseSuccessResponse("Unable to update task because no matching task was found", false)); } task.UpdateTask( @@ -182,7 +180,7 @@ private static async Task HandleUpdateTaskInformation( context.Response.Headers.Location = $"{context.Request.Scheme}://{context.Request.Host}/{context.Request.Path}/{taskId}"; - return Results.Ok(new BaseResponse("task information updated successfully")); + return Results.Ok(new BaseSuccessResponse("task information updated successfully")); } private static async Task HandleUpdateTaskStatus( @@ -192,12 +190,14 @@ private static async Task HandleUpdateTaskStatus( ITaskRepository taskRepository) { CheckAuthorizationAsAdministrator(context); - if (await taskRepository.GetTaskById(taskId) is not { } task) return Results.NoContent(); + if (await taskRepository.GetTaskById(taskId) is not { } task) + return Results.NoContent(); task.UpdateTaskStatus(status); taskRepository.UpdateTask(task); - context.Response.Headers.Location = "{context.Request.Scheme}://{context.Request.Host}/{context.Request.Path}/{task.Id}"; + context.Response.Headers.Location = + $"{context.Request.Scheme}://{context.Request.Host}/{context.Request.Path}/{task.Id}"; return Results.Ok("task status updated successfully"); } @@ -221,9 +221,6 @@ await userRepository.GetUserById(id) ) ).ToList(); - var hasAdmin = collaborators.FindAll(c => c.IsAdmin).ToList(); - if (hasAdmin.Count != 0) return Results.BadRequest(new BaseResponse("Only collaborators can be added to the task.", false)); - task.AddCollaboratorsToTask(collaborators); taskRepository.AddTask(task); diff --git a/src/HigiaServer.API/Endpoints/UserEndpoint.cs b/src/HigiaServer.API/Endpoints/UserEndpoint.cs deleted file mode 100644 index 2837690..0000000 --- a/src/HigiaServer.API/Endpoints/UserEndpoint.cs +++ /dev/null @@ -1,56 +0,0 @@ -using AutoMapper; - -using HigiaServer.Application.Contracts.Requests; -using HigiaServer.Application.Contracts.Responses; -using HigiaServer.Application.Errors; -using HigiaServer.Application.Repositories; - -namespace HigiaServer.API.Endpoints; - -public static class UserEndpoint -{ - public static IEndpointRouteBuilder AddUserEndpoint(this IEndpointRouteBuilder app) - { - var userEndpoint = app.MapGroup("higia-server/api/user").WithTags("User"); - - // update info user - userEndpoint.MapPut("/{userId:guid}", HandleUpdaterInfoUser) - .WithName("Update user information") - .WithOpenApi(x => - { - x.Summary = "Update user information"; - return x; - }); - - return app; - } - - #region - - public static async Task HandleUpdaterInfoUser( - Guid userId, - UpdateInfoUserRequest request, - HttpContext context, - IUserRepository userRepository, - IMapper mapper - ) - { - if (!context.User!.Identity!.IsAuthenticated) throw new UnauthenticatedException(); - if (await userRepository.GetUserById(userId) is not { } user) - { - return Results.BadRequest(new BaseResponse($"User with id {userId} was not found!", false)); - } - - // update user information - user.UpdateInfoUser( - name: request.Name, - email: request.Email, - number: request.Number - ); - - await userRepository.UpdateUser(user); - return Results.Ok(new BaseResponse("user information updated successfully", false)); - } - - #endregion -} \ No newline at end of file diff --git a/src/HigiaServer.Application/Contracts/Requests/UpdateInfoUserRequest.cs b/src/HigiaServer.Application/Contracts/Requests/UpdateInfoUserRequest.cs deleted file mode 100644 index 9c116e1..0000000 --- a/src/HigiaServer.Application/Contracts/Requests/UpdateInfoUserRequest.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace HigiaServer.Application.Contracts.Requests; - -public class UpdateInfoUserRequest(string? name, string? email, string? number) -{ - public string? Name { get; private set; } = name; - [EmailAddress] public string? Email { get; private set; } = email; - public string? Number { get; private set; } = number; -} diff --git a/src/HigiaServer.Application/Contracts/Responses/BaseSuccessResponse.cs b/src/HigiaServer.Application/Contracts/Responses/BaseSuccessResponse.cs index bc5a5da..e46784a 100644 --- a/src/HigiaServer.Application/Contracts/Responses/BaseSuccessResponse.cs +++ b/src/HigiaServer.Application/Contracts/Responses/BaseSuccessResponse.cs @@ -1,6 +1,6 @@ namespace HigiaServer.Application.Contracts.Responses; -public class BaseResponse(string message, bool success = true) +public class BaseSuccessResponse(string message, bool success = true) { public bool Success { get; private set; } = success; public string Message { get; private set; } = message; diff --git a/src/HigiaServer.Application/Contracts/Responses/BaseResponseWithT.cs b/src/HigiaServer.Application/Contracts/Responses/SuccessResponseWithT.cs similarity index 100% rename from src/HigiaServer.Application/Contracts/Responses/BaseResponseWithT.cs rename to src/HigiaServer.Application/Contracts/Responses/SuccessResponseWithT.cs diff --git a/src/HigiaServer.Application/Repositories/IUserRepository.cs b/src/HigiaServer.Application/Repositories/IUserRepository.cs index 819d8a1..ee560f5 100644 --- a/src/HigiaServer.Application/Repositories/IUserRepository.cs +++ b/src/HigiaServer.Application/Repositories/IUserRepository.cs @@ -7,5 +7,4 @@ public interface IUserRepository void AddUser(User user); Task GetUserByEmail(string email); Task GetUserById(Guid userId); - System.Threading.Tasks.Task UpdateUser(User user); } diff --git a/src/HigiaServer.Domain/Entities/RecordTask.cs b/src/HigiaServer.Domain/Entities/RecordTask.cs deleted file mode 100644 index 50c62dc..0000000 --- a/src/HigiaServer.Domain/Entities/RecordTask.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System; - -namespace HigiaServer.Domain.Entities; - -public class RecordTask -{ - private TimeSpan _totalTimeSpend = TimeSpan.Zero; - - #region [Properties] - - public DateTime CreateDate { get; private set; } = DateTime.Now; - public DateTime? StartDate { get; private set; } - public DateTime? CloseDate { get; private set; } - public DateTime? PausedTime { get; private set; } - public TimeSpan TotalTimeSpend - { - get { return CalculateTotalTimeSpent(); } - private set { _totalTimeSpend = value; } - } - - public Task? Task { get; private set; } - - #endregion - - #region [Public Methods] - - public void RecordActiveTask() - { - if (PausedTime.HasValue) - { - _totalTimeSpend += DateTime.Now - PausedTime.Value; - PausedTime = null; - } - else if (!StartDate.HasValue) - { - StartDate = DateTime.Now; - } - } - - public void RecordPausedTask() - { - if (StartDate.HasValue && !PausedTime.HasValue) - { - PausedTime = DateTime.Now; - } - } - - public void RecordCompleteTask() - { - if (StartDate.HasValue) - { - if (PausedTime.HasValue) - { - _totalTimeSpend += PausedTime.Value - StartDate.Value; - } - else - { - _totalTimeSpend += DateTime.Now - StartDate.Value; - } - - CloseDate = DateTime.Now; - } - } - - private TimeSpan CalculateTotalTimeSpent() - { - if (StartDate.HasValue) - { - if (PausedTime.HasValue) - { - return _totalTimeSpend + (PausedTime.Value - StartDate.Value); - } - else if (CloseDate.HasValue) - { - return _totalTimeSpend; - } - else - { - return _totalTimeSpend + (DateTime.Now - StartDate.Value); - } - } - - return _totalTimeSpend; - } - - #endregion -} - diff --git a/src/HigiaServer.Domain/Entities/Task.cs b/src/HigiaServer.Domain/Entities/Task.cs index 9c963f5..44cdba4 100644 --- a/src/HigiaServer.Domain/Entities/Task.cs +++ b/src/HigiaServer.Domain/Entities/Task.cs @@ -1,25 +1,21 @@ -using System.Security.Cryptography; - using HigiaServer.Domain.Enums; namespace HigiaServer.Domain.Entities; -public class Task(string title, string[] coordinates, UrgencyLevel urgencyLevel, string? description) +public class Task( + string title, + string[] coordinates, + UrgencyLevel urgencyLevel, + string? description +) { - #region [Properties] - public Guid Id { get; private set; } = Guid.NewGuid(); public string Title { get; private set; } = title; public UrgencyLevel UrgencyLevel { get; private set; } = urgencyLevel; public string? Description { get; private set; } = description; public string[] Coordinates { get; private set; } = coordinates; public Status Status { get; private set; } = Status.New; - public List Collaborators { get; private set; } = []; - public RecordTask RecordTask { get; private set; } = new RecordTask(); - - #endregion - - #region [Public Methods] + public List Collaborators { get; } = []; public void UpdateTask(string? title = null, string? description = null, string[]? coordinates = null) { @@ -34,47 +30,5 @@ public void UpdateTask(string? title = null, string? description = null, string[ public void RemoveCollaboratorFromTask(User user) => Collaborators.Remove(user); - public void UpdateTaskStatus(Status newStatus) - { - if(newStatus == Status.New) return; - - switch (newStatus) - { - case Status.Active: StartTask(); break; - case Status.Paused: PauseTask(); break; - case Status.Complete: CompleteTask(); break; - } - } - - #endregion - - #region [Private Methods] - private void StartTask() - { - if(Status == Status.New) - { - Status = Status.Active; - RecordTask.RecordActiveTask(); - } - } - - private void PauseTask() - { - if(Status == Status.Active) - { - Status = Status.Paused; - RecordTask.RecordPausedTask(); - } - } - - private void CompleteTask() - { - if(Status == Status.Active || Status == Status.Paused) - { - Status = Status.Complete; - RecordTask.RecordCompleteTask(); - } - } - - #endregion -} \ No newline at end of file + public void UpdateTaskStatus(Status newStatus) => Status = newStatus; +} diff --git a/src/HigiaServer.Domain/Entities/User.cs b/src/HigiaServer.Domain/Entities/User.cs index efb88b1..0cb4214 100644 --- a/src/HigiaServer.Domain/Entities/User.cs +++ b/src/HigiaServer.Domain/Entities/User.cs @@ -3,17 +3,10 @@ namespace HigiaServer.Domain.Entities; public class User(bool isAdmin, string name, string email, string password, string? number = null) { public Guid Id { get; init; } = Guid.NewGuid(); - public string Name { get; private set; } = name.Trim(); + public string Name { get; private set; } = name; public string Email { get; private set; } = email; public string Password { get; private set; } = password; public bool IsAdmin { get; private set; } = isAdmin; - public string? Number { get; private set; } = number?.Trim(); + public string? Number { get; private set; } = number; public List? Tasks { get; private set; } = isAdmin ? [] : null; - - public void UpdateInfoUser(string? name, string? email, string? number) - { - Name = name?.Trim() ?? Name; - Email = email ?? Email; - Number = number ?? Number; - } } diff --git a/src/HigiaServer.Domain/Enums/Status.cs b/src/HigiaServer.Domain/Enums/Status.cs index 634e7f6..528317d 100644 --- a/src/HigiaServer.Domain/Enums/Status.cs +++ b/src/HigiaServer.Domain/Enums/Status.cs @@ -5,5 +5,5 @@ public enum Status New = 0, Active = 1, Paused = 2, - Complete = 3 + Closed = 3 } diff --git a/src/HigiaServer.Infra/DbContext/HigiaServerContext.cs b/src/HigiaServer.Infra/DbContext/HigiaServerContext.cs index d3ec8ea..0758c47 100644 --- a/src/HigiaServer.Infra/DbContext/HigiaServerContext.cs +++ b/src/HigiaServer.Infra/DbContext/HigiaServerContext.cs @@ -7,7 +7,6 @@ namespace HigiaServer.Infra.DbContext; public class HigiaServerContext : Microsoft.EntityFrameworkCore.DbContext { public DbSet Tasks { get; set; } - public DbSet RecordTasks { get; set; } public DbSet Users { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) diff --git a/src/HigiaServer.Infra/Repositories/UserRepository.cs b/src/HigiaServer.Infra/Repositories/UserRepository.cs index a10be32..f9e623d 100644 --- a/src/HigiaServer.Infra/Repositories/UserRepository.cs +++ b/src/HigiaServer.Infra/Repositories/UserRepository.cs @@ -20,10 +20,4 @@ public async void AddUser(User user) public async Task GetUserById(Guid userId) => await _context.Users.SingleOrDefaultAsync(x => x.Id == userId); - - public async System.Threading.Tasks.Task UpdateUser(User user) - { - _context.Update(user); - await _context.SaveChangesAsync(); - } }