Replace custom socket implementation with SignalR.
Replace MSAL and custom cookie auth with Microsoft.Identity.EntityFramework Also some UI redesign to accommodate different login experience.
This commit is contained in:
3
Shogi.Database/AspNetUsersId.sql
Normal file
3
Shogi.Database/AspNetUsersId.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
-- This is so I don't have to remember the type used in the dbo.AspNetUsers table for the Id column.
|
||||
CREATE TYPE [dbo].[AspNetUsersId]
|
||||
FROM NVARCHAR(450) NOT NULL;
|
||||
@@ -4,4 +4,11 @@
|
||||
--CREATE ROLE db_executor
|
||||
--GRANT EXECUTE To db_executor
|
||||
|
||||
-- Give Shogi.Api user permission to db_executor, db_datareader, db_datawriter
|
||||
-- Give Shogi.Api user permission to db_executor, db_datareader, db_datawriter
|
||||
|
||||
|
||||
/**
|
||||
* Local setup instructions, in order:
|
||||
* 1. To setup the Shogi database, use the dacpac process in visual studio with the Shogi.Database project.
|
||||
* 2. To setup the Entity Framework users database, run this powershell command using Shogi.Api as the target project: dotnet ef database update
|
||||
*/
|
||||
@@ -10,6 +10,5 @@ Post-Deployment Script Template
|
||||
--------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
:r .\Scripts\PopulateLoginPlatforms.sql
|
||||
:r .\Scripts\PopulatePieces.sql
|
||||
:r .\Scripts\EnableSnapshotIsolationLevel.sql
|
||||
@@ -1,16 +0,0 @@
|
||||
|
||||
DECLARE @LoginPlatforms TABLE (
|
||||
[Platform] NVARCHAR(20)
|
||||
)
|
||||
|
||||
INSERT INTO @LoginPlatforms ([Platform])
|
||||
VALUES
|
||||
('Guest'),
|
||||
('Microsoft');
|
||||
|
||||
MERGE [user].[LoginPlatform] as t
|
||||
USING @LoginPlatforms as s
|
||||
ON t.[Platform] = s.[Platform]
|
||||
WHEN NOT MATCHED THEN
|
||||
INSERT ([Platform])
|
||||
VALUES (s.[Platform]);
|
||||
18
Shogi.Database/Session/Functions/MaxNewSessionsPerUser.sql
Normal file
18
Shogi.Database/Session/Functions/MaxNewSessionsPerUser.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
CREATE FUNCTION [session].[MaxNewSessionsPerUser]() RETURNS INT
|
||||
AS
|
||||
BEGIN
|
||||
|
||||
DECLARE @MaxNewSessionsCreatedByAnyOneUser INT;
|
||||
|
||||
WITH CountOfNewSessionsPerPlayer AS
|
||||
(
|
||||
SELECT COUNT(*) as TotalNewSessions
|
||||
FROM [session].[Session]
|
||||
WHERE Player2Id IS NULL
|
||||
GROUP BY Player1Id
|
||||
)
|
||||
SELECT @MaxNewSessionsCreatedByAnyOneUser = MAX(CountOfNewSessionsPerPlayer.TotalNewSessions)
|
||||
FROM CountOfNewSessionsPerPlayer
|
||||
|
||||
RETURN @MaxNewSessionsCreatedByAnyOneUser
|
||||
END
|
||||
@@ -1,9 +1,9 @@
|
||||
CREATE PROCEDURE [session].[CreateMove]
|
||||
@To VARCHAR(2),
|
||||
@From VARCHAR(2) = NULL,
|
||||
@To VARCHAR(2),
|
||||
@From VARCHAR(2) = NULL,
|
||||
@IsPromotion BIT = 0,
|
||||
@PieceFromHand NVARCHAR(13) = NULL,
|
||||
@SessionName [session].[SessionName]
|
||||
@PieceFromHand NVARCHAR(13) = NULL,
|
||||
@SessionId [session].[SessionSurrogateKey]
|
||||
AS
|
||||
|
||||
BEGIN
|
||||
@@ -13,11 +13,6 @@ BEGIN
|
||||
|
||||
BEGIN TRANSACTION
|
||||
|
||||
DECLARE @SessionId BIGINT = 0;
|
||||
SELECT @SessionId = Id
|
||||
FROM [session].[Session]
|
||||
WHERE [Name] = @SessionName;
|
||||
|
||||
DECLARE @PieceIdFromhand INT = NULL;
|
||||
SELECT @PieceIdFromhand = Id
|
||||
FROM [session].[Piece]
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
CREATE PROCEDURE [session].[CreateSession]
|
||||
@Name [session].[SessionName],
|
||||
@Player1Name [user].[UserName]
|
||||
@Id [session].[SessionSurrogateKey],
|
||||
@Player1Id [dbo].[AspNetUsersId]
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON
|
||||
|
||||
INSERT INTO [session].[Session] ([Name], Player1Id)
|
||||
SELECT @Name, Id
|
||||
FROM [user].[User]
|
||||
WHERE [Name] = @Player1Name
|
||||
INSERT INTO [session].[Session]
|
||||
([Id], Player1Id)
|
||||
VALUES
|
||||
(@Id, @Player1Id)
|
||||
|
||||
END
|
||||
@@ -1,5 +1,5 @@
|
||||
CREATE PROCEDURE [session].[DeleteSession]
|
||||
@Name [session].[SessionName]
|
||||
@Id [session].[SessionSurrogateKey]
|
||||
AS
|
||||
|
||||
DELETE FROM [session].[Session] WHERE [Name] = @Name;
|
||||
DELETE FROM [session].[Session] WHERE [Id] = @Id;
|
||||
@@ -1,5 +1,5 @@
|
||||
CREATE PROCEDURE [session].[ReadSession]
|
||||
@Name [session].[SessionName]
|
||||
@Id [session].[SessionSurrogateKey]
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON -- Performance boost
|
||||
@@ -10,13 +10,12 @@ BEGIN
|
||||
|
||||
-- Session
|
||||
SELECT
|
||||
sess.[Name],
|
||||
p1.[Name] as Player1,
|
||||
p2.[Name] as Player2
|
||||
FROM [session].[Session] sess
|
||||
INNER JOIN [user].[User] p1 on sess.Player1Id = p1.Id
|
||||
LEFT JOIN [user].[User] p2 on sess.Player2Id = p2.Id
|
||||
WHERE sess.[Name] = @Name;
|
||||
Id,
|
||||
Player1Id,
|
||||
Player2Id,
|
||||
CreatedDate
|
||||
FROM [session].[Session]
|
||||
WHERE Id = @Id;
|
||||
|
||||
-- Player moves
|
||||
SELECT
|
||||
@@ -27,7 +26,7 @@ BEGIN
|
||||
FROM [session].[Move] mv
|
||||
INNER JOIN [session].[Session] sess ON sess.Id = mv.SessionId
|
||||
LEFT JOIN [session].Piece piece on piece.Id = mv.PieceIdFromHand
|
||||
WHERE sess.[Name] = @Name;
|
||||
WHERE sess.[Id] = @Id;
|
||||
|
||||
COMMIT
|
||||
END
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
CREATE PROCEDURE [session].[ReadSessionPlayerCount]
|
||||
@PlayerName [user].UserName
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DECLARE @PlayerId as BIGINT;
|
||||
SELECT @PlayerId = Id
|
||||
FROM [user].[User]
|
||||
WHERE [Name] = @PlayerName;
|
||||
|
||||
-- Result set of sessions which @PlayerName participates in.
|
||||
SELECT
|
||||
[Name],
|
||||
CASE
|
||||
WHEN Player2Id IS NULL THEN 1
|
||||
ELSE 2
|
||||
END AS PlayerCount
|
||||
FROM [session].[Session]
|
||||
WHERE Player1Id = @PlayerId OR Player2Id = @PlayerId;
|
||||
|
||||
-- Result set of sessions which @PlayerName does not participate in.
|
||||
SELECT
|
||||
[Name],
|
||||
CASE
|
||||
WHEN Player2Id IS NULL THEN 1
|
||||
ELSE 2
|
||||
END AS PlayerCount
|
||||
FROM [session].[Session]
|
||||
WHERE Player1Id <> @PlayerId AND ISNULL(Player2Id, 0) <> @PlayerId;
|
||||
END
|
||||
@@ -0,0 +1,21 @@
|
||||
CREATE PROCEDURE [session].[ReadSessionsMetadata]
|
||||
@PlayerId [dbo].[AspNetUsersId]
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
-- Read all sessions, in this order:
|
||||
-- 1. sessions created by the logged-in user
|
||||
-- 2. any other sessions the logged-in user participates in
|
||||
-- 3. all other sessions
|
||||
SELECT
|
||||
Id, Player1Id, Player2Id, [Session].CreatedDate,
|
||||
case
|
||||
when Player1Id = @PlayerId then 0
|
||||
when Player2Id = @PlayerId then 1
|
||||
else 2
|
||||
end as OrderBy
|
||||
FROM [session].[Session]
|
||||
Order By OrderBy ASC, CreatedDate DESC
|
||||
|
||||
END
|
||||
@@ -1,13 +0,0 @@
|
||||
CREATE PROCEDURE [session].[ReadUsersBySession]
|
||||
@SessionName [session].[SessionName]
|
||||
AS
|
||||
|
||||
SELECT
|
||||
p1.[Name] as Player1Name,
|
||||
p1.DisplayName as Player1DisplayName,
|
||||
p2.[Name] as Player2Name,
|
||||
p2.DisplayName as Player2Displayname
|
||||
FROM [session].[Session] sess
|
||||
INNER JOIN [user].[User] p1 ON sess.Player1Id = p1.Id
|
||||
LEFT JOIN [user].[User] p2 on sess.Player2Id = p2.Id
|
||||
WHERE sess.[Name] = @SessionName;
|
||||
@@ -1,16 +1,13 @@
|
||||
CREATE PROCEDURE [session].[SetPlayer2]
|
||||
@SessionName [session].[SessionName],
|
||||
@Player2Name [user].[UserName] NULL
|
||||
@SessionId [session].[SessionSurrogateKey],
|
||||
@PlayerId [dbo].[AspNetUsersId]
|
||||
AS
|
||||
BEGIN
|
||||
SET NOCOUNT ON;
|
||||
|
||||
DECLARE @player2Id BIGINT;
|
||||
SELECT @player2Id = Id FROM [user].[User] WHERE [Name] = @Player2Name;
|
||||
|
||||
UPDATE sess
|
||||
SET Player2Id = @player2Id
|
||||
FROM [session].[Session] sess
|
||||
WHERE sess.[Name] = @SessionName;
|
||||
|
||||
UPDATE [session].[Session]
|
||||
SET Player2Id = @PlayerId
|
||||
FROM [session].[Session]
|
||||
WHERE Id = @SessionId;
|
||||
|
||||
END
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
CREATE TABLE [session].[Move]
|
||||
(
|
||||
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
|
||||
[SessionId] BIGINT NOT NULL,
|
||||
[To] VARCHAR(2) NOT NULL,
|
||||
[From] VARCHAR(2) NULL,
|
||||
[Id] INT NOT NULL PRIMARY KEY IDENTITY,
|
||||
[SessionId] [session].[SessionSurrogateKey] NOT NULL,
|
||||
[To] VARCHAR(2) NOT NULL,
|
||||
[From] VARCHAR(2) NULL,
|
||||
[PieceIdFromHand] INT NULL,
|
||||
[IsPromotion] BIT DEFAULT 0
|
||||
[IsPromotion] BIT DEFAULT 0
|
||||
|
||||
CONSTRAINT [Cannot end where you start]
|
||||
CHECK ([From] <> [To]),
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
CREATE TABLE [session].[Session]
|
||||
(
|
||||
Id BIGINT NOT NULL PRIMARY KEY IDENTITY,
|
||||
[Name] [session].[SessionName] UNIQUE,
|
||||
Player1Id BIGINT NOT NULL,
|
||||
Player2Id BIGINT NULL,
|
||||
Created DATETIMEOFFSET NOT NULL DEFAULT SYSDATETIMEOFFSET(),
|
||||
|
||||
CONSTRAINT FK_Player1_User FOREIGN KEY (Player1Id) REFERENCES [user].[User] (Id)
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE,
|
||||
|
||||
CONSTRAINT FK_Player2_User FOREIGN KEY (Player2Id) REFERENCES [user].[User] (Id)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION
|
||||
Id [session].[SessionSurrogateKey] PRIMARY KEY,
|
||||
Player1Id [dbo].[AspNetUsersId] NOT NULL,
|
||||
Player2Id [dbo].[AspNetUsersId] NULL,
|
||||
[CreatedDate] DATETIMEOFFSET NOT NULL DEFAULT SYSDATETIMEOFFSET(),
|
||||
CONSTRAINT [CK_Session_LimitedNewSessions] CHECK ([session].MaxNewSessionsPerUser() < 4),
|
||||
)
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
CREATE TYPE [session].[SessionName]
|
||||
FROM nvarchar(50) NOT NULL
|
||||
2
Shogi.Database/Session/Types/SessionSurrogateKey.sql
Normal file
2
Shogi.Database/Session/Types/SessionSurrogateKey.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
CREATE TYPE [session].[SessionSurrogateKey]
|
||||
FROM CHAR(36) NOT NULL
|
||||
17
Shogi.Database/Shogi.Database.refactorlog
Normal file
17
Shogi.Database/Shogi.Database.refactorlog
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Operations Version="1.0" xmlns="http://schemas.microsoft.com/sqlserver/dac/Serialization/2012/02">
|
||||
<Operation Name="Rename Refactor" Key="3cbf39d6-79cd-48fe-b8e3-dab0060d1092" ChangeDateTime="08/17/2024 03:58:12">
|
||||
<Property Name="ElementName" Value="[session].[Session].[Name]" />
|
||||
<Property Name="ElementType" Value="SqlSimpleColumn" />
|
||||
<Property Name="ParentElementName" Value="[session].[Session]" />
|
||||
<Property Name="ParentElementType" Value="SqlTable" />
|
||||
<Property Name="NewName" Value="SessionId" />
|
||||
</Operation>
|
||||
<Operation Name="Rename Refactor" Key="6ec1662d-c600-4558-af11-95a94acd23d9" ChangeDateTime="08/17/2024 15:59:09">
|
||||
<Property Name="ElementName" Value="[session].[Session].[Created]" />
|
||||
<Property Name="ElementType" Value="SqlSimpleColumn" />
|
||||
<Property Name="ParentElementName" Value="[session].[Session]" />
|
||||
<Property Name="ParentElementType" Value="SqlTable" />
|
||||
<Property Name="NewName" Value="CreatedDate" />
|
||||
</Operation>
|
||||
</Operations>
|
||||
@@ -58,36 +58,27 @@
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties" />
|
||||
<Folder Include="Session" />
|
||||
<Folder Include="User" />
|
||||
<Folder Include="Session\Tables" />
|
||||
<Folder Include="Session\Stored Procedures" />
|
||||
<Folder Include="User\Tables" />
|
||||
<Folder Include="Session\Types" />
|
||||
<Folder Include="User\Types" />
|
||||
<Folder Include="User\StoredProcedures" />
|
||||
<Folder Include="Post Deployment" />
|
||||
<Folder Include="Post Deployment\Scripts" />
|
||||
<Folder Include="Session\Functions" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Build Include="Session\session.sql" />
|
||||
<Build Include="User\user.sql" />
|
||||
<Build Include="Session\Tables\Session.sql" />
|
||||
<Build Include="Session\Stored Procedures\CreateSession.sql" />
|
||||
<Build Include="User\Tables\User.sql" />
|
||||
<Build Include="Session\Types\SessionName.sql" />
|
||||
<Build Include="User\Types\UserName.sql" />
|
||||
<Build Include="User\StoredProcedures\CreateUser.sql" />
|
||||
<Build Include="Session\Stored Procedures\ReadSessionPlayerCount.sql" />
|
||||
<Build Include="User\StoredProcedures\ReadUser.sql" />
|
||||
<Build Include="User\Tables\LoginPlatform.sql" />
|
||||
<None Include="Post Deployment\Scripts\PopulateLoginPlatforms.sql" />
|
||||
<Build Include="Session\Types\SessionSurrogateKey.sql" />
|
||||
<Build Include="Session\Stored Procedures\SetPlayer2.sql" />
|
||||
<Build Include="Session\Stored Procedures\ReadSession.sql" />
|
||||
<Build Include="Session\Tables\Move.sql" />
|
||||
<Build Include="Session\Tables\Piece.sql" />
|
||||
<Build Include="Session\Stored Procedures\DeleteSession.sql" />
|
||||
<Build Include="Session\Stored Procedures\CreateMove.sql" />
|
||||
<Build Include="Session\Stored Procedures\ReadUsersBySession.sql" />
|
||||
<Build Include="Session\Stored Procedures\ReadSessionsMetadata.sql" />
|
||||
<Build Include="AspNetUsersId.sql" />
|
||||
<Build Include="Session\Functions\MaxNewSessionsPerUser.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PostDeploy Include="Post Deployment\Script.PostDeployment.sql" />
|
||||
@@ -97,4 +88,7 @@
|
||||
<None Include="Post Deployment\Scripts\EnableSnapshotIsolationLevel.sql" />
|
||||
<None Include="FirstTimeSetup.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<RefactorLog Include="Shogi.Database.refactorlog" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,14 +0,0 @@
|
||||
CREATE PROCEDURE [user].[CreateUser]
|
||||
@Name [user].[UserName],
|
||||
@DisplayName NVARCHAR(100),
|
||||
@Platform NVARCHAR(20)
|
||||
AS
|
||||
BEGIN
|
||||
|
||||
SET NOCOUNT ON
|
||||
|
||||
INSERT INTO [user].[User] ([Name], DisplayName, [Platform])
|
||||
VALUES
|
||||
(@Name, @DisplayName, @Platform);
|
||||
|
||||
END
|
||||
@@ -1,11 +0,0 @@
|
||||
CREATE PROCEDURE [user].[ReadUser]
|
||||
@Name [user].[UserName]
|
||||
AS
|
||||
BEGIN
|
||||
SELECT
|
||||
[Name] as Id,
|
||||
DisplayName,
|
||||
[Platform]
|
||||
FROM [user].[User]
|
||||
WHERE [Name] = @Name;
|
||||
END
|
||||
@@ -1,4 +0,0 @@
|
||||
CREATE TABLE [user].[LoginPlatform]
|
||||
(
|
||||
[Platform] NVARCHAR(20) NOT NULL PRIMARY KEY
|
||||
)
|
||||
@@ -1,12 +0,0 @@
|
||||
CREATE TABLE [user].[User]
|
||||
(
|
||||
[Id] BIGINT NOT NULL PRIMARY KEY IDENTITY, -- TODO: Consider using user.UserName as the PK to avoid confusing "Id" in the database vs "Id" in the domain model.
|
||||
[Name] [user].[UserName] NOT NULL UNIQUE,
|
||||
[DisplayName] NVARCHAR(100) NOT NULL,
|
||||
[Platform] NVARCHAR(20) NOT NULL,
|
||||
[CreatedDate] DATETIMEOFFSET DEFAULT SYSDATETIMEOFFSET()
|
||||
|
||||
CONSTRAINT User_Platform FOREIGN KEY ([Platform]) References [user].[LoginPlatform] ([Platform])
|
||||
ON DELETE CASCADE
|
||||
ON UPDATE CASCADE
|
||||
)
|
||||
@@ -1,2 +0,0 @@
|
||||
CREATE TYPE [user].[UserName]
|
||||
FROM nvarchar(100) NOT NULL
|
||||
@@ -1 +0,0 @@
|
||||
CREATE SCHEMA [user]
|
||||
Reference in New Issue
Block a user