Mizuki/Controllers/LoginController.cs
2025-01-13 00:11:40 +01:00

105 lines
No EOL
3 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Mizuki.Dtos;
using Mizuki.Services;
using Mizuki.Validators;
namespace Mizuki.Controllers;
/// <summary>
/// The login controller for Mizuki.
/// </summary>
[ApiController]
[Route("/api/user")]
public class LoginController(
UserService userService,
LoginService loginService,
LoginDataValidator loginDataValidator) : ControllerBase
{
/// <summary>
/// Logs into Mizuki as a given user.
/// </summary>
/// <param name="dto">The login data dto.</param>
/// <returns>Redirect.</returns>
[HttpPost]
[Route("login")]
public async Task<RedirectResult> Login(
[FromForm] LoginDataDto dto)
{
if (!await userService.CheckPasswordForUser(dto.Username, dto.Password))
{
return Redirect("/login?error=Invalid username or password.");
}
var user = await userService.GetUserForUsername(dto.Username);
await loginService.LoginAsUser(user);
Console.WriteLine($"Logged in as {user.Username}");
return Redirect("/");
}
/// <summary>
/// Logs out of Mizuki.
/// </summary>
/// <returns>Redirect.</returns>
[Authorize]
[Route("logout")]
public async Task<RedirectResult> Logout()
{
await loginService.Logout();
return Redirect("/");
}
/// <summary>
/// Registers a new user in Mizuki.
/// </summary>
/// <param name="dto">The login data dto.</param>
/// <returns>Redirect.</returns>
[Route("register")]
[HttpPost]
public async Task<RedirectResult> Register(
[FromForm] LoginDataDto dto)
{
if (await userService.UsernameTaken(dto.Username))
return Redirect("/register?error=This user already exists.");
var result = await loginDataValidator.ValidateAsync(dto);
if (!result.IsValid)
{
if (result.Errors.Any(e => e.PropertyName == "Username"))
return Redirect("/register?error=Invalid username.");
if (result.Errors.Any(e => e.PropertyName == "Password"))
return Redirect("/register?error=Invalid password.");
}
await userService.CreateUser(
dto.Username,
dto.Password);
return Redirect("/");
}
/// <summary>
/// Checks whether we have logged in.
/// </summary>
/// <returns>Either an OK or a forbidden result.</returns>
[Route("check")]
[HttpGet]
public async Task<Results<Ok, ForbidHttpResult>> Check()
{
try
{
var user = await loginService.GetActiveUser();
Console.WriteLine($"Get active user returned {user.Username}");
return TypedResults.Ok();
}
catch
{
Console.WriteLine($"Get active user returned FORBID");
return TypedResults.Forbid();
}
}
}