in the middle of relearning msal
This commit is contained in:
@@ -59,10 +59,14 @@ public class SessionRepository : ISessionRepository
|
|||||||
{
|
{
|
||||||
session.Board.Move(move.PieceFromHand.Value, move.To);
|
session.Board.Move(move.PieceFromHand.Value, move.To);
|
||||||
}
|
}
|
||||||
else
|
else if (move.From != null)
|
||||||
{
|
{
|
||||||
session.Board.Move(move.From, move.To, false);
|
session.Board.Move(move.From, move.To, false);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Corrupt data during {nameof(ReadSession)}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class ShogiUserClaimsTransformer : IShogiUserClaimsTransformer
|
|||||||
|
|
||||||
private async Task<ClaimsPrincipal> CreateClaimsFromMicrosoftPrincipal(ClaimsPrincipal principal)
|
private async Task<ClaimsPrincipal> CreateClaimsFromMicrosoftPrincipal(ClaimsPrincipal principal)
|
||||||
{
|
{
|
||||||
var id = principal.GetMsalAccountId();
|
var id = principal.GetMicrosoftUserId();
|
||||||
if (string.IsNullOrWhiteSpace(id))
|
if (string.IsNullOrWhiteSpace(id))
|
||||||
{
|
{
|
||||||
throw new UnauthorizedAccessException("Found MSAL claims but no preferred_username.");
|
throw new UnauthorizedAccessException("Found MSAL claims but no preferred_username.");
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ BEGIN
|
|||||||
piece.[Name] as PieceFromHand
|
piece.[Name] as PieceFromHand
|
||||||
FROM [session].[Move] mv
|
FROM [session].[Move] mv
|
||||||
INNER JOIN [session].[Session] sess ON sess.Id = mv.SessionId
|
INNER JOIN [session].[Session] sess ON sess.Id = mv.SessionId
|
||||||
RIGHT JOIN [session].Piece piece on piece.Id = mv.PieceIdFromHand
|
LEFT JOIN [session].Piece piece on piece.Id = mv.PieceIdFromHand
|
||||||
WHERE sess.[Name] = @Name;
|
WHERE sess.[Name] = @Name;
|
||||||
|
|
||||||
COMMIT
|
COMMIT
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
@*<CascadingAuthenticationState>*@
|
<CascadingAuthenticationState>
|
||||||
|
|
||||||
<Router AppAssembly="@typeof(App).Assembly">
|
<Router AppAssembly="@typeof(App).Assembly">
|
||||||
<Found Context="routeData">
|
<Found Context="routeData">
|
||||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||||
@*<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
|
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
|
||||||
<Authorizing>
|
<Authorizing>
|
||||||
Authorizing!!
|
Authorizing!!
|
||||||
</Authorizing>
|
</Authorizing>
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
<p role="alert">You are not authorized to access this resource.</p>
|
<p role="alert">You are not authorized to access this resource.</p>
|
||||||
}
|
}
|
||||||
</NotAuthorized>
|
</NotAuthorized>
|
||||||
</AuthorizeRouteView>*@
|
</AuthorizeRouteView>
|
||||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||||
</Found>
|
</Found>
|
||||||
<NotFound>
|
<NotFound>
|
||||||
@@ -28,4 +28,4 @@
|
|||||||
</NotFound>
|
</NotFound>
|
||||||
</Router>
|
</Router>
|
||||||
|
|
||||||
@*</CascadingAuthenticationState>*@
|
</CascadingAuthenticationState>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using Shogi.UI.Pages.Home.Api;
|
using Shogi.UI.Pages.Home.Api;
|
||||||
using Shogi.UI.Shared;
|
using Shogi.UI.Shared;
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@ public class AccountManager
|
|||||||
private readonly IShogiApi shogiApi;
|
private readonly IShogiApi shogiApi;
|
||||||
private readonly IConfiguration configuration;
|
private readonly IConfiguration configuration;
|
||||||
private readonly ILocalStorage localStorage;
|
private readonly ILocalStorage localStorage;
|
||||||
//private readonly AuthenticationStateProvider authState;
|
private readonly AuthenticationStateProvider authState;
|
||||||
private readonly NavigationManager navigation;
|
private readonly NavigationManager navigation;
|
||||||
private readonly ShogiSocket shogiSocket;
|
private readonly ShogiSocket shogiSocket;
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ public class AccountManager
|
|||||||
AccountState accountState,
|
AccountState accountState,
|
||||||
IShogiApi unauthenticatedClient,
|
IShogiApi unauthenticatedClient,
|
||||||
IConfiguration configuration,
|
IConfiguration configuration,
|
||||||
//AuthenticationStateProvider authState,
|
AuthenticationStateProvider authState,
|
||||||
ILocalStorage localStorage,
|
ILocalStorage localStorage,
|
||||||
NavigationManager navigation,
|
NavigationManager navigation,
|
||||||
ShogiSocket shogiSocket)
|
ShogiSocket shogiSocket)
|
||||||
@@ -26,7 +27,7 @@ public class AccountManager
|
|||||||
this.accountState = accountState;
|
this.accountState = accountState;
|
||||||
this.shogiApi = unauthenticatedClient;
|
this.shogiApi = unauthenticatedClient;
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
//this.authState = authState;
|
this.authState = authState;
|
||||||
this.localStorage = localStorage;
|
this.localStorage = localStorage;
|
||||||
this.navigation = navigation;
|
this.navigation = navigation;
|
||||||
this.shogiSocket = shogiSocket;
|
this.shogiSocket = shogiSocket;
|
||||||
@@ -53,29 +54,28 @@ public class AccountManager
|
|||||||
|
|
||||||
public async Task LoginWithMicrosoftAccount()
|
public async Task LoginWithMicrosoftAccount()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
var state = await authState.GetAuthenticationStateAsync();
|
||||||
//var state = await authState.GetAuthenticationStateAsync();
|
|
||||||
|
|
||||||
//if (state.User?.Identity?.Name == null || state.User?.Identity?.IsAuthenticated != true)
|
if (state.User?.Identity?.Name == null || state.User?.Identity?.IsAuthenticated != true)
|
||||||
//{
|
{
|
||||||
// navigation.NavigateTo("authentication/login");
|
navigation.NavigateTo("authentication/login");
|
||||||
// return;
|
return;
|
||||||
//}
|
}
|
||||||
|
|
||||||
//var id = state.User.Identity.Name;
|
var response = await shogiApi.GetToken();
|
||||||
//var socketToken = await shogiApi.GetToken();
|
if (response != null)
|
||||||
//if (socketToken.HasValue)
|
{
|
||||||
//{
|
User = new User
|
||||||
// User = new User
|
{
|
||||||
// {
|
DisplayName = response.DisplayName,
|
||||||
// DisplayName = id,
|
Id = response.UserId,
|
||||||
// Id = id,
|
OneTimeSocketToken = response.OneTimeToken,
|
||||||
// OneTimeSocketToken = socketToken.Value
|
WhichAccountPlatform = WhichAccountPlatform.Microsoft,
|
||||||
// };
|
};
|
||||||
|
|
||||||
// await ConnectToSocketAsync();
|
await shogiSocket.OpenAsync(User.OneTimeSocketToken.ToString());
|
||||||
// await localStorage.SetAccountPlatform(WhichAccountPlatform.Microsoft);
|
await localStorage.SetAccountPlatform(WhichAccountPlatform.Microsoft);
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using Shogi.UI.Shared;
|
using Shogi.UI.Shared;
|
||||||
|
|
||||||
namespace Shogi.UI.Pages.Home.Account
|
namespace Shogi.UI.Pages.Home.Account;
|
||||||
|
|
||||||
|
public static class LocalStorageExtensions
|
||||||
{
|
{
|
||||||
public static class LocalStorageExtensions
|
|
||||||
{
|
|
||||||
private const string AccountPlatform = "AccountPlatform";
|
private const string AccountPlatform = "AccountPlatform";
|
||||||
|
|
||||||
public static Task<WhichAccountPlatform?> GetAccountPlatform(this ILocalStorage self)
|
public static Task<WhichAccountPlatform?> GetAccountPlatform(this ILocalStorage self)
|
||||||
@@ -20,5 +20,4 @@ namespace Shogi.UI.Pages.Home.Account
|
|||||||
{
|
{
|
||||||
return self.Delete(AccountPlatform).AsTask();
|
return self.Delete(AccountPlatform).AsTask();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
namespace Shogi.UI.Pages.Home.Account
|
namespace Shogi.UI.Pages.Home.Account;
|
||||||
|
|
||||||
|
public class LoginEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public class LoginEventArgs : EventArgs
|
|
||||||
{
|
|
||||||
public User? User { get; set; }
|
public User? User { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ public interface IShogiApi
|
|||||||
Task<ReadSessionsPlayerCountResponse?> GetSessionsPlayerCount();
|
Task<ReadSessionsPlayerCountResponse?> GetSessionsPlayerCount();
|
||||||
Task<CreateTokenResponse?> GetToken();
|
Task<CreateTokenResponse?> GetToken();
|
||||||
Task GuestLogout();
|
Task GuestLogout();
|
||||||
Task PostMove(string sessionName, MovePieceCommand move);
|
Task Move(string sessionName, MovePieceCommand move);
|
||||||
Task<HttpStatusCode> PostSession(string name, bool isPrivate);
|
Task<HttpStatusCode> PostSession(string name, bool isPrivate);
|
||||||
}
|
}
|
||||||
@@ -63,9 +63,9 @@ namespace Shogi.UI.Pages.Home.Api
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task PostMove(string sessionName, MovePieceCommand command)
|
public async Task Move(string sessionName, MovePieceCommand command)
|
||||||
{
|
{
|
||||||
await this.HttpClient.PostAsJsonAsync($"Sessions{sessionName}/Move", command);
|
await this.HttpClient.PatchAsync($"Sessions/{sessionName}/Move", JsonContent.Create(command));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<HttpStatusCode> PostSession(string name, bool isPrivate)
|
public async Task<HttpStatusCode> PostSession(string name, bool isPrivate)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@
|
|||||||
<span>I</span>
|
<span>I</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- Promote prompt -->
|
<!-- Promote prompt -->
|
||||||
<div class="promote-prompt">
|
<div class="promote-prompt" data-visible="@PromotePrompt.IsVisible">
|
||||||
<p>Do you wish to promote?</p>
|
<p>Do you wish to promote?</p>
|
||||||
<div>
|
<div>
|
||||||
<button type="button">Yes</button>
|
<button type="button">Yes</button>
|
||||||
@@ -114,6 +114,7 @@
|
|||||||
: this.session.BoardState.Player2Hand;
|
: this.session.BoardState.Player2Hand;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool IsMyTurn => session?.BoardState.WhoseTurn == Perspective;
|
||||||
|
|
||||||
string? selectedPosition;
|
string? selectedPosition;
|
||||||
WhichPiece? selectedPiece;
|
WhichPiece? selectedPiece;
|
||||||
@@ -138,21 +139,24 @@
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async void OnClickTile(Piece? piece, string position)
|
async void OnClickTile(Piece? piece, string position)
|
||||||
{
|
{
|
||||||
if (SessionName == null) return;
|
if (SessionName == null || !IsMyTurn) return;
|
||||||
|
|
||||||
if (selectedPosition == null)
|
if (selectedPosition == null || piece?.Owner == Perspective)
|
||||||
{
|
{
|
||||||
|
// Select a position.
|
||||||
selectedPosition = position;
|
selectedPosition = position;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (selectedPosition == position)
|
if (selectedPosition == position)
|
||||||
{
|
{
|
||||||
|
// Deselect the selected position.
|
||||||
selectedPosition = null;
|
selectedPosition = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (piece != null)
|
if (piece == null)
|
||||||
{
|
{
|
||||||
if (ShouldPromptForPromotion(position) || ShouldPromptForPromotion(selectedPosition))
|
if (ShouldPromptForPromotion(position) || ShouldPromptForPromotion(selectedPosition))
|
||||||
{
|
{
|
||||||
@@ -164,7 +168,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await ShogiApi.PostMove(SessionName, new MovePieceCommand
|
await ShogiApi.Move(SessionName, new MovePieceCommand
|
||||||
{
|
{
|
||||||
From = selectedPosition,
|
From = selectedPosition,
|
||||||
IsPromotion = false,
|
IsPromotion = false,
|
||||||
@@ -173,6 +177,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnClickHand(Piece piece)
|
void OnClickHand(Piece piece)
|
||||||
{
|
{
|
||||||
selectedPiece = piece.WhichPiece;
|
selectedPiece = piece.WhichPiece;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.board {
|
.board {
|
||||||
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"rank A9 B9 C9 D9 E9 F9 G9 H9 I9"
|
"rank A9 B9 C9 D9 E9 F9 G9 H9 I9"
|
||||||
@@ -59,9 +60,10 @@
|
|||||||
overflow: hidden; /* Because SVGs are shaped weird */
|
overflow: hidden; /* Because SVGs are shaped weird */
|
||||||
transition: filter linear 0.25s;
|
transition: filter linear 0.25s;
|
||||||
}
|
}
|
||||||
.tile[data-selected] {
|
|
||||||
|
.tile[data-selected] {
|
||||||
filter: invert(0.8);
|
filter: invert(0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.ruler {
|
.ruler {
|
||||||
color: beige;
|
color: beige;
|
||||||
@@ -91,3 +93,20 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.promote-prompt {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
border: 2px solid #444;
|
||||||
|
background-color: #eaeaea;
|
||||||
|
padding: 1rem;
|
||||||
|
box-shadow: 1px 1px 1px #444;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.promote-prompt[data-visible="true"] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class PromotePrompt
|
|||||||
if (command != null && sessionName != null)
|
if (command != null && sessionName != null)
|
||||||
{
|
{
|
||||||
command.IsPromotion = false;
|
command.IsPromotion = false;
|
||||||
return shogiApi.PostMove(sessionName, command);
|
return shogiApi.Move(sessionName, command);
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ public class PromotePrompt
|
|||||||
if (command != null && sessionName != null)
|
if (command != null && sessionName != null)
|
||||||
{
|
{
|
||||||
command.IsPromotion = true;
|
command.IsPromotion = true;
|
||||||
return shogiApi.PostMove(sessionName, command);
|
return shogiApi.Move(sessionName, command);
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
//ModalService.ShowLoginModal();
|
//ModalService.ShowLoginModal();
|
||||||
//Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}");
|
Navigation.NavigateTo($"authentication/login?returnUrl={Uri.EscapeDataString(Navigation.Uri)}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -277,11 +277,11 @@ public class AcceptanceTests : IClassFixture<GuestTestFixture>
|
|||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
var session = (await ReadTestSession()).Session;
|
var session = (await ReadTestSession()).Session;
|
||||||
session.BoardState.Board["A2"].Should().BeNull();
|
session.BoardState.Board["A3"].Should().BeNull();
|
||||||
session.BoardState.Board["A3"].Should().NotBeNull();
|
session.BoardState.Board["A4"].Should().NotBeNull();
|
||||||
session.BoardState.Board["A3"]!.IsPromoted.Should().BeFalse();
|
session.BoardState.Board["A4"]!.IsPromoted.Should().BeFalse();
|
||||||
session.BoardState.Board["A3"]!.Owner.Should().Be(WhichPlayer.Player1);
|
session.BoardState.Board["A4"]!.Owner.Should().Be(WhichPlayer.Player1);
|
||||||
session.BoardState.Board["A3"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
session.BoardState.Board["A4"]!.WhichPiece.Should().Be(WhichPiece.Pawn);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user