From f2ccde2ea68667fc87611adf05db77655e1a2dd9 Mon Sep 17 00:00:00 2001 From: AleksDw Date: Sat, 31 May 2025 02:19:01 +0200 Subject: [PATCH] Join, leave, registrations endpoints todo: remove smb from event endpoint --- WebApp/DTOs/EventRegistrationDto.cs | 11 ++ .../Endpoints/EventRegistrationEndpoints.cs | 110 ++++++++++++++++++ WebApp/Mapping/EventRegistrationMapping.cs | 17 +++ WebApp/Program.cs | 1 + 4 files changed, 139 insertions(+) create mode 100644 WebApp/DTOs/EventRegistrationDto.cs create mode 100644 WebApp/Endpoints/EventRegistrationEndpoints.cs create mode 100644 WebApp/Mapping/EventRegistrationMapping.cs diff --git a/WebApp/DTOs/EventRegistrationDto.cs b/WebApp/DTOs/EventRegistrationDto.cs new file mode 100644 index 0000000..a4331a2 --- /dev/null +++ b/WebApp/DTOs/EventRegistrationDto.cs @@ -0,0 +1,11 @@ +using System.ComponentModel.DataAnnotations; +using WebApp.Entities; + +namespace WebApp.DTOs; + +// Output values in JSON file +public record class EventRegistrationDto( + int EventId, + int UserId, + DateTime RegisteredAt + ); diff --git a/WebApp/Endpoints/EventRegistrationEndpoints.cs b/WebApp/Endpoints/EventRegistrationEndpoints.cs new file mode 100644 index 0000000..cec14f5 --- /dev/null +++ b/WebApp/Endpoints/EventRegistrationEndpoints.cs @@ -0,0 +1,110 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.EntityFrameworkCore; +using System.Security.Cryptography; +using WebApp.Data; +using WebApp.DTOs; +using WebApp.Entities; +using WebApp.Mapping; + +namespace WebApp.Endpoints +{ + public static class EventsRegistrationEndpoints + { + const string GetEventEndpointRegistrationName = "GetEventRegistration"; + + public static RouteGroupBuilder MapEventsRegistrationEndpoints(this WebApplication app) + { + var group = app.MapGroup("api/events") + .WithParameterValidation(); + + // POST /api/events/join/{id} + group.MapPost("/join/{id}", + async (int id, ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) => + { + Event? Eve = await dbContext.Events.FindAsync(id); + if (Eve is null) + return Results.Json(new { success = false, error_msg = "Event not found." }); + + Token? token = await guhf.GetTokenFromHTTPContext(httpContext); + User? user = await guhf.GetUserFromToken(token); + + if (user is null || user.IsOrganisation) + return Results.Json(new { success = false, error_msg = "Unauthorized or organisations cannot register for events." }); + + if (await dbContext.EventRegistrations.AnyAsync(er => er.UserId == user.UserId && er.EventId == id)) + return Results.Json(new { success = false, error_msg = "You are already registered for this event." }); + + if (Eve.EventDate < DateTime.UtcNow) + return Results.Json(new { success = false, error_msg = "This event has already ended." }); + + EventRegistration registration = new EventRegistration + { + UserId = user.UserId, + EventId = id, + RegisteredAt = DateTime.UtcNow + }; + dbContext.EventRegistrations.Add(registration); + await dbContext.SaveChangesAsync(); + + return Results.Json(new { success = true }); + }); + + // POST /api/events/leave/{id} + group.MapPost("/leave/{id}", + async (int id, ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) => + { + Event? Eve = await dbContext.Events.FindAsync(id); + if (Eve is null) + return Results.Json(new { success = false, error_msg = "Event not found." }); + + Token? token = await guhf.GetTokenFromHTTPContext(httpContext); + User? user = await guhf.GetUserFromToken(token); + + if (user is null) + return Results.Json(new { success = false, error_msg = "Unauthorized." }); + + if (!await dbContext.EventRegistrations.AnyAsync(er => er.UserId == user.UserId && er.EventId == id)) + return Results.Json(new { success = false, error_msg = "You are not registered for this event." }); + + if (Eve.EventDate < DateTime.UtcNow) + return Results.Json(new { success = false, error_msg = "This event has already ended." }); + + EventRegistration? registration = await dbContext.EventRegistrations + .FirstOrDefaultAsync(er => er.UserId == user.UserId && er.EventId == id); + + dbContext.EventRegistrations.Remove(registration); + await dbContext.SaveChangesAsync(); + + return Results.Json(new { success = true }); + }); + + // GET /api/events/registrations/{id} + group.MapGet("/registrations/{id}", + async (int id, ApplicationDbContext dbContext, HttpContext httpContext, GeneralUseHelpers guhf) => + { + Event? Eve = await dbContext.Events.FindAsync(id); + if (Eve is null) + return Results.Json(new { success = false, error_msg = "Event not found." }); + + Token? token = await guhf.GetTokenFromHTTPContext(httpContext); + Organisation? org = await guhf.GetOrganisationFromToken(token); + if (org is null || org.OrganisationId != Eve.OrganisationId) + return Results.Json(new { success = false, error_msg = "Unauthorized." }); + + var registrations = await dbContext.EventRegistrations + .Where(er => er.EventId == id) + .Select(er => er.ToEventRegistrationDto()) + .ToListAsync(); + + return Results.Json(new + { + success = true, + registrations + }); + }); + + return group; + } + } +} diff --git a/WebApp/Mapping/EventRegistrationMapping.cs b/WebApp/Mapping/EventRegistrationMapping.cs new file mode 100644 index 0000000..5f76622 --- /dev/null +++ b/WebApp/Mapping/EventRegistrationMapping.cs @@ -0,0 +1,17 @@ +using WebApp.DTOs; +using WebApp.Entities; + +namespace WebApp.Mapping +{ + public static class EventRegistrationMapping + { + public static EventRegistrationDto ToEventRegistrationDto(this EventRegistration er) + { + return new EventRegistrationDto( + er.EventId, + er.UserId, + er.RegisteredAt + ); + } + } +} diff --git a/WebApp/Program.cs b/WebApp/Program.cs index d1fd2dc..e5585ae 100644 --- a/WebApp/Program.cs +++ b/WebApp/Program.cs @@ -53,5 +53,6 @@ app.UseRouting(); // Enables routing to match incoming request to endpoints app.MapEventsEndpoints(); app.MapOrganizationsEndpoints(); app.MapAuthEndpoints(); +app.MapEventsRegistrationEndpoints(); app.Run();