From 1de344ac25b73176d3ecf55bed7a01e4cda60690 Mon Sep 17 00:00:00 2001 From: Polianin Nikita Date: Sat, 28 Dec 2024 07:46:06 +0300 Subject: [PATCH] refactor: to enable oauth during registration, use the appropriate controller. --- .../Configuration/SetupController.cs | 57 ++++++++++++++----- Endpoint/Controllers/V1/AuthController.cs | 1 - Security/Services/OAuthService.cs | 2 +- 3 files changed, 44 insertions(+), 16 deletions(-) diff --git a/Endpoint/Controllers/Configuration/SetupController.cs b/Endpoint/Controllers/Configuration/SetupController.cs index 7c3441e..cf974a7 100644 --- a/Endpoint/Controllers/Configuration/SetupController.cs +++ b/Endpoint/Controllers/Configuration/SetupController.cs @@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Data.Sqlite; using Microsoft.Extensions.Caching.Memory; -using Microsoft.Extensions.Options; using Mirea.Api.Dto.Common; using Mirea.Api.Dto.Requests; using Mirea.Api.Dto.Requests.Configuration; @@ -18,6 +17,7 @@ using Mirea.Api.Endpoint.Common.Services; using Mirea.Api.Endpoint.Configuration.Model; using Mirea.Api.Endpoint.Configuration.Model.GeneralSettings; using Mirea.Api.Endpoint.Configuration.Validation.Validators; +using Mirea.Api.Security.Common.Domain; using Mirea.Api.Security.Common.Model; using Mirea.Api.Security.Services; using MySqlConnector; @@ -26,13 +26,17 @@ using Serilog; using StackExchange.Redis; using System; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Data; +using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Security; using System.Security.Cryptography; +using System.Threading.Tasks; using CookieOptions = Microsoft.AspNetCore.Http.CookieOptions; +using OAuthProvider = Mirea.Api.Security.Common.Domain.OAuthProvider; using PasswordPolicy = Mirea.Api.Dto.Common.PasswordPolicy; namespace Mirea.Api.Endpoint.Controllers.Configuration; @@ -45,7 +49,7 @@ public class SetupController( IMaintenanceModeNotConfigureService notConfigureService, IMemoryCache cache, PasswordHashService passwordHashService, - IOptionsSnapshot user) : BaseController + OAuthService oAuthService) : BaseController { private const string CacheGeneralKey = "config_general"; private const string CacheAdminKey = "config_admin"; @@ -319,29 +323,54 @@ public class SetupController( return Ok(true); } - [HttpGet("UpdateAdminConfiguration")] + [HttpGet("HandleToken")] [TokenAuthentication] - public ActionResult UpdateAdminConfiguration() + public async Task HandleToken([FromQuery][MinLength(2)] string token) { - if (string.IsNullOrEmpty(user.Value.Email)) - return Ok(); + var (user, error, isSuccess, provider) = await oAuthService.GetOAuthUser(new Security.Common.Model.CookieOptions + { + Domain = HttpContext.GetCurrentDomain(), + Path = UrlHelper.GetSubPathWithoutFirstApiName + "api" + }, HttpContext, token); + + if (!isSuccess || user == null || provider == null) + throw new ControllerArgumentException(error ?? "Token processing error."); if (!cache.TryGetValue(CacheAdminKey, out var admin)) { - admin = user.Value; + admin = new Admin() + { + Email = user.Email ?? string.Empty, + Username = user.Username ?? string.Empty, + PasswordHash = string.Empty, + Salt = string.Empty, + OAuthProviders = new Dictionary + { + {provider.Value, user} + } + }; + cache.Set(CacheAdminKey, admin); return Ok(); } - admin!.OAuthProviders = user.Value.OAuthProviders; - - if (string.IsNullOrEmpty(admin.Email)) - admin.Email = user.Value.Email; - - if (string.IsNullOrEmpty(admin.Username)) - admin.Username = user.Value.Username; + 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() + { + { "traceId", Activity.Current?.Id ?? HttpContext.TraceIdentifier } + } + }); + admin.OAuthProviders ??= []; + admin.OAuthProviders.Add(provider.Value, user); cache.Set(CacheAdminKey, admin); + return Ok(); } diff --git a/Endpoint/Controllers/V1/AuthController.cs b/Endpoint/Controllers/V1/AuthController.cs index b7c49f3..2588dd8 100644 --- a/Endpoint/Controllers/V1/AuthController.cs +++ b/Endpoint/Controllers/V1/AuthController.cs @@ -172,7 +172,6 @@ public class AuthController(IOptionsSnapshot user, IOptionsSnapshotThe action to be performed: Login or Bind. /// If return Ok. If return [HttpGet("HandleToken")] - [MaintenanceModeIgnore] [BadRequestResponse] public async Task HandleToken([FromQuery][MinLength(2)] string token, [FromQuery] OAuthAction action) { diff --git a/Security/Services/OAuthService.cs b/Security/Services/OAuthService.cs index 621a566..1145fe1 100644 --- a/Security/Services/OAuthService.cs +++ b/Security/Services/OAuthService.cs @@ -332,7 +332,7 @@ public class OAuthService(ILogger logger, Dictionary(token, cancellation); - string tokenFailedKey = $"{requestInfo.Fingerprint}_oauth_token_failed"; + var tokenFailedKey = $"{requestInfo.Fingerprint}_oauth_token_failed"; if (result == null) {