From 72bb2b24efb45a762e92d71baf92840754749203 Mon Sep 17 00:00:00 2001
From: Cucumberrbob <128094686+Cucumberrbob@users.noreply.github.com>
Date: Thu, 6 Mar 2025 21:16:25 +0000
Subject: [PATCH] Add openapi compatible xmldoc to `AuthController`
# Conflicts:
# server/RdtClient.Web/Controllers/AuthController.cs
---
.../Controllers/AuthController.cs | 153 +++++++++++++++---
1 file changed, 135 insertions(+), 18 deletions(-)
diff --git a/server/RdtClient.Web/Controllers/AuthController.cs b/server/RdtClient.Web/Controllers/AuthController.cs
index 9a3f6ee..2fd4aeb 100644
--- a/server/RdtClient.Web/Controllers/AuthController.cs
+++ b/server/RdtClient.Web/Controllers/AuthController.cs
@@ -2,15 +2,28 @@
using Microsoft.AspNetCore.Mvc;
using RdtClient.Data.Enums;
using RdtClient.Service.Services;
+using System.ComponentModel.DataAnnotations;
namespace RdtClient.Web.Controllers;
+///
+/// Handles authentication and user management operations
+///
[Route("Api/Authentication")]
public class AuthController(Authentication authentication, Settings settings) : Controller
{
+ ///
+ /// Checks if the current session is authenticated
+ ///
+ /// Session is valid and authenticated, or authentication is disabled
+ /// System requires initial setup - no users exist in the database
+ /// Session is not authenticated
[AllowAnonymous]
[Route("IsLoggedIn")]
[HttpGet]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status402PaymentRequired, Type = typeof(ProblemDetails))]
+ [ProducesResponseType(StatusCodes.Status403Forbidden, Type = typeof(ProblemDetails))]
public async Task IsLoggedIn()
{
if (Settings.Get.General.AuthenticationType == AuthenticationType.None)
@@ -24,18 +37,33 @@ public class AuthController(Authentication authentication, Settings settings) :
if (user == null)
{
- return StatusCode(402, "Setup required");
+ return Problem(detail: "Setup required", statusCode: StatusCodes.Status402PaymentRequired);
}
-
- return StatusCode(403);
+
+ return Problem(detail: "Login required", statusCode: StatusCodes.Status403Forbidden);
}
-
+
return Ok();
}
+ ///
+ /// Creates the initial account for the system
+ ///
+ ///
+ /// This endpoint can only be used when no account exists.
+ /// It creates the account and automatically logs in.
+ ///
+ /// Registration details for the new account
+ /// Account created successfully and user is logged in
+ /// Invalid request - username/password missing or validation failed
+ /// Cannot create account - a user already exists in system
[AllowAnonymous]
[Route("Create")]
[HttpPost]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized, Type = typeof(ProblemDetails))]
public async Task Create([FromBody] AuthControllerLoginRequest? request)
{
if (request == null)
@@ -47,29 +75,43 @@ public class AuthController(Authentication authentication, Settings settings) :
if (user != null)
{
- return StatusCode(401);
+ return Problem(detail: "User already exists - only one user allowed", statusCode: StatusCodes.Status401Unauthorized);
}
-
+
if (String.IsNullOrEmpty(request.UserName) || String.IsNullOrEmpty(request.Password))
{
- return BadRequest("Invalid UserName or Password");
+ return Problem(detail: "Empty UserName or Password", statusCode: StatusCodes.Status400BadRequest);
}
var registerResult = await authentication.Register(request.UserName, request.Password);
if (!registerResult.Succeeded)
{
- return BadRequest(registerResult.Errors.First().Description);
+ return Problem(detail: registerResult.Errors.First().Description, statusCode: StatusCodes.Status400BadRequest);
}
-
+
await authentication.Login(request.UserName, request.Password);
return Ok();
}
+ ///
+ /// Configures the provider settings for the application
+ ///
+ ///
+ /// This endpoint can only be used when no provider is configured.
+ /// It sets up the initial provider configuration including the API key.
+ ///
+ /// Provider configuration details including provider type and API token
+ /// Provider configured successfully
+ /// Invalid request - missing required fields
+ /// Provider already configured
[AllowAnonymous]
[Route("SetupProvider")]
[HttpPost]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task SetupProvider([FromBody] AuthControllerSetupProviderRequest? request)
{
if (request == null)
@@ -95,10 +137,24 @@ public class AuthController(Authentication authentication, Settings settings) :
return Ok();
}
+ ///
+ /// Authenticates a user and creates a new session
+ ///
+ ///
+ /// Validates the provided credentials and creates an authenticated session if valid.
+ ///
+ /// Login credentials
+ /// Authentication successful
+ /// Invalid credentials or missing required fields
+ /// System requires initial setup - no users exist
[AllowAnonymous]
[Route("Login")]
[HttpPost]
- public async Task Login([FromBody] AuthControllerLoginRequest? request)
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
+ [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
+ [ProducesResponseType(StatusCodes.Status402PaymentRequired, Type = typeof(ProblemDetails))]
+ public async Task> Login([FromBody] AuthControllerLoginRequest? request)
{
if (request == null)
{
@@ -109,36 +165,55 @@ public class AuthController(Authentication authentication, Settings settings) :
if (user == null)
{
- return StatusCode(402);
+ return Problem(detail: "Setup required", statusCode: StatusCodes.Status402PaymentRequired);
}
if (String.IsNullOrEmpty(request.UserName) || String.IsNullOrEmpty(request.Password))
{
- return BadRequest("Invalid credentials");
+ return Problem(detail: "Invalid credentials", statusCode: StatusCodes.Status400BadRequest);
}
var result = await authentication.Login(request.UserName, request.Password);
if (!result.Succeeded)
{
- return BadRequest("Invalid credentials");
+ return Problem(detail: "Invalid credentials", statusCode: StatusCodes.Status400BadRequest);
}
return Ok();
}
-
+
+ ///
+ /// Ends the current authenticated session
+ ///
+ /// Session terminated successfully
[Route("Logout")]
[HttpPost]
+ [ProducesResponseType(StatusCodes.Status200OK)]
public async Task Logout()
{
await authentication.Logout();
+
return Ok();
}
-
+
+ ///
+ /// Updates the authenticated user's password
+ ///
+ ///
+ /// Requires authentication. Updates the password for the currently logged in user.
+ ///
+ /// Password update request containing the new password
+ /// Password updated successfully
+ /// Invalid request or password validation failed
+ /// Unauthorized - user must be authenticated
[Route("Update")]
[HttpPost]
[Authorize(Policy = "AuthSetting")]
- public async Task Update([FromBody] AuthControllerUpdateRequest? request)
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ProblemDetails))]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ public async Task> Update([FromBody] AuthControllerUpdateRequest? request)
{
if (request == null)
{
@@ -147,34 +222,76 @@ public class AuthController(Authentication authentication, Settings settings) :
if (String.IsNullOrEmpty(request.UserName) || String.IsNullOrEmpty(request.Password))
{
- return BadRequest("Invalid UserName or Password");
+ return Problem(detail: "Invalid UserName or Password", statusCode: StatusCodes.Status400BadRequest);
}
var updateResult = await authentication.Update(request.UserName, request.Password);
if (!updateResult.Succeeded)
{
- return BadRequest(updateResult.Errors.First().Description);
+ return Problem(detail: updateResult.Errors.First().Description, statusCode: StatusCodes.Status400BadRequest);
}
return Ok();
}
}
+///
+/// Request model for login and user creation operations
+///
public class AuthControllerLoginRequest
{
+ ///
+ /// Username for authentication
+ ///
+ /// admin
+ [Required]
public String? UserName { get; set; }
+
+ ///
+ /// Password for authentication
+ ///
+ /// MySecurePassword123!
+ [Required]
public String? Password { get; set; }
}
+///
+/// Request model for configuring the provider settings
+///
public class AuthControllerSetupProviderRequest
{
+ ///
+ /// Provider type identifier
+ ///
+ /// 1
+ [Required]
public Int32 Provider { get; set; }
+
+ ///
+ /// API token or key for the provider
+ ///
+ /// sk-1234567890abcdef
+ [Required]
public String? Token { get; set; }
}
+///
+/// Request model for updating user password
+///
public class AuthControllerUpdateRequest
{
+ ///
+ /// Username for the account
+ ///
+ /// myusername
+ [Required]
public String? UserName { get; set; }
+
+ ///
+ /// New password for the user account
+ ///
+ /// NewSecurePassword123!
+ [Required]
public String? Password { get; set; }
}
\ No newline at end of file