using FinalFactory.Rendezvous.Contracts; using FinalFactory.Rendezvous.Server.Provisioning; namespace FinalFactory.Rendezvous.Tests.Provisioning; public sealed class PublisherAuthorizationTests { private static readonly IReadOnlyDictionary ValidMetadata = new Dictionary(StringComparer.Ordinal) { ["mode"] = "co-op", ["map"] = "europa", }; [Fact] public void AuthoritativeScopeComesFromThePublisherPrincipal() { PublisherAuthorizationService service = CreateService(); DedicatedPublisherPrincipal principal = ProvisioningTestData.CreateDedicatedPublisher(); PublisherAuthorizationResult result = service.Authorize( principal, new GameId("space-game"), new EnvironmentId("production"), new RegionId("eu-central"), 7, ListingVisibility.Public, ValidMetadata, ProvisioningTestData.Now); Assert.True(result.IsAllowed); Assert.NotNull(result.Context); Assert.Equal(principal.GameId, result.Context.GameId); Assert.Equal(principal.EnvironmentId, result.Context.EnvironmentId); } [Theory] [InlineData("unscouted", "production")] [InlineData("space-game", "staging")] public void CrossGameAndEnvironmentScopeEscalationIsDenied( string requestedGame, string requestedEnvironment) { PublisherAuthorizationResult result = CreateService().Authorize( ProvisioningTestData.CreateDedicatedPublisher(), new GameId(requestedGame), new EnvironmentId(requestedEnvironment), new RegionId("eu-central"), 7, ListingVisibility.Public, ValidMetadata, ProvisioningTestData.Now); Assert.False(result.IsAllowed); Assert.Equal(PublisherAuthorizationError.ScopeMismatch, result.Error); Assert.Null(result.Context); } [Fact] public void OperatorCannotBeUsedAsAGamePublisher() { OperatorPrincipal principal = new( "operator-1", ProvisioningTestData.Now.AddMinutes(10), new HashSet { OperatorPermission.ReadPolicy }); PublisherAuthorizationResult result = CreateService().Authorize( principal, new GameId("space-game"), new EnvironmentId("production"), new RegionId("eu-central"), 7, ListingVisibility.Public, ValidMetadata, ProvisioningTestData.Now); Assert.Equal(PublisherAuthorizationError.NotPublisher, result.Error); } [Fact] public void AnonymousPublisherCanNeverEscalateToPublicVisibility() { AnonymousUnlistedPrincipal principal = new( "anonymous-source-1", ProvisioningTestData.Now.AddMinutes(2), new GameId("space-game"), new EnvironmentId("production"), new HashSet { new("eu-central") }); PublisherAuthorizationResult result = CreateService().Authorize( principal, principal.GameId, principal.EnvironmentId, new RegionId("eu-central"), 7, ListingVisibility.Public, ValidMetadata, ProvisioningTestData.Now); Assert.Equal(PublisherAuthorizationError.AnonymousMustBeUnlisted, result.Error); } [Fact] public void ExpiredPrincipalIsRecheckedAtAuthorizationTime() { DedicatedPublisherPrincipal principal = ProvisioningTestData.CreateDedicatedPublisher( ProvisioningTestData.Now.AddSeconds(-1)); PublisherAuthorizationResult result = CreateService().Authorize( principal, principal.GameId, principal.EnvironmentId, new RegionId("eu-central"), 7, ListingVisibility.Public, ValidMetadata, ProvisioningTestData.Now); Assert.Equal(PublisherAuthorizationError.PrincipalExpired, result.Error); } private static PublisherAuthorizationService CreateService() => new( GamePolicyRegistry.Create([ProvisioningTestData.CreatePolicy()])); }