astral-api/Astral.ApiServer/Controllers/BaseApiController.cs
Mike 81aa0ec1c0
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
WIP heartbeat and user presence
2024-12-15 16:06:14 +00:00

114 lines
3.6 KiB
C#

// <copyright file="BaseApiController.cs" company="alveus.dev">
// Copyright (c) alveus.dev. All rights reserved. Licensed under the MIT License.
// </copyright>
using System.Net;
using System.Net.Sockets;
using Astral.ApiServer.Models.Common;
using Astral.Core.Constants;
using Microsoft.AspNetCore.Mvc;
namespace Astral.ApiServer.Controllers;
/// <summary>
/// Base API controller with common methods.
/// </summary>
[Produces("application/json")]
[Consumes("application/json")]
public class BaseApiController : ControllerBase
{
/// <summary>
/// Return a failure status with no data.
/// </summary>
/// <returns>Instance of <see cref="IActionResult"/>.</returns>
protected IActionResult FailureResult()
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return new JsonResult(new ResponseModel
{
Status = "failure",
Success = false,
});
}
/// <summary>
/// Return a failure result with additional information.
/// </summary>
/// <param name="errorCode">Api error code.</param>
/// <param name="message">Api error message.</param>
/// <returns>Instance of <see cref="IActionResult"/>.</returns>
protected IActionResult FailureResult(string errorCode, string message)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return new JsonResult(new ErrorResponseModel
{
Status = "failure",
Error = errorCode,
Message = message,
});
}
/// <summary>
/// Returns a failure result indicating the body is missing from the request.
/// </summary>
/// <returns>Instance of <see cref="IActionResult"/>.</returns>
protected IActionResult MissingBodyResult()
{
return FailureResult(CoreErrorCodes.NoDataProvided, "Missing request body");
}
/// <summary>
/// Return a successful result.
/// </summary>
/// <param name="response">Instance of the response model.</param>
/// <typeparam name="TResponseModel">The response model type.</typeparam>
/// <returns>Instance of <see cref="IActionResult"/>.</returns>
protected IActionResult SuccessResult<TResponseModel>(TResponseModel response)
where TResponseModel : class
{
Response.StatusCode = (int)HttpStatusCode.OK;
return new JsonResult(new DataResponseModel<TResponseModel>(response));
}
/// <summary>
/// Return a success status with no data.
/// </summary>
/// <returns>Instance of <see cref="IActionResult"/>.</returns>
protected IActionResult SuccessResult()
{
Response.StatusCode = (int)HttpStatusCode.OK;
return new JsonResult(new ResponseModel
{
Status = "success",
Success = true,
});
}
/// <summary>
/// Fetch IP address of requesting agent.
/// </summary>
/// <returns>Request origin's IP address.</returns>
protected IPAddress ClientIpAddress()
{
IPAddress remoteIpAddress = null;
if (Request.Headers.TryGetValue("X-Forwarded-For", out var value))
{
foreach (var ip in value)
{
if (IPAddress.TryParse(ip, out var address) &&
address.AddressFamily is AddressFamily.InterNetwork
or AddressFamily.InterNetworkV6)
{
remoteIpAddress = address;
break;
}
}
}
else
{
remoteIpAddress = HttpContext.Connection.RemoteIpAddress?.MapToIPv4();
}
return remoteIpAddress;
}
}