feat: add a token handler
This commit is contained in:
parent
9d5007ef3a
commit
516ba5bb8e
17
ApiDto/Common/OAuthAction.cs
Normal file
17
ApiDto/Common/OAuthAction.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
namespace Mirea.Api.Dto.Common;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the actions that can be performed with an OAuth token.
|
||||||
|
/// </summary>
|
||||||
|
public enum OAuthAction
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The action to log in the user using the provided OAuth token.
|
||||||
|
/// </summary>
|
||||||
|
Login,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The action to bind an OAuth provider to the user's account.
|
||||||
|
/// </summary>
|
||||||
|
Bind
|
||||||
|
}
|
@ -11,12 +11,13 @@ using Mirea.Api.Endpoint.Common.Exceptions;
|
|||||||
using Mirea.Api.Endpoint.Common.MapperDto;
|
using Mirea.Api.Endpoint.Common.MapperDto;
|
||||||
using Mirea.Api.Endpoint.Common.Services;
|
using Mirea.Api.Endpoint.Common.Services;
|
||||||
using Mirea.Api.Endpoint.Configuration.Model;
|
using Mirea.Api.Endpoint.Configuration.Model;
|
||||||
using Mirea.Api.Security.Common.Model;
|
|
||||||
using Mirea.Api.Security.Services;
|
using Mirea.Api.Security.Services;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CookieOptions = Mirea.Api.Security.Common.Model.CookieOptions;
|
using CookieOptions = Mirea.Api.Security.Common.Model.CookieOptions;
|
||||||
using OAuthProvider = Mirea.Api.Security.Common.Domain.OAuthProvider;
|
using OAuthProvider = Mirea.Api.Security.Common.Domain.OAuthProvider;
|
||||||
@ -164,6 +165,67 @@ public class AuthController(IOptionsSnapshot<Admin> user, IOptionsSnapshot<Gener
|
|||||||
})
|
})
|
||||||
.ConvertToDto());
|
.ConvertToDto());
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Processes the OAuth token
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="token">The OAuth token used for authentication or binding.</param>
|
||||||
|
/// <param name="action">The action to be performed: Login or Bind.</param>
|
||||||
|
/// <returns>If <see cref="OAuthAction.Bind"/> return Ok. If <see cref="OAuthAction.Login"/> return <see cref="TwoFactorAuthentication"/></returns>
|
||||||
|
[HttpGet("HandleToken")]
|
||||||
|
[MaintenanceModeIgnore]
|
||||||
|
[BadRequestResponse]
|
||||||
|
public async Task<ActionResult> HandleToken([FromQuery][MinLength(2)] string token, [FromQuery] OAuthAction action)
|
||||||
|
{
|
||||||
|
var (oAuthUser, error, isSuccess, provider) = await oAuthService.GetOAuthUser(GetCookieParams(), HttpContext, token);
|
||||||
|
|
||||||
|
if (!isSuccess || oAuthUser == null || provider == null)
|
||||||
|
throw new ControllerArgumentException(error ?? "Token processing error.");
|
||||||
|
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case OAuthAction.Login:
|
||||||
|
return Ok(await auth.LoginOAuthAsync(GetCookieParams(), HttpContext, user.Value.ConvertToSecurity(), oAuthUser, provider.Value));
|
||||||
|
|
||||||
|
case OAuthAction.Bind:
|
||||||
|
var userId = HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||||
|
var admin = user.Value;
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(userId) || !int.TryParse(userId, out var result) || result != 1)
|
||||||
|
return Unauthorized(new ProblemDetails
|
||||||
|
{
|
||||||
|
Type = "https://tools.ietf.org/html/rfc9110#section-15.5.2",
|
||||||
|
Title = "Unauthorized",
|
||||||
|
Status = StatusCodes.Status401Unauthorized,
|
||||||
|
Detail = "The user is not logged in to link accounts.",
|
||||||
|
Extensions = new Dictionary<string, object?>()
|
||||||
|
{
|
||||||
|
{ "traceId", HttpContext.TraceIdentifier }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (admin.OAuthProviders != null && admin.OAuthProviders.ContainsKey(provider.Value))
|
||||||
|
return Conflict(new ProblemDetails
|
||||||
|
{
|
||||||
|
Type = "https://tools.ietf.org/html/rfc9110#section-15.5.10",
|
||||||
|
Title = "Conflict",
|
||||||
|
Status = StatusCodes.Status409Conflict,
|
||||||
|
Detail = "This OAuth provider is already associated with the account.",
|
||||||
|
Extensions = new Dictionary<string, object?>()
|
||||||
|
{
|
||||||
|
{ "traceId", HttpContext.TraceIdentifier }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
admin.OAuthProviders ??= [];
|
||||||
|
admin.OAuthProviders.Add(provider.Value, oAuthUser);
|
||||||
|
admin.SaveSetting();
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
default:
|
||||||
|
throw new ControllerArgumentException("The action cannot be processed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Logs in a user using their username or email and password.
|
/// Logs in a user using their username or email and password.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user