using Gameboard.ShogiUI.Sockets.Extensions; using Gameboard.ShogiUI.Sockets.Managers; 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 ISocketConnectionManager connectionManager; private readonly AuthenticationProperties authenticationProps; public SocketController( ILogger logger, ISocketTokenCache tokenCache, IGameboardManager gameboardManager, IGameboardRepository gameboardRepository, ISocketConnectionManager connectionManager) { this.logger = logger; this.tokenCache = tokenCache; this.gameboardManager = gameboardManager; this.gameboardRepository = gameboardRepository; this.connectionManager = connectionManager; authenticationProps = new AuthenticationProperties { AllowRefresh = true, IsPersistent = true }; } [HttpGet("GuestLogout")] [AllowAnonymous] public async Task GuestLogout() { var signoutTask = HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); var userId = User?.UserId(); if (!string.IsNullOrEmpty(userId)) { connectionManager.Unsubscribe(userId); } await signoutTask; return Ok(); } [HttpGet("Token")] public async Task GetToken() { var user = await gameboardManager.ReadUser(User); if (user == null) { if (await gameboardManager.CreateUser(User)) { user = await gameboardManager.ReadUser(User); } } if (user == null) { return Unauthorized(); } var token = tokenCache.GenerateToken(user.Id); return new JsonResult(new GetTokenResponse(token)); } [HttpGet("GuestToken")] [AllowAnonymous] public async Task GetGuestToken() { var user = await gameboardManager.ReadUser(User); if (user == null) { // Create a guest user. var newUser = Models.User.CreateGuestUser(Guid.NewGuid().ToString()); var success = await gameboardRepository.CreateUser(newUser); if (!success) { return Conflict(); } var identity = newUser.CreateClaimsIdentity(); await HttpContext.SignInAsync( CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity), authenticationProps ); user = newUser; } var token = tokenCache.GenerateToken(user.Id.ToString()); return this.Ok(new GetGuestTokenResponse(user.Id, user.DisplayName, token)); } } }