using System.Reflection; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Components; using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Layout; using ZB.MOM.WW.ScadaBridge.Security; namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Auth; public class RoutePolicyCoverageTests { [Fact] public void EveryRoutableComponent_HasItsReviewedPolicy_IncludingExternalSecrets() { var expected = new Dictionary { ["/"] = "authenticated", ["/admin/api-keys"] = AuthorizationPolicies.RequireAdmin, ["/admin/api-keys/create"] = AuthorizationPolicies.RequireAdmin, ["/admin/api-keys/{KeyId}/edit"] = AuthorizationPolicies.RequireAdmin, ["/admin/ldap-mappings"] = AuthorizationPolicies.RequireAdmin, ["/admin/ldap-mappings/create"] = AuthorizationPolicies.RequireAdmin, ["/admin/ldap-mappings/{Id:int}/edit"] = AuthorizationPolicies.RequireAdmin, ["/admin/sites"] = AuthorizationPolicies.RequireAdmin, ["/admin/sites/create"] = AuthorizationPolicies.RequireAdmin, ["/admin/sites/{Id:int}/edit"] = AuthorizationPolicies.RequireAdmin, ["/audit/configuration"] = AuthorizationPolicies.OperationalAudit, ["/audit/execution-tree"] = AuthorizationPolicies.OperationalAudit, ["/audit/log"] = AuthorizationPolicies.OperationalAudit, ["/deployment/debug-view"] = AuthorizationPolicies.RequireDeployment, ["/deployment/deployments"] = AuthorizationPolicies.RequireDeployment, ["/deployment/flow-debugger"] = AuthorizationPolicies.RequireFlowDebugger, ["/deployment/instances"] = AuthorizationPolicies.RequireDeployment, ["/deployment/instances/create"] = AuthorizationPolicies.RequireDeployment, ["/deployment/instances/{Id:int}/configure"] = AuthorizationPolicies.RequireDeployment, ["/deployment/topology"] = AuthorizationPolicies.RequireDeployment, ["/design/api-methods/create"] = AuthorizationPolicies.RequireDesign, ["/design/api-methods/{Id:int}/edit"] = AuthorizationPolicies.RequireDesign, ["/design/connections"] = AuthorizationPolicies.RequireDesign, ["/design/connections/create"] = AuthorizationPolicies.RequireDesign, ["/design/connections/{Id:int}/certificates"] = AuthorizationPolicies.RequireAdmin, ["/design/connections/{Id:int}/edit"] = AuthorizationPolicies.RequireDesign, ["/design/data-connections"] = AuthorizationPolicies.RequireDesign, ["/design/data-connections/create"] = AuthorizationPolicies.RequireDesign, ["/design/data-connections/{Id:int}/edit"] = AuthorizationPolicies.RequireDesign, ["/design/db-connections/create"] = AuthorizationPolicies.RequireDesign, ["/design/db-connections/{Id:int}/edit"] = AuthorizationPolicies.RequireDesign, ["/design/external-systems"] = AuthorizationPolicies.RequireDesign, ["/design/external-systems/create"] = AuthorizationPolicies.RequireDesign, ["/design/external-systems/{Id:int}/edit"] = AuthorizationPolicies.RequireDesign, ["/design/schema-library"] = AuthorizationPolicies.RequireDesign, ["/design/shared-scripts"] = AuthorizationPolicies.RequireDesign, ["/design/shared-scripts/create"] = AuthorizationPolicies.RequireDesign, ["/design/shared-scripts/{Id:int}/edit"] = AuthorizationPolicies.RequireDesign, ["/design/templates"] = AuthorizationPolicies.RequireDesign, ["/design/templates/create"] = AuthorizationPolicies.RequireDesign, ["/design/templates/{Id:int}"] = AuthorizationPolicies.RequireDesign, ["/design/transport/export"] = AuthorizationPolicies.RequireDesign, ["/design/transport/import"] = AuthorizationPolicies.RequireAdmin, ["/login"] = "anonymous", ["/monitoring/alarms"] = AuthorizationPolicies.RequireDeployment, ["/monitoring/event-logs"] = AuthorizationPolicies.RequireDeployment, ["/monitoring/health"] = "authenticated", ["/monitoring/parked-messages"] = AuthorizationPolicies.RequireDeployment, ["/notifications/kpis"] = AuthorizationPolicies.RequireDeployment, ["/notifications/lists"] = AuthorizationPolicies.RequireDesign, ["/notifications/lists/create"] = AuthorizationPolicies.RequireDesign, ["/notifications/lists/{Id:int}/edit"] = AuthorizationPolicies.RequireDesign, ["/notifications/report"] = AuthorizationPolicies.RequireDeployment, ["/notifications/sms"] = AuthorizationPolicies.RequireAdmin, ["/notifications/smtp"] = AuthorizationPolicies.RequireAdmin, ["/operations/secured-writes"] = AuthorizationPolicies.RequireSecuredWriteAccess, ["/site-calls/report"] = AuthorizationPolicies.RequireDeployment, ["/admin/secrets"] = "secrets:manage", }; var actual = new Dictionary(); foreach (var type in new[] { typeof(MainLayout).Assembly, typeof(ZB.MOM.WW.Secrets.Ui.SecretsPage).Assembly } .SelectMany(a => a.GetTypes())) { foreach (var route in type.GetCustomAttributes()) { var anonymous = type.IsDefined(typeof(AllowAnonymousAttribute)); var authorization = type.GetCustomAttributes().ToArray(); Assert.True(anonymous || authorization.Length > 0, $"Missing authorization: {route.Template}"); actual.Add(route.Template, anonymous ? "anonymous" : Assert.Single(authorization).Policy ?? "authenticated"); } } Assert.Equal(expected.OrderBy(x => x.Key), actual.OrderBy(x => x.Key)); } }