mirror of
https://github.com/GCMatters/hermes.git
synced 2026-02-04 21:50:12 +01:00
249 lines
9.8 KiB
C#
249 lines
9.8 KiB
C#
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using Microsoft.EntityFrameworkCore;
|
|
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();
|
|
|
|
// POST /api/auth/login
|
|
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
|
|
});
|
|
});
|
|
|
|
// POST /api/auth/logout
|
|
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 });
|
|
});
|
|
|
|
// GET /api/auth/my_account
|
|
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);
|
|
|
|
// GET /api/auth/my_events
|
|
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);
|
|
}
|
|
|
|
|
|
});
|
|
|
|
// POST /api/auth/add_skill
|
|
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 powinni 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 = "You already have this skill!" }, statusCode: 400);
|
|
}
|
|
|
|
return Results.Json(new { message = "Skill added successfully!" }, statusCode: 201);
|
|
});
|
|
|
|
// POST /api/auth/remove_skill
|
|
group.MapPost("/remove_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 powinni móc usuwać 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 ma już taki skill. Jeżeli nie ma, to nie ma sensu usuwać czegoś, czego nie ma.
|
|
VolunteerSkill? vs = await context.VolunteerSkills.FirstOrDefaultAsync(v => v.UserId == user.UserId && v.SkillId == dto.Skill);
|
|
if (vs is not null)
|
|
{
|
|
// Ma - zatem musimy usunąć otrzymany VolunteerSkill z bazy
|
|
VolunteerSkill newVs = dto.ToVolunteerSkillEntity(user.UserId);
|
|
|
|
await context.VolunteerSkills.Where(v => v.SkillId == dto.Skill)
|
|
.ExecuteDeleteAsync();
|
|
|
|
}
|
|
else
|
|
{
|
|
// Nie ma - (ta para UserId <-> SkillId nie istnieje w bazie). Zwracamy błąd.
|
|
return Results.Json(new { message = "You don't have this skill" }, statusCode: 400);
|
|
}
|
|
|
|
return Results.Json(new { message = "Skill deleted successfully!" }, statusCode: 201);
|
|
});
|
|
|
|
// GET /api/auth/skills
|
|
group.MapGet("/skills", async (HttpContext httpContext, ApplicationDbContext context, GeneralUseHelpers guh) =>
|
|
{
|
|
// Uzyskaj użytkownika z tokenu
|
|
Token? token = await guh.GetTokenFromHTTPContext(httpContext);
|
|
User? user = await guh.GetUserFromToken(token);
|
|
|
|
// Sprawdź, czy użytkownik istnieje i nie jest organizacją
|
|
if (user == null || user.IsOrganisation)
|
|
{
|
|
return Results.Json(new { message = "Unauthorized" }, statusCode: 401);
|
|
}
|
|
|
|
// Pobierz skille wolontariusza
|
|
var skills = await context.VolunteerSkills
|
|
.Where(vs => vs.UserId == user.UserId)
|
|
.Include(vs => vs.Skill)
|
|
.Select(vs => new
|
|
{
|
|
skillId = vs.Skill.SkillId,
|
|
skillName = vs.Skill.Name
|
|
})
|
|
.ToListAsync();
|
|
|
|
return Results.Json(skills);
|
|
});
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|