using System.Collections.Frozen; using FinalFactory.Rendezvous.Contracts; namespace FinalFactory.Rendezvous.Server.Provisioning; internal abstract record AuthenticatedPrincipal( string Subject, DateTimeOffset ExpiresAt); internal interface IPublisherPrincipal { string Subject { get; } DateTimeOffset ExpiresAt { get; } GameId GameId { get; } EnvironmentId EnvironmentId { get; } PublisherTrustMode TrustMode { get; } IReadOnlySet AllowedRegions { get; } } internal sealed record DedicatedPublisherPrincipal : AuthenticatedPrincipal, IPublisherPrincipal { public DedicatedPublisherPrincipal( string subject, DateTimeOffset expiresAt, GameId gameId, EnvironmentId environmentId, IEnumerable allowedRegions) : base(subject, expiresAt) { GameId = gameId; EnvironmentId = environmentId; AllowedRegions = allowedRegions.ToFrozenSet(); } public GameId GameId { get; } public EnvironmentId EnvironmentId { get; } public IReadOnlySet AllowedRegions { get; } public PublisherTrustMode TrustMode => PublisherTrustMode.ManagedDedicated; } internal sealed record PlayerHostGrantPrincipal : AuthenticatedPrincipal, IPublisherPrincipal { public PlayerHostGrantPrincipal( string subject, DateTimeOffset expiresAt, GameId gameId, EnvironmentId environmentId, IEnumerable allowedRegions) : base(subject, expiresAt) { GameId = gameId; EnvironmentId = environmentId; AllowedRegions = allowedRegions.ToFrozenSet(); } public GameId GameId { get; } public EnvironmentId EnvironmentId { get; } public IReadOnlySet AllowedRegions { get; } public PublisherTrustMode TrustMode => PublisherTrustMode.PlayerGrant; } internal sealed record AnonymousUnlistedPrincipal : AuthenticatedPrincipal, IPublisherPrincipal { public AnonymousUnlistedPrincipal( string subject, DateTimeOffset expiresAt, GameId gameId, EnvironmentId environmentId, IEnumerable allowedRegions) : base(subject, expiresAt) { GameId = gameId; EnvironmentId = environmentId; AllowedRegions = allowedRegions.ToFrozenSet(); } public GameId GameId { get; } public EnvironmentId EnvironmentId { get; } public IReadOnlySet AllowedRegions { get; } public PublisherTrustMode TrustMode => PublisherTrustMode.AnonymousUnlisted; } internal sealed record OperatorPrincipal : AuthenticatedPrincipal { public OperatorPrincipal( string subject, DateTimeOffset expiresAt, IEnumerable permissions) : base(subject, expiresAt) => Permissions = permissions.ToFrozenSet(); public IReadOnlySet Permissions { get; } } internal enum OperatorPermission { ReadPolicy = 1, ManagePolicy = 2, RevokePublisher = 3, RotateKeys = 4, } internal enum PrincipalCredentialKind { DedicatedPublisher = 1, PlayerHostGrant = 2, Operator = 3, }