Add alpha session gate with cookie auth and login UI.
This commit is contained in:
@@ -3,6 +3,7 @@ using HSchool.Server;
|
||||
using HSchool.Server.Api;
|
||||
using HSchool.Server.Game;
|
||||
using HSchool.Server.Net;
|
||||
using HSchool.Server.Session;
|
||||
using HSchool.Simulation;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Options;
|
||||
@@ -12,6 +13,14 @@ var builder = WebApplication.CreateBuilder(args);
|
||||
builder.AddServiceDefaults();
|
||||
builder.Services.AddProblemDetails();
|
||||
builder.Services.AddOpenApi();
|
||||
builder.Services.AddDataProtection();
|
||||
|
||||
builder.Services
|
||||
.AddOptions<HSchoolOptions>()
|
||||
.Bind(builder.Configuration.GetSection(HSchoolOptions.SectionName))
|
||||
.Validate(options => !string.IsNullOrWhiteSpace(options.AlphaPassword), "HSchool:AlphaPassword must be set.")
|
||||
.Validate(options => options.SessionCookieDays is > 0 and <= 365, "HSchool:SessionCookieDays must be between 1 and 365.")
|
||||
.ValidateOnStart();
|
||||
|
||||
builder.Services
|
||||
.AddOptions<SimulationOptions>()
|
||||
@@ -30,6 +39,8 @@ builder.Services
|
||||
|
||||
builder.Services.AddSingleton<GameCommandQueue>();
|
||||
builder.Services.AddSingleton<ClientRegistry>();
|
||||
builder.Services.AddSingleton<UserStore>();
|
||||
builder.Services.AddSingleton<SessionService>();
|
||||
builder.Services.AddSingleton<GameMetrics>();
|
||||
builder.Services.AddSingleton<SchoolStore>();
|
||||
builder.Services.AddSingleton<ModContent>();
|
||||
@@ -64,6 +75,9 @@ app.UseWebSockets(new WebSocketOptions
|
||||
KeepAliveInterval = TimeSpan.FromSeconds(30),
|
||||
});
|
||||
|
||||
app.UseMiddleware<SessionAuthMiddleware>();
|
||||
|
||||
app.MapSessionEndpoints();
|
||||
app.MapSchoolEndpoints();
|
||||
app.MapSettingsEndpoints();
|
||||
app.MapTimetableEndpoints();
|
||||
@@ -104,7 +118,7 @@ if (app.Configuration.GetValue("HSchool:AllowSaveReload", false))
|
||||
}
|
||||
|
||||
// The realtime channel: one binary frame per protocol message, see docs/protocol.md.
|
||||
app.Map("/ws/game", async (HttpContext context, GameSocketHandler handler) =>
|
||||
app.Map("/ws/game", async (HttpContext context, GameSocketHandler handler, SessionService sessions) =>
|
||||
{
|
||||
if (!context.WebSockets.IsWebSocketRequest)
|
||||
{
|
||||
@@ -113,8 +127,29 @@ app.Map("/ws/game", async (HttpContext context, GameSocketHandler handler) =>
|
||||
return;
|
||||
}
|
||||
|
||||
using WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();
|
||||
await handler.HandleAsync(socket, context.RequestAborted);
|
||||
if (!sessions.TryGetUserName(context, out var userName))
|
||||
{
|
||||
using WebSocket socket = await context.WebSockets.AcceptWebSocketAsync();
|
||||
if (socket.State is WebSocketState.Open or WebSocketState.CloseReceived)
|
||||
{
|
||||
try
|
||||
{
|
||||
await socket.CloseAsync(
|
||||
WebSocketCloseStatus.PolicyViolation,
|
||||
"Session required.",
|
||||
context.RequestAborted);
|
||||
}
|
||||
catch (WebSocketException)
|
||||
{
|
||||
// The peer may already be gone.
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
using WebSocket connected = await context.WebSockets.AcceptWebSocketAsync();
|
||||
await handler.HandleAsync(connected, userName, context.RequestAborted);
|
||||
});
|
||||
|
||||
app.MapDefaultEndpoints();
|
||||
|
||||
Reference in New Issue
Block a user