This commit is contained in:
		| @@ -0,0 +1,70 @@ | ||||
| using System.Collections.ObjectModel; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace StellaOps.Zastava.Core.Security; | ||||
|  | ||||
| public readonly record struct ZastavaOperationalToken( | ||||
|     string AccessToken, | ||||
|     string TokenType, | ||||
|     DateTimeOffset? ExpiresAtUtc, | ||||
|     IReadOnlyList<string> Scopes) | ||||
| { | ||||
|     public bool IsExpired(TimeProvider timeProvider, TimeSpan refreshSkew) | ||||
|     { | ||||
|         ArgumentNullException.ThrowIfNull(timeProvider); | ||||
|  | ||||
|         if (ExpiresAtUtc is null) | ||||
|         { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return timeProvider.GetUtcNow() >= ExpiresAtUtc.Value - refreshSkew; | ||||
|     } | ||||
|  | ||||
|     public static ZastavaOperationalToken FromResult( | ||||
|         string accessToken, | ||||
|         string tokenType, | ||||
|         DateTimeOffset? expiresAtUtc, | ||||
|         IEnumerable<string> scopes) | ||||
|     { | ||||
|         ArgumentException.ThrowIfNullOrWhiteSpace(accessToken); | ||||
|         ArgumentException.ThrowIfNullOrWhiteSpace(tokenType); | ||||
|  | ||||
|         IReadOnlyList<string> normalized = scopes switch | ||||
|         { | ||||
|             null => Array.Empty<string>(), | ||||
|             IReadOnlyList<string> readOnly => readOnly.Count == 0 ? Array.Empty<string>() : readOnly, | ||||
|             ICollection<string> collection => NormalizeCollection(collection), | ||||
|             _ => NormalizeEnumerable(scopes) | ||||
|         }; | ||||
|  | ||||
|         return new ZastavaOperationalToken( | ||||
|             accessToken, | ||||
|             tokenType, | ||||
|             expiresAtUtc, | ||||
|             normalized); | ||||
|     } | ||||
|  | ||||
|     private static IReadOnlyList<string> NormalizeCollection(ICollection<string> collection) | ||||
|     { | ||||
|         if (collection.Count == 0) | ||||
|         { | ||||
|             return Array.Empty<string>(); | ||||
|         } | ||||
|  | ||||
|         if (collection is IReadOnlyList<string> readOnly) | ||||
|         { | ||||
|             return readOnly; | ||||
|         } | ||||
|  | ||||
|         var buffer = new string[collection.Count]; | ||||
|         collection.CopyTo(buffer, 0); | ||||
|         return new ReadOnlyCollection<string>(buffer); | ||||
|     } | ||||
|  | ||||
|     private static IReadOnlyList<string> NormalizeEnumerable(IEnumerable<string> scopes) | ||||
|     { | ||||
|         var buffer = scopes.ToArray(); | ||||
|         return buffer.Length == 0 ? Array.Empty<string>() : new ReadOnlyCollection<string>(buffer); | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user