Scaffold some AAT stuff

This commit is contained in:
2022-06-19 17:35:33 -05:00
parent 3e938a8576
commit 770344422d
16 changed files with 275 additions and 47 deletions

View File

@@ -5,12 +5,8 @@ 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
{
@@ -19,7 +15,6 @@ namespace Gameboard.ShogiUI.Sockets.Controllers
[Authorize]
public class SocketController : ControllerBase
{
private readonly ILogger<SocketController> logger;
private readonly ISocketTokenCache tokenCache;
private readonly IGameboardManager gameboardManager;
private readonly IGameboardRepository gameboardRepository;
@@ -33,7 +28,6 @@ namespace Gameboard.ShogiUI.Sockets.Controllers
IGameboardRepository gameboardRepository,
ISocketConnectionManager connectionManager)
{
this.logger = logger;
this.tokenCache = tokenCache;
this.gameboardManager = gameboardManager;
this.gameboardRepository = gameboardRepository;

View File

@@ -8,9 +8,12 @@
<GenerateDocumentationFile>False</GenerateDocumentationFile>
<SignAssembly>False</SignAssembly>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>973a1f5f-ef25-4f1c-a24d-b0fc7d016ab8</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Extensions.AspNetCore.Configuration.Secrets" Version="1.0.0" />
<PackageReference Include="Azure.Identity" Version="1.6.0" />
<PackageReference Include="FluentValidation" Version="10.3.6" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="6.0.5" />

View File

@@ -35,7 +35,7 @@ namespace Gameboard.ShogiUI.Sockets.Managers
{
await Task.Delay(TimeSpan.FromMinutes(1));
Tokens.Remove(userName, out _);
});
}).ConfigureAwait(false);
return guid;
}

View File

@@ -60,16 +60,22 @@ namespace Gameboard.ShogiUI.Sockets
{
// TODO: Figure out how to make a middleware for sockets?
var socketService = app.Services.GetRequiredService<ISocketService>();
var origins = new[] {
"http://localhost:3000", "https://localhost:3000",
"http://127.0.0.1:3000", "https://127.0.0.1:3000",
"https://api.lucaserver.space", "https://lucaserver.space"
};
var allowedOrigins = app.Configuration.GetSection("Cors:AllowedOrigins").Get<string[]>();
var socketOptions = new WebSocketOptions();
foreach (var o in origins)
socketOptions.AllowedOrigins.Add(o);
app.UseCors(opt => opt.WithOrigins(origins).AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("Set-Cookie").AllowCredentials());
foreach (var origin in allowedOrigins)
socketOptions.AllowedOrigins.Add(origin);
app.UseCors(options =>
{
options
.WithOrigins(allowedOrigins)
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowAnyMethod()
.AllowAnyHeader()
.WithExposedHeaders("Set-Cookie")
.AllowCredentials();
});
app.UseWebSockets(socketOptions);
app.Use(async (context, next) =>
{

View File

@@ -0,0 +1,76 @@
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"resourceGroupName": {
"type": "string",
"defaultValue": "DefaultResourceGroup-CUS",
"metadata": {
"_parameterType": "resourceGroup",
"description": "Name of the resource group for the resource. It is recommended to put resources under same resource group for better tracking."
}
},
"resourceGroupLocation": {
"type": "string",
"defaultValue": "centralus",
"metadata": {
"_parameterType": "location",
"description": "Location of the resource group. Resource groups could have different location than resources."
}
},
"resourceLocation": {
"type": "string",
"defaultValue": "[parameters('resourceGroupLocation')]",
"metadata": {
"_parameterType": "location",
"description": "Location of the resource. By default use resource group's location, unless the resource provider is not supported there."
}
}
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"name": "[parameters('resourceGroupName')]",
"location": "[parameters('resourceGroupLocation')]",
"apiVersion": "2019-10-01"
},
{
"type": "Microsoft.Resources/deployments",
"name": "[concat(parameters('resourceGroupName'), 'Deployment', uniqueString(concat('GameboardShogiUISocketsv', subscription().subscriptionId)))]",
"resourceGroup": "[parameters('resourceGroupName')]",
"apiVersion": "2019-10-01",
"dependsOn": [
"[parameters('resourceGroupName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "GameboardShogiUISocketsv",
"type": "Microsoft.KeyVault/vaults",
"location": "[parameters('resourceLocation')]",
"properties": {
"sku": {
"family": "A",
"name": "Standard"
},
"tenantId": "d6019544-c403-415c-8e96-50009635b6aa",
"accessPolicies": [],
"enabledForDeployment": true,
"enabledForDiskEncryption": true,
"enabledForTemplateDeployment": true
},
"apiVersion": "2016-10-01"
}
]
}
}
}
],
"metadata": {
"_dependencyType": "secrets.keyVault"
}
}

View File

@@ -5,7 +5,9 @@
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
"ASPNETCORE_ENVIRONMENT": "Development",
"VaultUri": "https://gameboardshogiuisocketsv.vault.azure.net/",
"AZURE_USERNAME": "Hauth@live.com"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}

View File

@@ -3,6 +3,11 @@
"identityapp1": {
"type": "identityapp",
"dynamicId": null
},
"secrets1": {
"type": "secrets",
"connectionId": "VaultUri",
"dynamicId": null
}
}
}

View File

@@ -3,6 +3,13 @@
"identityapp1": {
"type": "identityapp.default",
"dynamicId": null
},
"secrets1": {
"secretStore": null,
"resourceId": "/subscriptions/[parameters('subscriptionId')]/resourceGroups/[parameters('resourceGroupName')]/providers/Microsoft.KeyVault/vaults/GameboardShogiUISocketsv",
"type": "secrets.keyVault",
"connectionId": "VaultUri",
"dynamicId": null
}
}
}

View File

@@ -0,0 +1,4 @@
# Gameboard.ShogiUI.Sockets
# Forgetmenots
Don't forget to run `dotnet user-secrets init` within the AAT project.

View File

@@ -67,12 +67,14 @@ namespace Gameboard.ShogiUI.Sockets.Repositories
* 3) User document of Player2.
*/
var session = group.FirstOrDefault()?.doc.ToObject<SessionDocument>();
var player1Doc = group.Skip(1).FirstOrDefault()?.doc.ToObject<UserDocument>();
var player2Doc = group.Skip(2).FirstOrDefault()?.doc.ToObject<UserDocument>();
if (session != null && player1Doc != null)
var player1 = group.Skip(1).FirstOrDefault()?.doc.ToObject<UserDocument>();
var player2Doc = group.Skip(2).FirstOrDefault()?.doc;
if (session != null && player1 != null && player2Doc != null)
{
var player2 = player2Doc == null ? null : new Models.User(player2Doc);
sessions.Add(new SessionMetadata(session.Name, session.IsPrivate, player1Doc.Id, player2?.Id));
var player2 = IsUserDocument(player2Doc)
? new Models.User(player2Doc.ToObject<UserDocument>()!)
: null;
sessions.Add(new SessionMetadata(session.Name, session.IsPrivate, player1.Id, player2?.Id));
}
}
return new Collection<SessionMetadata>(sessions);
@@ -80,6 +82,11 @@ namespace Gameboard.ShogiUI.Sockets.Repositories
return new Collection<SessionMetadata>(Array.Empty<SessionMetadata>());
}
private static bool IsUserDocument(JObject player2Doc)
{
return player2Doc?.SelectToken(nameof(CouchDocument.DocumentType))?.Value<WhichDocumentType>() == WhichDocumentType.User;
}
public async Task<Session?> ReadSession(string name)
{
static Shogi.Domain.Pieces.Piece? MapPiece(Piece? piece)
@@ -112,17 +119,16 @@ namespace Gameboard.ShogiUI.Sockets.Repositories
* Everything Else) Snapshots of the boardstate after every player move.
*/
var session = group[0].doc.ToObject<SessionDocument>();
var player1Doc = group[1].doc.ToObject<UserDocument>();
var group2DocumentType = group[2].doc.Property(nameof(UserDocument.DocumentType).ToCamelCase())?.Value.Value<string>();
var player2Doc = group2DocumentType == WhichDocumentType.User.ToString()
? group[2].doc.ToObject<UserDocument>()
: null;
var player1 = group[1].doc.ToObject<UserDocument>();
var player2Doc = group[2].doc;
var boardState = group.Last().doc.ToObject<BoardStateDocument>();
if (session != null && player1Doc != null && boardState != null)
if (session != null && player1 != null && boardState != null)
{
var player2 = player2Doc == null ? null : new Models.User(player2Doc);
var metaData = new SessionMetadata(session.Name, session.IsPrivate, player1Doc.DisplayName, player2Doc?.DisplayName);
var player2 = IsUserDocument(player2Doc)
? new Models.User(player2Doc.ToObject<UserDocument>()!)
: null;
var metaData = new SessionMetadata(session.Name, session.IsPrivate, player1.Id, player2?.Id);
var shogiBoardState = new BoardState(boardState.Board.ToDictionary(kvp => kvp.Key, kvp => MapPiece(kvp.Value)));
return new Session(shogiBoardState, metaData);
}
@@ -151,15 +157,14 @@ namespace Gameboard.ShogiUI.Sockets.Repositories
* 3) User document of Player2.
*/
var session = group[0].doc.ToObject<SessionDocument>();
var player1Doc = group[1].doc.ToObject<UserDocument>();
var group2DocumentType = group[2].doc.Property(nameof(UserDocument.DocumentType).ToCamelCase())?.Value.Value<string>();
var player2Doc = group2DocumentType == WhichDocumentType.User.ToString()
? group[2].doc.ToObject<UserDocument>()
: null;
if (session != null && player1Doc != null)
var player1 = group[1].doc.ToObject<UserDocument>();
var player2Doc = group[2].doc;
if (session != null && player1 != null)
{
var player2 = player2Doc == null ? null : new Models.User(player2Doc);
return new SessionMetadata(session.Name, session.IsPrivate, player1Doc.Id, player2?.Id);
var player2 = IsUserDocument(player2Doc)
? new Models.User(player2Doc.ToObject<UserDocument>()!)
: null;
return new SessionMetadata(session.Name, session.IsPrivate, player1.Id, player2?.Id);
}
}
return null;

View File

@@ -18,5 +18,13 @@
"ClientId": "c1e94676-cab0-42ba-8b6c-9532b8486fff",
"SwaggerUIClientId": "26bf69a4-2af8-4711-bf5b-79f75e20b082"
},
"Cors": {
"AllowedOrigins": [
"http://localhost:3000",
"https://localhost:3000",
"https://api.lucaserver.space",
"https://lucaserver.space"
]
},
"AllowedHosts": "*"
}