Files
hermes/WebApp/Endpoints/AuthEndpoints.cs

178 lines
6.7 KiB
C#

using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.EntityFrameworkCore;
using System.Runtime.Intrinsics.Arm;
using System.Security.Cryptography;
using System.Text;
using WebApp.Data;
using WebApp.DTOs;
using WebApp.Entities;
using WebApp.Mapping;
namespace WebApp.Endpoints
{
public static class AuthEndpoints
{
public static RouteGroupBuilder MapAuthEndpoints(this WebApplication app)
{
const string GetUserEndpointName = "GetUser";
var group = app.MapGroup("api/auth")
.WithParameterValidation();
group.MapPost("/login", async (LoginDto dto, ApplicationDbContext context, GeneralUseHelpers guh) =>
{
var user = await context.WebUsers.FirstOrDefaultAsync(u => u.Email == dto.Email);
string hashedPassword = HashPasswordSHA512(dto.Password);
if (user == null || user.Password != hashedPassword)
{
return Results.Json(new { message = "Wrong email or password." }, statusCode: 401);
}
var token = await guh.CreateNewToken(user.UserId);
return Results.Ok(new
{
message = "Login successful.",
token = token.Value
});
});
group.MapPost("/logout", async (HttpContext httpContext, GeneralUseHelpers guh) =>
{
var token = await guh.GetTokenFromHTTPContext(httpContext);
if (token == null)
{
return Results.Json(new { message = "No valid token found." }, statusCode: 401);
}
await guh.DeleteToken(token);
httpContext.Response.Cookies.Delete("token");
return Results.Ok(new { success = true });
});
group.MapGet("/my_account", async (HttpContext httpContext, GeneralUseHelpers guh) =>
{
var token = await guh.GetTokenFromHTTPContext(httpContext);
if(token == null)
{
return Results.Json(new { message = "No valid token found." }, statusCode: 401);
}
User? user = await guh.GetUserFromToken(token);
if(user == null)
{
return Results.Json(new {message = "No user found."}, statusCode: 404);
}
Organisation? org = await guh.GetOrganisationFromUserId(user.UserId);
if (org is not null) return Results.Ok(user.ToUserSummaryWithOrgIdDto(org.OrganisationId));
return Results.Ok(user.ToUserSummaryDto());
})
.WithName(GetUserEndpointName);
group.MapGet("/my_events", async (HttpContext httpContext, GeneralUseHelpers guh, ApplicationDbContext context) =>
{
var token = await guh.GetTokenFromHTTPContext(httpContext);
if (token == null)
{
return Results.Json(new { message = "No valid token found." }, statusCode: 401);
}
User? user = await guh.GetUserFromToken(token);
if (user == null)
{
return Results.Json(new { message = "No user found." }, statusCode: 404);
}
if(!user.IsOrganisation)
{
var events = await context.EventRegistrations
.Where(er => er.UserId == user.UserId)
.Select(er => er.Event.ToEventSummaryNoErDto())
.ToListAsync();
return Results.Ok(events);
}
else
{
var org = await context.Organisations.FirstOrDefaultAsync(o => o.UserId == user.UserId);
if(org == null)
{
return Results.Json(new { message = "No organisation found for this user." }, statusCode: 404);
}
var events = await context.Events
.Where(e => e.OrganisationId == org.OrganisationId)
.Select(e => e.ToEventSummaryDto())
.ToListAsync();
return Results.Ok(events);
}
});
group.MapPost("/add_skill", async (SingleSkillDto dto, HttpContext httpContext, ApplicationDbContext context, GeneralUseHelpers guh) =>
{
// Uzyskaj użytkownika z tokenu
Token? token = await guh.GetTokenFromHTTPContext(httpContext);
User? user = await guh.GetUserFromToken(token);
// Tylko wolontariusze powinno móc dodawać swoje skille
if (user == null || user.IsOrganisation) {
return Results.Json(new { message = "Unauthorized" }, statusCode: 401);
}
// Szukamy skilla w bazie o ID takim, jak w otrzymanym DTO
Skill? skill = await context.Skills.FindAsync(dto.Skill);
if (skill is null)
{
return Results.Json(new { message = "Skill not found" }, statusCode: 404);
}
// Sprawdzamy, czy ten użytkownik nie ma już takiego skilla. Jeżeli ma, nie ma sensu dodawać go kilkukrotnie.
VolunteerSkill? vs = await context.VolunteerSkills.FirstOrDefaultAsync(v => v.UserId == user.UserId && v.SkillId == dto.Skill);
if (vs is null)
{
// Nie ma - zatem musimy dodać nowy VolunteerSkill do bazy
VolunteerSkill newVs = dto.ToVolunteerSkillEntity(user.UserId);
context.VolunteerSkills.Add(newVs);
await context.SaveChangesAsync();
} else
{
// Ma - (ta para UserId <-> SkillId już istnieje w bazie) użytkownik już ma ten skill
return Results.Json(new { message = "User already has this skill" }, statusCode: 400);
}
return Results.Json(new { message = "Skill added successfully!" }, statusCode: 201);
});
return group;
}
static string HashPasswordSHA512(string password)
{
using (var sha512 = SHA512.Create())
{
byte[] bytes = Encoding.ASCII.GetBytes(password);
byte[] hash = sha512.ComputeHash(bytes);
string hashstring = BitConverter.ToString(hash).Replace("-", "").ToLower();
return hashstring;
}
}
}
}