refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)
Solution + 23 src projects + 26 test projects renamed; folders, csproj, namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated. ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated. SQL roles/logins, LDAP domains, CLI command name, and CLI config dir (~/.scadalink → ~/.scadabridge) also renamed. Build green; 5 Host.Tests fail awaiting SQL login rename in next commit. Pre-existing StaleTagMonitor timing flakes unchanged. Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
using Microsoft.AspNetCore.Antiforgery;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using ZB.MOM.WW.ScadaBridge.CentralUI.Auth;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Auth;
|
||||
|
||||
/// <summary>
|
||||
/// Regression tests for CentralUI-017. <c>POST /auth/logout</c> called
|
||||
/// <c>.DisableAntiforgery()</c> and a plain <c>GET /logout</c> route also
|
||||
/// signed the user out — either could be triggered cross-site to forcibly log
|
||||
/// a user out. Logout is a state-changing authenticated action and must be
|
||||
/// CSRF-protected: the POST keeps antiforgery enabled and the state-changing
|
||||
/// GET route is removed.
|
||||
/// </summary>
|
||||
public class AuthEndpointsCsrfTests
|
||||
{
|
||||
private static IReadOnlyList<RouteEndpoint> BuildEndpoints()
|
||||
{
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
builder.Services.AddRouting();
|
||||
builder.Services.AddAntiforgery();
|
||||
// Dispose the host: an undisposed WebApplication leaks its config
|
||||
// PhysicalFileProvider (appsettings reload-watch FileSystemWatcher — a
|
||||
// process-wide macOS run-loop thread) and a ConsoleLoggerProcessor
|
||||
// thread, which keep the test host process alive after the run.
|
||||
using var app = builder.Build();
|
||||
app.MapAuthEndpoints();
|
||||
|
||||
return ((IEndpointRouteBuilder)app).DataSources
|
||||
.SelectMany(ds => ds.Endpoints)
|
||||
.OfType<RouteEndpoint>()
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static RouteEndpoint? Find(IReadOnlyList<RouteEndpoint> endpoints, string pattern, string method)
|
||||
=> endpoints.FirstOrDefault(e =>
|
||||
e.RoutePattern.RawText == pattern &&
|
||||
(e.Metadata.GetMetadata<HttpMethodMetadata>()?.HttpMethods.Contains(method) ?? false));
|
||||
|
||||
[Fact]
|
||||
public void PostAuthLogout_DoesNotDisableAntiforgery()
|
||||
{
|
||||
var endpoints = BuildEndpoints();
|
||||
var logout = Find(endpoints, "/auth/logout", "POST");
|
||||
|
||||
Assert.NotNull(logout);
|
||||
// DisableAntiforgery() leaves an IAntiforgeryMetadata with
|
||||
// RequiresValidation == false. A CSRF-protected POST has either no such
|
||||
// metadata, or metadata that still requires validation.
|
||||
var antiforgery = logout!.Metadata.GetMetadata<IAntiforgeryMetadata>();
|
||||
Assert.True(antiforgery is null || antiforgery.RequiresValidation,
|
||||
"POST /auth/logout must keep antiforgery validation enabled.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetLogout_StateChangingRoute_IsRemoved()
|
||||
{
|
||||
var endpoints = BuildEndpoints();
|
||||
var getLogout = Find(endpoints, "/logout", "GET");
|
||||
|
||||
Assert.Null(getLogout);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PostAuthLogin_StillDisablesAntiforgery_PreAuthIsAcceptable()
|
||||
{
|
||||
// Login is a pre-auth endpoint; disabling antiforgery there is acceptable
|
||||
// and intentional. This pins that the fix did not over-correct.
|
||||
var endpoints = BuildEndpoints();
|
||||
var login = Find(endpoints, "/auth/login", "POST");
|
||||
|
||||
Assert.NotNull(login);
|
||||
var antiforgery = login!.Metadata.GetMetadata<IAntiforgeryMetadata>();
|
||||
Assert.NotNull(antiforgery);
|
||||
Assert.False(antiforgery!.RequiresValidation);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user