112 lines
4.9 KiB
C#
112 lines
4.9 KiB
C#
using ZB.MOM.WW.MxGateway.Contracts.Proto;
|
|
using ZB.MOM.WW.MxGateway.Contracts.Proto.Galaxy;
|
|
using ZB.MOM.WW.MxGateway.Server.Security.Authorization;
|
|
|
|
namespace ZB.MOM.WW.MxGateway.Tests.Security.Authorization;
|
|
|
|
public sealed class GatewayGrpcScopeResolverTests
|
|
{
|
|
/// <summary>Verifies that ResolveRequiredScope returns the expected scope for known RPC request types.</summary>
|
|
/// <param name="requestType">The gRPC request type to test.</param>
|
|
/// <param name="expectedScope">The expected scope for the request.</param>
|
|
[Theory]
|
|
[InlineData(typeof(OpenSessionRequest), GatewayScopes.SessionOpen)]
|
|
[InlineData(typeof(CloseSessionRequest), GatewayScopes.SessionClose)]
|
|
[InlineData(typeof(StreamEventsRequest), GatewayScopes.EventsRead)]
|
|
[InlineData(typeof(AcknowledgeAlarmRequest), GatewayScopes.InvokeWrite)]
|
|
[InlineData(typeof(StreamAlarmsRequest), GatewayScopes.EventsRead)]
|
|
[InlineData(typeof(TestConnectionRequest), GatewayScopes.MetadataRead)]
|
|
[InlineData(typeof(GetLastDeployTimeRequest), GatewayScopes.MetadataRead)]
|
|
[InlineData(typeof(DiscoverHierarchyRequest), GatewayScopes.MetadataRead)]
|
|
[InlineData(typeof(WatchDeployEventsRequest), GatewayScopes.MetadataRead)]
|
|
[InlineData(typeof(BrowseChildrenRequest), GatewayScopes.MetadataRead)]
|
|
public void ResolveRequiredScope_KnownRpcRequest_ReturnsExpectedScope(
|
|
Type requestType,
|
|
string expectedScope)
|
|
{
|
|
GatewayGrpcScopeResolver resolver = new();
|
|
object request = Activator.CreateInstance(requestType)!;
|
|
|
|
string scope = resolver.ResolveRequiredScope(request);
|
|
|
|
Assert.Equal(expectedScope, scope);
|
|
}
|
|
|
|
/// <summary>Verifies that ResolveRequiredScope returns the expected scope for MXAccess invoke commands.</summary>
|
|
/// <param name="commandKind">The MXAccess command kind to test.</param>
|
|
/// <param name="expectedScope">The expected scope for the command.</param>
|
|
[Theory]
|
|
[InlineData(MxCommandKind.Register, GatewayScopes.InvokeRead)]
|
|
[InlineData(MxCommandKind.AddItem, GatewayScopes.InvokeRead)]
|
|
[InlineData(MxCommandKind.Advise, GatewayScopes.InvokeRead)]
|
|
[InlineData(MxCommandKind.Write, GatewayScopes.InvokeWrite)]
|
|
[InlineData(MxCommandKind.Write2, GatewayScopes.InvokeWrite)]
|
|
[InlineData(MxCommandKind.WriteSecured, GatewayScopes.InvokeSecure)]
|
|
[InlineData(MxCommandKind.WriteSecured2, GatewayScopes.InvokeSecure)]
|
|
[InlineData(MxCommandKind.WriteBulk, GatewayScopes.InvokeWrite)]
|
|
[InlineData(MxCommandKind.Write2Bulk, GatewayScopes.InvokeWrite)]
|
|
[InlineData(MxCommandKind.WriteSecuredBulk, GatewayScopes.InvokeSecure)]
|
|
[InlineData(MxCommandKind.WriteSecured2Bulk, GatewayScopes.InvokeSecure)]
|
|
[InlineData(MxCommandKind.ReadBulk, GatewayScopes.InvokeRead)]
|
|
[InlineData(MxCommandKind.AuthenticateUser, GatewayScopes.InvokeSecure)]
|
|
[InlineData(MxCommandKind.ArchestraUserToId, GatewayScopes.MetadataRead)]
|
|
[InlineData(MxCommandKind.GetSessionState, GatewayScopes.MetadataRead)]
|
|
[InlineData(MxCommandKind.GetWorkerInfo, GatewayScopes.MetadataRead)]
|
|
[InlineData(MxCommandKind.DrainEvents, GatewayScopes.EventsRead)]
|
|
[InlineData(MxCommandKind.ShutdownWorker, GatewayScopes.Admin)]
|
|
public void ResolveRequiredScope_InvokeCommand_ReturnsExpectedScope(
|
|
MxCommandKind commandKind,
|
|
string expectedScope)
|
|
{
|
|
GatewayGrpcScopeResolver resolver = new();
|
|
|
|
string scope = resolver.ResolveRequiredScope(new MxCommandRequest
|
|
{
|
|
Command = new MxCommand
|
|
{
|
|
Kind = commandKind
|
|
}
|
|
});
|
|
|
|
Assert.Equal(expectedScope, scope);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies that an unmapped request type fails closed: the resolver returns the
|
|
/// most-restrictive <see cref="GatewayScopes.Admin"/> scope rather than a permissive
|
|
/// default, so a newly added RPC that is never mapped is denied to ordinary keys.
|
|
/// </summary>
|
|
[Fact]
|
|
public void ResolveRequiredScope_UnmappedRequestType_FailsClosedToAdminScope()
|
|
{
|
|
GatewayGrpcScopeResolver resolver = new();
|
|
|
|
string scope = resolver.ResolveRequiredScope(new UnmappedRequest());
|
|
|
|
Assert.Equal(GatewayScopes.Admin, scope);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies that an <see cref="MxCommandRequest"/> with an unrecognized command kind
|
|
/// resolves to the read scope rather than silently granting write or admin access.
|
|
/// </summary>
|
|
[Fact]
|
|
public void ResolveRequiredScope_UnknownInvokeCommandKind_ReturnsInvokeReadScope()
|
|
{
|
|
GatewayGrpcScopeResolver resolver = new();
|
|
|
|
string scope = resolver.ResolveRequiredScope(new MxCommandRequest
|
|
{
|
|
Command = new MxCommand
|
|
{
|
|
Kind = (MxCommandKind)9999,
|
|
},
|
|
});
|
|
|
|
Assert.Equal(GatewayScopes.InvokeRead, scope);
|
|
}
|
|
|
|
/// <summary>Request type intentionally not mapped by the scope resolver.</summary>
|
|
private sealed class UnmappedRequest;
|
|
}
|