using Gameboard.ShogiUI.Sockets.Managers; using Gameboard.ShogiUI.Sockets.Repositories; using Gameboard.ShogiUI.Sockets.ServiceModels.Api; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using System.Linq; using System.Threading.Tasks; namespace Gameboard.ShogiUI.Sockets.Controllers { [Authorize] [Route("[controller]")] [ApiController] public class SocketController : ControllerBase { public static readonly string WebSessionKey = "session-id"; private readonly ILogger logger; private readonly ISocketTokenManager tokenManager; private readonly IGameboardManager gameboardManager; private readonly IGameboardRepository gameboardRepository; private readonly CookieOptions createSessionOptions; private readonly CookieOptions deleteSessionOptions; public SocketController( ILogger logger, ISocketTokenManager tokenManager, IGameboardManager gameboardManager, IGameboardRepository gameboardRepository) { this.logger = logger; this.tokenManager = tokenManager; this.gameboardManager = gameboardManager; this.gameboardRepository = gameboardRepository; createSessionOptions = new CookieOptions { Secure = true, HttpOnly = true, SameSite = SameSiteMode.None, Expires = DateTimeOffset.Now.AddYears(5) }; deleteSessionOptions = new CookieOptions(); } [HttpGet("Yep")] [AllowAnonymous] public IActionResult Yep() { deleteSessionOptions.Expires = DateTimeOffset.Now.AddDays(-1); Response.Cookies.Append(WebSessionKey, "", deleteSessionOptions); return Ok(); } [HttpGet("Token")] public IActionResult GetToken() { var userName = HttpContext.User.Claims.First(c => c.Type == "preferred_username").Value; var token = tokenManager.GenerateToken(userName); return new JsonResult(new GetTokenResponse(token)); } /// /// Builds a token for guest users to send when requesting a socket connection. /// Sends a HttpOnly cookie to the client with which to identify guest users. /// /// /// [AllowAnonymous] [HttpGet("GuestToken")] public async Task GetGuestToken() { var cookies = Request.Cookies; var webSessionId = cookies.ContainsKey(WebSessionKey) ? Guid.Parse(cookies[WebSessionKey]!) : Guid.NewGuid(); var webSessionIdAsString = webSessionId.ToString(); var user = await gameboardRepository.ReadGuestUser(webSessionId); if (user == null) { var userName = await gameboardManager.CreateGuestUser(webSessionId); var token = tokenManager.GenerateToken(webSessionIdAsString); Response.Cookies.Append(WebSessionKey, webSessionIdAsString, createSessionOptions); return new JsonResult(new GetGuestTokenResponse(userName, token)); } else { var token = tokenManager.GenerateToken(webSessionIdAsString); Response.Cookies.Append(WebSessionKey, webSessionIdAsString, createSessionOptions); return new JsonResult(new GetGuestTokenResponse(user.Name, token)); } } } }