feat(auth)!: ScadaBridge canonical roles + SoD collapse (Audit→Administrator, AuditReadOnly→Viewer) + config-DB migration (Task 1.7)
Standardize role string VALUES on the canonical vocabulary
(Administrator/Designer/Deployer/Viewer; Operator/Engineer unused here):
Admin -> Administrator
Design -> Designer
Deployment -> Deployer
Audit -> Administrator (COLLAPSE; accepted privilege escalation)
AuditReadOnly-> Viewer (COLLAPSE; keeps audit-read, no export)
SoD: OperationalAuditRoles = { Administrator, Viewer },
AuditExportRoles = { Administrator }
so Viewer reads the audit log + nav but cannot bulk-export, while
Administrator does both + holds the full admin surface (the documented,
accepted auditor/admin SoD collapse).
Atomic move across every enforcement site:
- Roles constants; AuthorizationPolicies (RequireClaim values + SoD arrays +
honest XML-doc); RoleMapper Deployer check.
- ManagementActor.GetRequiredRole switch + the hard-coded site-scope
admin-bypass (now Roles.Administrator at all 6 sites). Site-scoping logic
is otherwise unchanged.
- DebugStreamHub Administrator/Deployer gates (Deployer kept case-sensitive).
- CentralUI BrowseService/BindingTester Designer guards; LdapMappingForm
dropdown now offers canonical values (incl. Viewer).
- Config-DB seed (LdapGroupMappings Id 1-4) + EF migration CanonicalizeRoles:
Id-keyed UpdateData for seed rows + idempotent raw catch-all UPDATEs for
operator-added rows. Down is lossy on the collapse (documented in-file).
No pending model changes.
Tests reworked to the collapsed model across Security/CentralUI/
ManagementService/ConfigurationDatabase/Integration suites, incl. explicit
Viewer-reads-not-exports and former-Audit-now-Administrator-escalation cases.
CHANGELOG: BREAKING security note documenting the canonicalization + SoD
collapse.
This commit is contained in:
@@ -18,7 +18,7 @@ namespace ZB.MOM.WW.ScadaBridge.ManagementService.Tests;
|
||||
/// the seam (the real <c>LibraryInboundApiKeyAdmin</c> + SQLite mapping is covered end-to-end
|
||||
/// by the Security project's <c>LibraryInboundApiKeyAdminTests</c>). They verify the actor's
|
||||
/// dispatch, response shapes (string keyId, one-time token, methods), the preserved ScadaBridge
|
||||
/// management-audit calls, and that the "Admin" role gate still applies to all five commands.
|
||||
/// management-audit calls, and that the "Administrator" role gate still applies to all five commands.
|
||||
/// </summary>
|
||||
public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
{
|
||||
@@ -48,7 +48,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
public void CreateApiKey_ReturnsKeyIdAndOneTimeToken()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new CreateApiKeyCommand("MES-Production", new[] { "MethodA", "MethodB" }), "Admin"));
|
||||
actor.Tell(Envelope(new CreateApiKeyCommand("MES-Production", new[] { "MethodA", "MethodB" }), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -73,7 +73,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
public void CreateApiKey_AuditsTheCreate()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new CreateApiKeyCommand("MES-Production", new[] { "MethodA" }), "Admin"));
|
||||
actor.Tell(Envelope(new CreateApiKeyCommand("MES-Production", new[] { "MethodA" }), "Administrator"));
|
||||
ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
|
||||
_auditService.Received(1).LogAsync(
|
||||
@@ -84,7 +84,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
public void CreateApiKey_ResponseDoesNotEchoAHash()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new CreateApiKeyCommand("MES-Production", new[] { "MethodA" }), "Admin"));
|
||||
actor.Tell(Envelope(new CreateApiKeyCommand("MES-Production", new[] { "MethodA" }), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -100,7 +100,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
_admin.Seed("key-2", "Service B", enabled: false, "M3");
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new ListApiKeysCommand(), "Admin"));
|
||||
actor.Tell(Envelope(new ListApiKeysCommand(), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -125,7 +125,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
_admin.Seed("key-1", "Service A", enabled: true, "M1");
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new UpdateApiKeyCommand("key-1", false), "Admin"));
|
||||
actor.Tell(Envelope(new UpdateApiKeyCommand("key-1", false), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -145,7 +145,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
_admin.Seed("key-1", "Service A", enabled: true, "M1");
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new DeleteApiKeyCommand("key-1"), "Admin"));
|
||||
actor.Tell(Envelope(new DeleteApiKeyCommand("key-1"), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -162,7 +162,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
_admin.Seed("key-1", "Service A", enabled: true, "Old1", "Old2");
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new SetApiKeyMethodsCommand("key-1", new[] { "New1", "New2", "New3" }), "Admin"));
|
||||
actor.Tell(Envelope(new SetApiKeyMethodsCommand("key-1", new[] { "New1", "New2", "New3" }), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -188,7 +188,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
{
|
||||
// No keys seeded — "key-unknown" does not exist.
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new UpdateApiKeyCommand("key-unknown", false), "Admin"));
|
||||
actor.Tell(Envelope(new UpdateApiKeyCommand("key-unknown", false), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -202,7 +202,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
public void SetApiKeyMethods_UnknownKey_ReturnsManagementError_AndDoesNotAudit()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new SetApiKeyMethodsCommand("key-unknown", new[] { "M1" }), "Admin"));
|
||||
actor.Tell(Envelope(new SetApiKeyMethodsCommand("key-unknown", new[] { "M1" }), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -215,7 +215,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
public void DeleteApiKey_UnknownKey_ReturnsManagementError_AndDoesNotAudit()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new DeleteApiKeyCommand("key-unknown"), "Admin"));
|
||||
actor.Tell(Envelope(new DeleteApiKeyCommand("key-unknown"), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -232,7 +232,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
public void CreateApiKey_EmptyMethods_ReturnsManagementError()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new CreateApiKeyCommand("MES-Production", Array.Empty<string>()), "Admin"));
|
||||
actor.Tell(Envelope(new CreateApiKeyCommand("MES-Production", Array.Empty<string>()), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -249,7 +249,7 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
_admin.Seed("key-1", "Service A", enabled: true, "M1");
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new SetApiKeyMethodsCommand("key-1", Array.Empty<string>()), "Admin"));
|
||||
actor.Tell(Envelope(new SetApiKeyMethodsCommand("key-1", Array.Empty<string>()), "Administrator"));
|
||||
|
||||
var response = ExpectMsg<ManagementError>(TimeSpan.FromSeconds(5));
|
||||
|
||||
@@ -265,11 +265,11 @@ public class ApiKeyCreationTests : TestKit, IDisposable
|
||||
public void EveryApiKeyCommand_RequiresAdminRole(object command)
|
||||
{
|
||||
var actor = CreateActor();
|
||||
// A Design-role caller (not Admin) must be rejected for every API-key command.
|
||||
actor.Tell(Envelope(command, "Design"));
|
||||
// A Designer-role caller (not Administrator) must be rejected for every API-key command.
|
||||
actor.Tell(Envelope(command, "Designer"));
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Admin", response.Message);
|
||||
Assert.Contains("Administrator", response.Message);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> AllApiKeyCommands() => new[]
|
||||
|
||||
@@ -125,7 +125,7 @@ public class AuditEndpointsTests
|
||||
public async Task Query_ValidParams_ReturnsJsonPage()
|
||||
{
|
||||
var (client, _, host) = await BuildHostAsync(
|
||||
roles: new[] { "Audit" },
|
||||
roles: new[] { "Administrator" },
|
||||
queryPages: new[] { (IReadOnlyList<AuditEvent>)new[] { SampleEvent() } });
|
||||
using (host)
|
||||
{
|
||||
@@ -160,7 +160,7 @@ public class AuditEndpointsTests
|
||||
new DateTime(2026, 5, 20, 11, 0, 0, DateTimeKind.Utc)),
|
||||
};
|
||||
var (client, repo, host) = await BuildHostAsync(
|
||||
roles: new[] { "Audit" },
|
||||
roles: new[] { "Administrator" },
|
||||
queryPages: new[] { pageOne });
|
||||
using (host)
|
||||
{
|
||||
@@ -193,9 +193,9 @@ public class AuditEndpointsTests
|
||||
[Fact]
|
||||
public async Task Query_WithoutOperationalAudit_Returns403()
|
||||
{
|
||||
// A user whose only role is Design holds neither OperationalAudit nor
|
||||
// A user whose only role is Designer holds neither OperationalAudit nor
|
||||
// AuditExport — the query endpoint must 403.
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Design" });
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Designer" });
|
||||
using (host)
|
||||
{
|
||||
var response = await client.SendAsync(Get("/api/audit/query"));
|
||||
@@ -206,7 +206,7 @@ public class AuditEndpointsTests
|
||||
[Fact]
|
||||
public async Task Query_WithoutCredentials_Returns401()
|
||||
{
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Audit" });
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Administrator" });
|
||||
using (host)
|
||||
{
|
||||
var response = await client.SendAsync(Get("/api/audit/query", credential: ""));
|
||||
@@ -215,10 +215,11 @@ public class AuditEndpointsTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Query_AuditReadOnlyRole_IsAllowed()
|
||||
public async Task Query_ViewerRole_IsAllowed()
|
||||
{
|
||||
// AuditReadOnly satisfies OperationalAudit (read) — query must succeed.
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "AuditReadOnly" });
|
||||
// Viewer (post Task 1.7 home of the former AuditReadOnly role) satisfies
|
||||
// OperationalAudit (read) — query must succeed.
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Viewer" });
|
||||
using (host)
|
||||
{
|
||||
var response = await client.SendAsync(Get("/api/audit/query"));
|
||||
@@ -234,7 +235,7 @@ public class AuditEndpointsTests
|
||||
public async Task Export_Csv_StreamsContent_WithCsvContentType()
|
||||
{
|
||||
var (client, _, host) = await BuildHostAsync(
|
||||
roles: new[] { "Audit" },
|
||||
roles: new[] { "Administrator" },
|
||||
queryPages: new[]
|
||||
{
|
||||
(IReadOnlyList<AuditEvent>)new[] { SampleEvent() },
|
||||
@@ -263,7 +264,7 @@ public class AuditEndpointsTests
|
||||
{
|
||||
// No format= param → csv default.
|
||||
var (client, _, host) = await BuildHostAsync(
|
||||
roles: new[] { "Audit" },
|
||||
roles: new[] { "Administrator" },
|
||||
queryPages: new[] { (IReadOnlyList<AuditEvent>)Array.Empty<AuditEvent>() });
|
||||
using (host)
|
||||
{
|
||||
@@ -277,7 +278,7 @@ public class AuditEndpointsTests
|
||||
public async Task Export_Jsonl_StreamsOnePerLine()
|
||||
{
|
||||
var (client, _, host) = await BuildHostAsync(
|
||||
roles: new[] { "Audit" },
|
||||
roles: new[] { "Administrator" },
|
||||
queryPages: new[]
|
||||
{
|
||||
(IReadOnlyList<AuditEvent>)new[]
|
||||
@@ -313,7 +314,7 @@ public class AuditEndpointsTests
|
||||
{
|
||||
// Parquet archival is deferred to v1.x (Component-AuditLog.md) — no
|
||||
// library is referenced, so the endpoint returns 501 with guidance.
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Audit" });
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Administrator" });
|
||||
using (host)
|
||||
{
|
||||
var response = await client.SendAsync(Get("/api/audit/export?format=parquet"));
|
||||
@@ -327,9 +328,10 @@ public class AuditEndpointsTests
|
||||
[Fact]
|
||||
public async Task Export_WithoutAuditExport_Returns403()
|
||||
{
|
||||
// AuditReadOnly grants read (OperationalAudit) but NOT bulk export
|
||||
// (AuditExport) — the export endpoint must 403.
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "AuditReadOnly" });
|
||||
// Viewer (former AuditReadOnly) grants read (OperationalAudit) but NOT
|
||||
// bulk export (AuditExport) — the export endpoint must 403. This is the
|
||||
// preserved half-SoD after the Task 1.7 AuditReadOnly→Viewer collapse.
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Viewer" });
|
||||
using (host)
|
||||
{
|
||||
var response = await client.SendAsync(Get("/api/audit/export?format=csv"));
|
||||
@@ -340,7 +342,7 @@ public class AuditEndpointsTests
|
||||
[Fact]
|
||||
public async Task Export_UnsupportedFormat_Returns400()
|
||||
{
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Audit" });
|
||||
var (client, _, host) = await BuildHostAsync(roles: new[] { "Administrator" });
|
||||
using (host)
|
||||
{
|
||||
var response = await client.SendAsync(Get("/api/audit/export?format=xml"));
|
||||
@@ -496,7 +498,7 @@ public class AuditEndpointsTests
|
||||
{
|
||||
// End-to-end: a repeated channel= query param must surface at the
|
||||
// repository as a two-element Channels list.
|
||||
var (client, repo, host) = await BuildHostAsync(roles: new[] { "Audit" });
|
||||
var (client, repo, host) = await BuildHostAsync(roles: new[] { "Administrator" });
|
||||
using (host)
|
||||
{
|
||||
var response = await client.SendAsync(Get(
|
||||
@@ -537,11 +539,11 @@ public class AuditEndpointsTests
|
||||
[Fact]
|
||||
public void ApplySiteScope_SystemWideUser_ReturnsFilterUnchanged()
|
||||
{
|
||||
// Empty PermittedSiteIds is the system-wide signal (Admin, system-wide
|
||||
// Deployment, audit roles with no scope rules attached). The filter
|
||||
// should pass through with no restriction added.
|
||||
// Empty PermittedSiteIds is the system-wide signal (Administrator,
|
||||
// system-wide Deployer, audit roles with no scope rules attached). The
|
||||
// filter should pass through with no restriction added.
|
||||
var user = new ZB.MOM.WW.ScadaBridge.Commons.Messages.Management.AuthenticatedUser(
|
||||
"alice", "Alice", new[] { "Admin" }, Array.Empty<string>());
|
||||
"alice", "Alice", new[] { "Administrator" }, Array.Empty<string>());
|
||||
var filter = new AuditLogQueryFilter(SourceSiteIds: new[] { "plant-a" });
|
||||
|
||||
var result = AuditEndpoints.ApplySiteScope(filter, user);
|
||||
@@ -557,7 +559,7 @@ public class AuditEndpointsTests
|
||||
// the query to the user's permitted set, otherwise a site-scoped audit
|
||||
// user could read every site's rows.
|
||||
var user = new ZB.MOM.WW.ScadaBridge.Commons.Messages.Management.AuthenticatedUser(
|
||||
"alice", "Alice", new[] { "AuditReadOnly" }, new[] { "plant-a", "plant-b" });
|
||||
"alice", "Alice", new[] { "Viewer" }, new[] { "plant-a", "plant-b" });
|
||||
var filter = new AuditLogQueryFilter();
|
||||
|
||||
var result = AuditEndpoints.ApplySiteScope(filter, user);
|
||||
@@ -571,7 +573,7 @@ public class AuditEndpointsTests
|
||||
public void ApplySiteScope_ScopedUser_ExplicitInScopeFilter_KeptVerbatim()
|
||||
{
|
||||
var user = new ZB.MOM.WW.ScadaBridge.Commons.Messages.Management.AuthenticatedUser(
|
||||
"alice", "Alice", new[] { "AuditReadOnly" }, new[] { "plant-a", "plant-b" });
|
||||
"alice", "Alice", new[] { "Viewer" }, new[] { "plant-a", "plant-b" });
|
||||
var filter = new AuditLogQueryFilter(SourceSiteIds: new[] { "plant-a" });
|
||||
|
||||
var result = AuditEndpoints.ApplySiteScope(filter, user);
|
||||
@@ -586,7 +588,7 @@ public class AuditEndpointsTests
|
||||
// Caller explicitly asked for a site they cannot see — the helper signals
|
||||
// "403" by returning null rather than silently producing an empty page.
|
||||
var user = new ZB.MOM.WW.ScadaBridge.Commons.Messages.Management.AuthenticatedUser(
|
||||
"alice", "Alice", new[] { "AuditReadOnly" }, new[] { "plant-a" });
|
||||
"alice", "Alice", new[] { "Viewer" }, new[] { "plant-a" });
|
||||
var filter = new AuditLogQueryFilter(SourceSiteIds: new[] { "plant-b" });
|
||||
|
||||
var result = AuditEndpoints.ApplySiteScope(filter, user);
|
||||
@@ -598,7 +600,7 @@ public class AuditEndpointsTests
|
||||
public void ApplySiteScope_ScopedUser_MixedInAndOutOfScopeFilter_IntersectedToInScopeOnly()
|
||||
{
|
||||
var user = new ZB.MOM.WW.ScadaBridge.Commons.Messages.Management.AuthenticatedUser(
|
||||
"alice", "Alice", new[] { "AuditReadOnly" }, new[] { "plant-a" });
|
||||
"alice", "Alice", new[] { "Viewer" }, new[] { "plant-a" });
|
||||
var filter = new AuditLogQueryFilter(SourceSiteIds: new[] { "plant-a", "plant-b" });
|
||||
|
||||
var result = AuditEndpoints.ApplySiteScope(filter, user);
|
||||
|
||||
@@ -12,7 +12,7 @@ public class DebugStreamHubTests
|
||||
public void IsInstanceAccessAllowed_SiteScopedUser_InScopeInstance_Allowed()
|
||||
{
|
||||
var allowed = DebugStreamHub.IsInstanceAccessAllowed(
|
||||
roles: new[] { "Deployment" },
|
||||
roles: new[] { "Deployer" },
|
||||
permittedSiteIds: new[] { "1", "2" },
|
||||
instanceSiteId: 2);
|
||||
|
||||
@@ -23,7 +23,7 @@ public class DebugStreamHubTests
|
||||
public void IsInstanceAccessAllowed_SiteScopedUser_OutOfScopeInstance_Denied()
|
||||
{
|
||||
var allowed = DebugStreamHub.IsInstanceAccessAllowed(
|
||||
roles: new[] { "Deployment" },
|
||||
roles: new[] { "Deployer" },
|
||||
permittedSiteIds: new[] { "1", "2" },
|
||||
instanceSiteId: 99);
|
||||
|
||||
@@ -33,9 +33,9 @@ public class DebugStreamHubTests
|
||||
[Fact]
|
||||
public void IsInstanceAccessAllowed_SystemWideDeployment_AnySiteAllowed()
|
||||
{
|
||||
// Empty permitted set == system-wide Deployment.
|
||||
// Empty permitted set == system-wide Deployer.
|
||||
var allowed = DebugStreamHub.IsInstanceAccessAllowed(
|
||||
roles: new[] { "Deployment" },
|
||||
roles: new[] { "Deployer" },
|
||||
permittedSiteIds: Array.Empty<string>(),
|
||||
instanceSiteId: 99);
|
||||
|
||||
@@ -46,7 +46,7 @@ public class DebugStreamHubTests
|
||||
public void IsInstanceAccessAllowed_AdminRole_BypassesSiteScope()
|
||||
{
|
||||
var allowed = DebugStreamHub.IsInstanceAccessAllowed(
|
||||
roles: new[] { "Admin", "Deployment" },
|
||||
roles: new[] { "Administrator", "Deployer" },
|
||||
permittedSiteIds: new[] { "1" },
|
||||
instanceSiteId: 99);
|
||||
|
||||
@@ -57,7 +57,7 @@ public class DebugStreamHubTests
|
||||
public void IsInstanceAccessAllowed_AdminRoleCheck_IsCaseInsensitive()
|
||||
{
|
||||
var allowed = DebugStreamHub.IsInstanceAccessAllowed(
|
||||
roles: new[] { "admin" },
|
||||
roles: new[] { "administrator" },
|
||||
permittedSiteIds: new[] { "1" },
|
||||
instanceSiteId: 99);
|
||||
|
||||
|
||||
@@ -61,12 +61,12 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
public void CreateSiteCommand_WithDesignRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new CreateSiteCommand("Site1", "SITE1", "Desc"), "Design");
|
||||
var envelope = Envelope(new CreateSiteCommand("Site1", "SITE1", "Desc"), "Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Admin", response.Message);
|
||||
Assert.Contains("Administrator", response.Message);
|
||||
Assert.Equal(envelope.CorrelationId, response.CorrelationId);
|
||||
}
|
||||
|
||||
@@ -79,19 +79,19 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Admin", response.Message);
|
||||
Assert.Contains("Administrator", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DeploymentCommand_WithDesignRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new CreateInstanceCommand("Inst1", 1, 1), "Design");
|
||||
var envelope = Envelope(new CreateInstanceCommand("Inst1", 1, 1), "Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Deployment", response.Message);
|
||||
Assert.Contains("Deployer", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -109,19 +109,19 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Admin", response.Message);
|
||||
Assert.Contains("Administrator", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void QueryAuditLogCommand_WithDeploymentRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new QueryAuditLogCommand(null, null, null, null, null, 1, 25), "Deployment");
|
||||
var envelope = Envelope(new QueryAuditLogCommand(null, null, null, null, null, 1, 25), "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Admin", response.Message);
|
||||
Assert.Contains("Administrator", response.Message);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
@@ -154,7 +154,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => siteRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new ListSitesCommand(), "Design");
|
||||
var envelope = Envelope(new ListSitesCommand(), "Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -220,7 +220,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new CreateInstanceCommand("Pump1", 1, 1),
|
||||
"Deployment");
|
||||
"Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -264,7 +264,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new CreateInstanceCommand("BadInst", 99, 1),
|
||||
"Deployment");
|
||||
"Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -280,16 +280,16 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
[Fact]
|
||||
public void DesignCommand_WithAdminRole_ReturnsUnauthorized()
|
||||
{
|
||||
// CreateTemplateCommand requires "Design" role, "Admin" alone is insufficient
|
||||
// CreateTemplateCommand requires "Designer" role, "Administrator" alone is insufficient
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new CreateTemplateCommand("T1", null, null),
|
||||
"Admin");
|
||||
"Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Design", response.Message);
|
||||
Assert.Contains("Designer", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -305,7 +305,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new CreateSiteCommand("NewSite", "NS1", "Desc"),
|
||||
"Admin");
|
||||
"Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -324,10 +324,10 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => siteRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
// "admin" lowercase should still match "Admin" requirement
|
||||
// "administrator" lowercase should still match "Administrator" requirement
|
||||
var envelope = Envelope(
|
||||
new CreateSiteCommand("Site2", "S2", null),
|
||||
"admin");
|
||||
"administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -343,84 +343,84 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
public void SharedScriptCreate_WithAdminRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new CreateSharedScriptCommand("Script1", "code", null, null), "Admin");
|
||||
var envelope = Envelope(new CreateSharedScriptCommand("Script1", "code", null, null), "Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Design", response.Message);
|
||||
Assert.Contains("Designer", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DatabaseConnectionCreate_WithDeploymentRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new CreateDatabaseConnectionDefCommand("DB1", "Server=test"), "Deployment");
|
||||
var envelope = Envelope(new CreateDatabaseConnectionDefCommand("DB1", "Server=test"), "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Design", response.Message);
|
||||
Assert.Contains("Designer", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApiMethodCreate_WithAdminRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new CreateApiMethodCommand("Method1", "code", 30, null, null), "Admin");
|
||||
var envelope = Envelope(new CreateApiMethodCommand("Method1", "code", 30, null, null), "Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Design", response.Message);
|
||||
Assert.Contains("Designer", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddTemplateAttribute_WithDeploymentRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new AddTemplateAttributeCommand(1, "Attr1", "Float", null, null, null, false), "Deployment");
|
||||
var envelope = Envelope(new AddTemplateAttributeCommand(1, "Attr1", "Float", null, null, null, false), "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Design", response.Message);
|
||||
Assert.Contains("Designer", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UpdateApiKey_WithDesignRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new UpdateApiKeyCommand("key-1", true), "Design");
|
||||
var envelope = Envelope(new UpdateApiKeyCommand("key-1", true), "Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Admin", response.Message);
|
||||
Assert.Contains("Administrator", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddScopeRule_WithDesignRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new AddScopeRuleCommand(1, 1), "Design");
|
||||
var envelope = Envelope(new AddScopeRuleCommand(1, 1), "Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Admin", response.Message);
|
||||
Assert.Contains("Administrator", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UpdateArea_WithAdminRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new UpdateAreaCommand(1, "NewName"), "Admin");
|
||||
var envelope = Envelope(new UpdateAreaCommand(1, "NewName"), "Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Design", response.Message);
|
||||
Assert.Contains("Designer", response.Message);
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
@@ -486,7 +486,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => secRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new ListScopeRulesCommand(1), "Admin");
|
||||
var envelope = Envelope(new ListScopeRulesCommand(1), "Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -545,7 +545,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
.Returns(new Instance("Pump7") { Id = 7, SiteId = 2 });
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new GetInstanceCommand(7), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new GetInstanceCommand(7), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -560,7 +560,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
.Returns(new Instance("Pump7") { Id = 7, SiteId = 1 });
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new GetInstanceCommand(7), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new GetInstanceCommand(7), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -573,7 +573,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
AddSiteRepoWithSite(2, "SITE2");
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new GetSiteCommand(2), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new GetSiteCommand(2), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -591,7 +591,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => uiRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new ListAreasCommand(2), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new ListAreasCommand(2), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -608,7 +608,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => siteRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new GetDataConnectionCommand(5), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new GetDataConnectionCommand(5), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -623,7 +623,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
AddSiteRepoWithSite(2, "SITE2");
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new GetSiteCommand(2), new[] { "1" }, "Admin");
|
||||
var envelope = ScopedEnvelope(new GetSiteCommand(2), new[] { "1" }, "Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -637,7 +637,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
AddSiteRepoWithSite(2, "SITE2");
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new QueryEventLogsCommand("SITE2"), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new QueryEventLogsCommand("SITE2"), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -651,7 +651,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
AddSiteRepoWithSite(2, "SITE2");
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new QueryParkedMessagesCommand("SITE2"), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new QueryParkedMessagesCommand("SITE2"), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -665,7 +665,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
AddSiteRepoWithSite(2, "SITE2");
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new RetryParkedMessageCommand("SITE2", "msg-1"), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new RetryParkedMessageCommand("SITE2", "msg-1"), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -679,7 +679,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
AddSiteRepoWithSite(2, "SITE2");
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new DiscardParkedMessageCommand("SITE2", "msg-1"), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new DiscardParkedMessageCommand("SITE2", "msg-1"), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -696,7 +696,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
AddSiteRepoWithSite(2, "SITE2");
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new DebugSnapshotCommand(9), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new DebugSnapshotCommand(9), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -808,12 +808,12 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
public void QueryDeployments_WithDesignRole_ReturnsUnauthorized()
|
||||
{
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new QueryDeploymentsCommand(), "Design");
|
||||
var envelope = Envelope(new QueryDeploymentsCommand(), "Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Deployment", response.Message);
|
||||
Assert.Contains("Deployer", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -828,7 +828,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => deployRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new QueryDeploymentsCommand(), "Deployment");
|
||||
var envelope = Envelope(new QueryDeploymentsCommand(), "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -846,7 +846,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => deployRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new QueryDeploymentsCommand(InstanceId: 5), "Deployment");
|
||||
var envelope = Envelope(new QueryDeploymentsCommand(InstanceId: 5), "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -864,7 +864,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => deployRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(InstanceId: 5), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(InstanceId: 5), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -885,7 +885,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => deployRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(InstanceId: 5), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(InstanceId: 5), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -914,7 +914,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => deployRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -951,7 +951,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => deployRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(), new[] { "1" }, "Deployment");
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(), new[] { "1" }, "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -974,7 +974,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
_services.AddScoped(_ => deployRepo);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(), new[] { "1" }, "Admin", "Deployment");
|
||||
var envelope = ScopedEnvelope(new QueryDeploymentsCommand(), new[] { "1" }, "Administrator", "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1006,7 +1006,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
// "Good" is valid, "Bogus" is not — the whole command must fail with
|
||||
// nothing written.
|
||||
var overrides = new Dictionary<string, string?> { ["Good"] = "1", ["Bogus"] = "2" };
|
||||
var envelope = Envelope(new SetInstanceOverridesCommand(3, overrides), "Deployment");
|
||||
var envelope = Envelope(new SetInstanceOverridesCommand(3, overrides), "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1036,7 +1036,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
|
||||
var actor = CreateActor();
|
||||
var overrides = new Dictionary<string, string?> { ["A"] = "1", ["B"] = "2" };
|
||||
var envelope = Envelope(new SetInstanceOverridesCommand(4, overrides), "Deployment");
|
||||
var envelope = Envelope(new SetInstanceOverridesCommand(4, overrides), "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1095,7 +1095,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new UpdateSmtpConfigCommand(1, "new.example.com", 465, "Basic", "new@example.com", "SSL", "user:pass"),
|
||||
"Design");
|
||||
"Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1125,7 +1125,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new UpdateSmtpConfigCommand(1, "new.example.com", 465, "Basic", "new@example.com"),
|
||||
"Design");
|
||||
"Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1148,7 +1148,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
.Returns((Template?)null);
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new CreateInstanceCommand("BadInst", 99, 1), "Deployment");
|
||||
var envelope = Envelope(new CreateInstanceCommand("BadInst", 99, 1), "Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1228,12 +1228,12 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
// ExportBundle requires the Design role; an Admin-only caller is rejected.
|
||||
AddBundleSubstitutes();
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(AllExportCommand(), "Admin");
|
||||
var envelope = Envelope(AllExportCommand(), "Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Design", response.Message);
|
||||
Assert.Contains("Designer", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -1244,12 +1244,12 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
// configuration).
|
||||
AddBundleSubstitutes();
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new PreviewBundleCommand("AA==", null), "Design");
|
||||
var envelope = Envelope(new PreviewBundleCommand("AA==", null), "Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Admin", response.Message);
|
||||
Assert.Contains("Administrator", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -1257,12 +1257,12 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
{
|
||||
AddBundleSubstitutes();
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new ImportBundleCommand("AA==", null, "skip"), "Design");
|
||||
var envelope = Envelope(new ImportBundleCommand("AA==", null, "skip"), "Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Admin", response.Message);
|
||||
Assert.Contains("Administrator", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -1286,7 +1286,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
SourceEnvironment: "test-env");
|
||||
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(cmd, "Design");
|
||||
var envelope = Envelope(cmd, "Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1331,7 +1331,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
// base64 check before reaching the importer.
|
||||
var payload = Convert.ToBase64String(new byte[] { 0x01, 0x02, 0x03 });
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(new ImportBundleCommand(payload, null, "skip"), "Admin");
|
||||
var envelope = Envelope(new ImportBundleCommand(payload, null, "skip"), "Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1399,7 +1399,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
// "overwrite" policy so the final (Identical) row would otherwise differ
|
||||
// from the Modified row's action — proves the last-write-wins semantics.
|
||||
var envelope = Envelope(new ImportBundleCommand(payload, null, "overwrite"), "Admin");
|
||||
var envelope = Envelope(new ImportBundleCommand(payload, null, "overwrite"), "Administrator");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1425,7 +1425,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new AddTemplateNativeAlarmSourceCommand(1, "Pressure", "Opc", "ns=2;s=T01", null, "desc", false),
|
||||
"Design");
|
||||
"Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1440,12 +1440,12 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new AddTemplateNativeAlarmSourceCommand(1, "Pressure", "Opc", "ns=2;s=T01", null, null, false),
|
||||
"Deployment");
|
||||
"Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Design", response.Message);
|
||||
Assert.Contains("Designer", response.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -1473,7 +1473,7 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new SetInstanceNativeAlarmSourceOverrideCommand(1, "Pressure", "Opc2", "ns=2;s=NEW", null),
|
||||
"Deployment");
|
||||
"Deployer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
@@ -1488,11 +1488,11 @@ public class ManagementActorTests : TestKit, IDisposable
|
||||
var actor = CreateActor();
|
||||
var envelope = Envelope(
|
||||
new SetInstanceNativeAlarmSourceOverrideCommand(1, "Pressure", "Opc2", "ns=2;s=NEW", null),
|
||||
"Design");
|
||||
"Designer");
|
||||
|
||||
actor.Tell(envelope);
|
||||
|
||||
var response = ExpectMsg<ManagementUnauthorized>(TimeSpan.FromSeconds(5));
|
||||
Assert.Contains("Deployment", response.Message);
|
||||
Assert.Contains("Deployer", response.Message);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user