using Gameboard.ShogiUI.Sockets.Extensions; using Gameboard.ShogiUI.Sockets.Managers; using Gameboard.ShogiUI.Sockets.Models; using Gameboard.ShogiUI.Sockets.Repositories; using Gameboard.ShogiUI.Sockets.ServiceModels.Api; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using System.Security.Claims; using System.Threading.Tasks; namespace Gameboard.ShogiUI.Sockets.Controllers { [ApiController] [Route("[controller]")] [Authorize(Roles = "Shogi")] public class SocketController : ControllerBase { private readonly ILogger logger; private readonly ISocketTokenCache tokenCache; private readonly IGameboardManager gameboardManager; private readonly IGameboardRepository gameboardRepository; private readonly AuthenticationProperties authenticationProps; public SocketController( ILogger logger, ISocketTokenCache tokenCache, IGameboardManager gameboardManager, IGameboardRepository gameboardRepository) { this.logger = logger; this.tokenCache = tokenCache; this.gameboardManager = gameboardManager; this.gameboardRepository = gameboardRepository; authenticationProps = new AuthenticationProperties { AllowRefresh = true, IsPersistent = true }; } [HttpGet("GuestLogout")] [AllowAnonymous] public async Task GuestLogout() { await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); return Ok(); } [HttpGet("Token")] public async Task GetToken() { var identityId = User.UserId(); if (string.IsNullOrWhiteSpace(identityId)) { return Unauthorized(); } var user = await gameboardManager.ReadUser(User); if (user == null) { user = new User(identityId); var success = await gameboardRepository.CreateUser(user); if (!success) { return Unauthorized(); } } var token = tokenCache.GenerateToken(user.Name); return new JsonResult(new GetTokenResponse(token)); } [HttpGet("GuestToken")] [AllowAnonymous] public async Task GetGuestToken() { if (Guid.TryParse(User.UserId(), out Guid webSessionId)) { var user = await gameboardRepository.ReadGuestUser(webSessionId); if (user != null) { var token = tokenCache.GenerateToken(webSessionId.ToString()); return new JsonResult(new GetGuestTokenResponse(user.Name, token)); } } else { // Setup a guest user. var newSessionId = Guid.NewGuid(); var user = new User(Guid.NewGuid().ToString(), newSessionId); if (await gameboardRepository.CreateUser(user)) { var identity = user.CreateGuestUserIdentity(); await this.HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), authenticationProps ); var token = tokenCache.GenerateToken(newSessionId.ToString()); return new JsonResult(new GetGuestTokenResponse(user.Name, token)); } } return Unauthorized(); } } }