| | | 1 | | namespace ArturRios.Heimdall.Command.Services; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Who an authentication token is being issued for (UC-11 step 6, FR-AU-04). Every identifier is |
| | | 5 | | /// a <c>PublicId</c>: internal <c>bigint</c> Ids never reach a token (NFR-15). |
| | | 6 | | /// </summary> |
| | | 7 | | /// <param name="PersonId">The authenticated person's <c>PublicId</c>.</param> |
| | | 8 | | /// <param name="DisplayName">Their display name, included for downstream profile provisioning.</param> |
| | | 9 | | /// <param name="RoleId">Their role value (see <c>Roles</c>).</param> |
| | | 10 | | /// <param name="ScopeId"> |
| | | 11 | | /// The <c>PublicId</c> of the scope a <c>User</c> belongs to; <c>null</c> for a |
| | | 12 | | /// <c>ScopeAdmin</c> or <c>SystemAdmin</c>. |
| | | 13 | | /// </param> |
| | | 14 | | /// <param name="OwnedScopeIds"> |
| | | 15 | | /// The <c>PublicId</c>s of the non-deleted scopes a <c>ScopeAdmin</c> owns; empty otherwise. |
| | | 16 | | /// </param> |
| | | 17 | | /// <param name="SecurityStamp"> |
| | | 18 | | /// The person's current <c>SecurityStamp</c>, which the token carries so a later credential |
| | | 19 | | /// change revokes it (FR-AU-11); <c>null</c> for a Google User, who has none. Required, with no |
| | | 20 | | /// default, so an issuer cannot build a person's subject and forget it: a Google User's caller |
| | | 21 | | /// passes <c>null</c> on purpose. |
| | | 22 | | /// </param> |
| | | 23 | | public record AuthTokenSubject( |
| | | 24 | | Guid PersonId, |
| | | 25 | | string DisplayName, |
| | | 26 | | int RoleId, |
| | | 27 | | Guid? ScopeId, |
| | | 28 | | IReadOnlyCollection<Guid> OwnedScopeIds, |
| | | 29 | | Guid? SecurityStamp); |
| | | 30 | | |
| | | 31 | | /// <summary>An issued authentication token and the moment it stops being valid.</summary> |
| | | 32 | | /// <param name="Token">The signed token.</param> |
| | | 33 | | /// <param name="ExpiresAt">The token's expiry, in UTC.</param> |
| | 557 | 34 | | public record AuthToken(string Token, DateTime ExpiresAt); |
| | | 35 | | |
| | | 36 | | /// <summary> |
| | | 37 | | /// Issues the authentication token UC-11 returns on a successful login (FR-AU-03). The signing |
| | | 38 | | /// scheme and the claim vocabulary belong to the presentation layer, so the application layer |
| | | 39 | | /// only says who the token is for. The call is asynchronous because the presentation's |
| | | 40 | | /// implementation reads the acting scope's flagged permissions from the database before it |
| | | 41 | | /// builds the claims (UC-31…UC-35, FR-SP). |
| | | 42 | | /// </summary> |
| | | 43 | | public interface IAuthTokenIssuer |
| | | 44 | | { |
| | | 45 | | /// <param name="subject">The person the token represents, and the scopes it should claim.</param> |
| | | 46 | | /// <returns>The signed token and its expiry.</returns> |
| | | 47 | | Task<AuthToken> IssueAsync(AuthTokenSubject subject); |
| | | 48 | | |
| | | 49 | | /// <summary> |
| | | 50 | | /// Issues the token a restricted identity receives when its credential checks out (NFR-24, |
| | | 51 | | /// UC-45): it names the subject and their role and nothing else — no scope, no owned scopes, |
| | | 52 | | /// no scope permissions — and is marked as admitting only the endpoints through which a |
| | | 53 | | /// subject exercises a right over their own identity (UC-41, UC-42, UC-44, UC-45). |
| | | 54 | | /// </summary> |
| | | 55 | | /// <param name="subjectId">The restricted identity's <c>PublicId</c>.</param> |
| | | 56 | | /// <param name="roleId">Its role value (see <c>Roles</c>); a Google User's is always <c>User</c>.</param> |
| | | 57 | | /// <param name="securityStamp"> |
| | | 58 | | /// A person's current <c>SecurityStamp</c> (FR-AU-11); <c>null</c> for a Google User. |
| | | 59 | | /// </param> |
| | | 60 | | /// <returns>The signed token and its expiry.</returns> |
| | | 61 | | Task<AuthToken> IssueSubjectRightsOnlyAsync(Guid subjectId, int roleId, Guid? securityStamp); |
| | | 62 | | } |