using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Shogi.Api.Extensions; using Shogi.Api.Managers; using Shogi.Api.Repositories; using Shogi.Contracts.Api; namespace Shogi.Api.Controllers; [ApiController] [Route("[controller]")] [Authorize] public class UserController : ControllerBase { private readonly ISocketTokenCache tokenCache; private readonly ISocketConnectionManager connectionManager; private readonly IUserRepository userRepository; private readonly IShogiUserClaimsTransformer claimsTransformation; private readonly AuthenticationProperties authenticationProps; public UserController( ILogger logger, ISocketTokenCache tokenCache, ISocketConnectionManager connectionManager, IUserRepository userRepository, IShogiUserClaimsTransformer claimsTransformation) { this.tokenCache = tokenCache; this.connectionManager = connectionManager; this.userRepository = userRepository; this.claimsTransformation = claimsTransformation; authenticationProps = new AuthenticationProperties { AllowRefresh = true, IsPersistent = true }; } [HttpGet("Token")] public ActionResult GetWebSocketToken() { var userId = User.GetShogiUserId(); var displayName = User.GetShogiUserDisplayname(); var token = tokenCache.GenerateToken(userId); return new CreateTokenResponse { DisplayName = displayName, OneTimeToken = token, UserId = userId }; } /// /// /// Used by cookie authentication. /// [AllowAnonymous] [HttpGet("LoginAsGuest")] public async Task GuestLogin([FromQuery] string? returnUrl) { var principal = await this.claimsTransformation.CreateClaimsFromGuestPrincipal(User); if (principal != null) { await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, principal, authenticationProps ); } if (!string.IsNullOrWhiteSpace(returnUrl)) { return Redirect(returnUrl); } return Ok(); } [HttpPut("GuestLogout")] public async Task GuestLogout() { var signOutTask = HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); var userId = User?.GetShogiUserId(); if (!string.IsNullOrEmpty(userId)) { connectionManager.Unsubscribe(userId); } await signOutTask; return Ok(); } }