feat: add tenant provisioning and key lifecycle (#5)
quality-gate / quality (push) Successful in 50s

Closes #5
This commit is contained in:
KyuubiYoru
2026-07-16 05:13:35 +02:00
parent 69c8b2d2bc
commit 47382ddadc
21 changed files with 2294 additions and 6 deletions
@@ -0,0 +1,107 @@
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<RegionId> AllowedRegions { get; }
}
internal sealed record DedicatedPublisherPrincipal : AuthenticatedPrincipal, IPublisherPrincipal
{
public DedicatedPublisherPrincipal(
string subject,
DateTimeOffset expiresAt,
GameId gameId,
EnvironmentId environmentId,
IEnumerable<RegionId> allowedRegions)
: base(subject, expiresAt)
{
GameId = gameId;
EnvironmentId = environmentId;
AllowedRegions = allowedRegions.ToFrozenSet();
}
public GameId GameId { get; }
public EnvironmentId EnvironmentId { get; }
public IReadOnlySet<RegionId> AllowedRegions { get; }
public PublisherTrustMode TrustMode => PublisherTrustMode.ManagedDedicated;
}
internal sealed record PlayerHostGrantPrincipal : AuthenticatedPrincipal, IPublisherPrincipal
{
public PlayerHostGrantPrincipal(
string subject,
DateTimeOffset expiresAt,
GameId gameId,
EnvironmentId environmentId,
IEnumerable<RegionId> allowedRegions)
: base(subject, expiresAt)
{
GameId = gameId;
EnvironmentId = environmentId;
AllowedRegions = allowedRegions.ToFrozenSet();
}
public GameId GameId { get; }
public EnvironmentId EnvironmentId { get; }
public IReadOnlySet<RegionId> AllowedRegions { get; }
public PublisherTrustMode TrustMode => PublisherTrustMode.PlayerGrant;
}
internal sealed record AnonymousUnlistedPrincipal : AuthenticatedPrincipal, IPublisherPrincipal
{
public AnonymousUnlistedPrincipal(
string subject,
DateTimeOffset expiresAt,
GameId gameId,
EnvironmentId environmentId,
IEnumerable<RegionId> allowedRegions)
: base(subject, expiresAt)
{
GameId = gameId;
EnvironmentId = environmentId;
AllowedRegions = allowedRegions.ToFrozenSet();
}
public GameId GameId { get; }
public EnvironmentId EnvironmentId { get; }
public IReadOnlySet<RegionId> AllowedRegions { get; }
public PublisherTrustMode TrustMode => PublisherTrustMode.AnonymousUnlisted;
}
internal sealed record OperatorPrincipal : AuthenticatedPrincipal
{
public OperatorPrincipal(
string subject,
DateTimeOffset expiresAt,
IEnumerable<OperatorPermission> permissions)
: base(subject, expiresAt) => Permissions = permissions.ToFrozenSet();
public IReadOnlySet<OperatorPermission> Permissions { get; }
}
internal enum OperatorPermission
{
ReadPolicy = 1,
ManagePolicy = 2,
RevokePublisher = 3,
RotateKeys = 4,
}
internal enum PrincipalCredentialKind
{
DedicatedPublisher = 1,
PlayerHostGrant = 2,
Operator = 3,
}