yep
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
using Gameboard.ShogiUI.Sockets.Managers;
|
||||
using Gameboard.ShogiUI.Sockets.Repositories;
|
||||
using Gameboard.ShogiUI.Sockets.ServiceModels.Api.Messages;
|
||||
using Gameboard.ShogiUI.Sockets.ServiceModels.Api;
|
||||
using Gameboard.ShogiUI.Sockets.ServiceModels.Socket;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -13,34 +15,36 @@ namespace Gameboard.ShogiUI.Sockets.Controllers
|
||||
[Route("[controller]")]
|
||||
public class GameController : ControllerBase
|
||||
{
|
||||
private readonly IGameboardManager manager;
|
||||
private static readonly string UsernameClaim = "preferred_username";
|
||||
private readonly IGameboardManager gameboardManager;
|
||||
private readonly IGameboardRepository gameboardRepository;
|
||||
private readonly ISocketConnectionManager communicationManager;
|
||||
private readonly IGameboardRepository repository;
|
||||
private string? JwtUserName => HttpContext.User.Claims.FirstOrDefault(c => c.Type == UsernameClaim)?.Value;
|
||||
|
||||
public GameController(
|
||||
IGameboardRepository repository,
|
||||
IGameboardManager manager,
|
||||
ISocketConnectionManager communicationManager)
|
||||
{
|
||||
this.manager = manager;
|
||||
gameboardManager = manager;
|
||||
gameboardRepository = repository;
|
||||
this.communicationManager = communicationManager;
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
[HttpPost("JoinCode")]
|
||||
public async Task<IActionResult> PostGameInvitation([FromBody] PostGameInvitation request)
|
||||
{
|
||||
var userName = HttpContext.User.Claims.First(c => c.Type == "preferred_username").Value;
|
||||
var isPlayer1 = await manager.IsPlayer1(request.SessionName, userName);
|
||||
if (isPlayer1)
|
||||
{
|
||||
var code = await repository.PostJoinCode(request.SessionName, userName);
|
||||
return new CreatedResult("", new PostGameInvitationResponse(code));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new UnauthorizedResult();
|
||||
}
|
||||
|
||||
//var isPlayer1 = await gameboardManager.IsPlayer1(request.SessionName, userName);
|
||||
//if (isPlayer1)
|
||||
//{
|
||||
// var code = await gameboardRepository.PostJoinCode(request.SessionName, userName);
|
||||
// return new CreatedResult("", new PostGameInvitationResponse(code));
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
return new UnauthorizedResult();
|
||||
//}
|
||||
}
|
||||
|
||||
[AllowAnonymous]
|
||||
@@ -48,19 +52,58 @@ namespace Gameboard.ShogiUI.Sockets.Controllers
|
||||
public async Task<IActionResult> PostGuestGameInvitation([FromBody] PostGuestGameInvitation request)
|
||||
{
|
||||
|
||||
var isGuest = manager.IsGuest(request.GuestId);
|
||||
var isPlayer1 = manager.IsPlayer1(request.SessionName, request.GuestId);
|
||||
if (isGuest && await isPlayer1)
|
||||
{
|
||||
var code = await repository.PostJoinCode(request.SessionName, request.GuestId);
|
||||
return new CreatedResult("", new PostGameInvitationResponse(code));
|
||||
}
|
||||
else
|
||||
{
|
||||
return new UnauthorizedResult();
|
||||
}
|
||||
//var isGuest = gameboardManager.IsGuest(request.GuestId);
|
||||
//var isPlayer1 = gameboardManager.IsPlayer1(request.SessionName, request.GuestId);
|
||||
//if (isGuest && await isPlayer1)
|
||||
//{
|
||||
// var code = await gameboardRepository.PostJoinCode(request.SessionName, request.GuestId);
|
||||
// return new CreatedResult("", new PostGameInvitationResponse(code));
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
return new UnauthorizedResult();
|
||||
//}
|
||||
}
|
||||
|
||||
[HttpPost("{gameName}/Move")]
|
||||
public async Task<IActionResult> PostMove([FromRoute] string gameName, [FromBody] PostMove request)
|
||||
{
|
||||
Models.User? user = null;
|
||||
if (Request.Cookies.ContainsKey(SocketController.WebSessionKey))
|
||||
{
|
||||
var webSessionId = Guid.Parse(Request.Cookies[SocketController.WebSessionKey]!);
|
||||
user = await gameboardManager.ReadUser(webSessionId);
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(JwtUserName))
|
||||
{
|
||||
user = await gameboardManager.ReadUser(JwtUserName);
|
||||
}
|
||||
|
||||
var session = await gameboardManager.ReadSession(gameName);
|
||||
|
||||
if (session == null || user == null || (session.Player1 != user.Name && session.Player2 != user.Name))
|
||||
{
|
||||
throw new UnauthorizedAccessException("You are not seated at this game.");
|
||||
}
|
||||
|
||||
var move = request.Move;
|
||||
var moveModel = move.PieceFromCaptured.HasValue
|
||||
? new Models.Move(move.PieceFromCaptured.Value, move.To, move.IsPromotion)
|
||||
: new Models.Move(move.From!, move.To, move.IsPromotion);
|
||||
var moveSuccess = session.Shogi.Move(moveModel);
|
||||
|
||||
if (moveSuccess)
|
||||
{
|
||||
await communicationManager.BroadcastToPlayers(new MoveResponse
|
||||
{
|
||||
GameName = session.Name,
|
||||
PlayerName = user.Name,
|
||||
Move = moveModel.ToServiceModel()
|
||||
}, session.Player1, session.Player2);
|
||||
return Ok();
|
||||
}
|
||||
throw new InvalidOperationException("Illegal move.");
|
||||
}
|
||||
// TODO: Use JWT tokens for guests so they can authenticate and use API routes, too.
|
||||
//[Route("")]
|
||||
//public async Task<IActionResult> PostSession([FromBody] PostSession request)
|
||||
@@ -69,7 +112,7 @@ namespace Gameboard.ShogiUI.Sockets.Controllers
|
||||
// var success = await repository.CreateSession(model);
|
||||
// if (success)
|
||||
// {
|
||||
// var message = new ServiceModels.Socket.Messages.CreateGameResponse(ServiceModels.Socket.Types.ClientAction.CreateGame)
|
||||
// var message = new ServiceModels.Socket.Messages.CreateGameResponse(ServiceModels.Types.ClientAction.CreateGame)
|
||||
// {
|
||||
// Game = model.ToServiceModel(),
|
||||
// PlayerName =
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using Gameboard.ShogiUI.Sockets.Managers;
|
||||
using Gameboard.ShogiUI.Sockets.Repositories;
|
||||
using Gameboard.ShogiUI.Sockets.ServiceModels.Api.Messages;
|
||||
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;
|
||||
|
||||
@@ -14,10 +16,13 @@ namespace Gameboard.ShogiUI.Sockets.Controllers
|
||||
[ApiController]
|
||||
public class SocketController : ControllerBase
|
||||
{
|
||||
public static readonly string WebSessionKey = "session-id";
|
||||
private readonly ILogger<SocketController> logger;
|
||||
private readonly ISocketTokenManager tokenManager;
|
||||
private readonly IGameboardManager gameboardManager;
|
||||
private readonly IGameboardRepository gameboardRepository;
|
||||
private readonly CookieOptions createSessionOptions;
|
||||
private readonly CookieOptions deleteSessionOptions;
|
||||
|
||||
public SocketController(
|
||||
ILogger<SocketController> logger,
|
||||
@@ -29,6 +34,23 @@ namespace Gameboard.ShogiUI.Sockets.Controllers
|
||||
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")]
|
||||
@@ -39,25 +61,36 @@ namespace Gameboard.ShogiUI.Sockets.Controllers
|
||||
return new JsonResult(new GetTokenResponse(token));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpGet("GuestToken")]
|
||||
public async Task<IActionResult> GetGuestToken([FromQuery] GetGuestToken request)
|
||||
public async Task<IActionResult> GetGuestToken()
|
||||
{
|
||||
if (request.ClientId == null)
|
||||
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 clientId = await gameboardManager.CreateGuestUser();
|
||||
var token = tokenManager.GenerateToken(clientId);
|
||||
return new JsonResult(new GetGuestTokenResponse(clientId, token));
|
||||
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
|
||||
{
|
||||
if (await gameboardRepository.IsGuestUser(request.ClientId))
|
||||
{
|
||||
var token = tokenManager.GenerateToken(request.ClientId);
|
||||
return new JsonResult(new GetGuestTokenResponse(request.ClientId, token));
|
||||
}
|
||||
var token = tokenManager.GenerateToken(webSessionIdAsString);
|
||||
Response.Cookies.Append(WebSessionKey, webSessionIdAsString, createSessionOptions);
|
||||
return new JsonResult(new GetGuestTokenResponse(user.Name, token));
|
||||
}
|
||||
return new UnauthorizedResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user