-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
34 changed files
with
619 additions
and
661 deletions.
There are no files selected for viewing
236 changes: 123 additions & 113 deletions
236
...dentity.Domain/ApiKeys/ApiKeyAggregate.cs → lib/Logitar.Identity.Core/ApiKeys/ApiKey.cs
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
using Logitar.EventSourcing; | ||
|
||
namespace Logitar.Identity.Core.ApiKeys; | ||
|
||
/// <summary> | ||
/// Represents the identifier of an API key. | ||
/// </summary> | ||
public readonly struct ApiKeyId | ||
{ | ||
/// <summary> | ||
/// Gets the identifier of the event stream. | ||
/// </summary> | ||
public StreamId StreamId { get; } | ||
/// <summary> | ||
/// Gets the value of the identifier. | ||
/// </summary> | ||
public string Value => StreamId.Value; | ||
|
||
/// <summary> | ||
/// Gets the tenant identifier. | ||
/// </summary> | ||
public TenantId? TenantId { get; } | ||
/// <summary> | ||
/// Gets the entity identifier. | ||
/// </summary> | ||
public EntityId EntityId { get; } | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ApiKeyId"/> struct. | ||
/// </summary> | ||
/// <param name="tenantId">The tenant identifier.</param> | ||
/// <param name="entityId">The entity identifier.</param> | ||
public ApiKeyId(TenantId? tenantId, Guid entityId) : this(tenantId, Convert.ToBase64String(entityId.ToByteArray()).ToUriSafeBase64()) | ||
{ | ||
} | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ApiKeyId"/> struct. | ||
/// </summary> | ||
/// <param name="tenantId">The tenant identifier.</param> | ||
/// <param name="entityId">The entity identifier.</param> | ||
public ApiKeyId(TenantId? tenantId, string entityId) | ||
{ | ||
TenantId = tenantId; | ||
EntityId = new(entityId); | ||
StreamId = new(tenantId.HasValue ? $"{tenantId}:{entityId}" : entityId); | ||
} | ||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ApiKeyId"/> struct. | ||
/// </summary> | ||
/// <param name="streamId">A stream identifier.</param> | ||
public ApiKeyId(StreamId streamId) | ||
{ | ||
StreamId = streamId; | ||
} | ||
|
||
/// <summary> | ||
/// Randomly generates a new API key identifier. | ||
/// </summary> | ||
/// <param name="tenantId">The tenant identifier.</param> | ||
/// <returns>The generated identifier.</returns> | ||
public static ApiKeyId NewId(TenantId? tenantId = null) => new(tenantId, Guid.NewGuid()); | ||
|
||
/// <summary> | ||
/// Returns a value indicating whether or not the specified identifiers are equal. | ||
/// </summary> | ||
/// <param name="left">The first identifier to compare.</param> | ||
/// <param name="right">The other identifier to compare.</param> | ||
/// <returns>True if the identifiers are equal.</returns> | ||
public static bool operator ==(ApiKeyId left, ApiKeyId right) => left.Equals(right); | ||
/// <summary> | ||
/// Returns a value indicating whether or not the specified identifiers are different. | ||
/// </summary> | ||
/// <param name="left">The first identifier to compare.</param> | ||
/// <param name="right">The other identifier to compare.</param> | ||
/// <returns>True if the identifiers are different.</returns> | ||
public static bool operator !=(ApiKeyId left, ApiKeyId right) => !left.Equals(right); | ||
|
||
/// <summary> | ||
/// Returns a value indicating whether or not the specified object is equal to the identifier. | ||
/// </summary> | ||
/// <param name="obj">The object to be compared to.</param> | ||
/// <returns>True if the object is equal to the identifier.</returns> | ||
public override bool Equals([NotNullWhen(true)] object? obj) => obj is ApiKeyId id && id.Value == Value; | ||
/// <summary> | ||
/// Returns the hash code of the current identifier. | ||
/// </summary> | ||
/// <returns>The hash code.</returns> | ||
public override int GetHashCode() => Value.GetHashCode(); | ||
/// <summary> | ||
/// Returns a string representation of the identifier. | ||
/// </summary> | ||
/// <returns>The string representation.</returns> | ||
public override string ToString() => Value; | ||
} |
39 changes: 39 additions & 0 deletions
39
lib/Logitar.Identity.Core/ApiKeys/ApiKeyIsExpiredException.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
namespace Logitar.Identity.Core.ApiKeys; | ||
|
||
/// <summary> | ||
/// The exception raised when an expired API key is authenticated. | ||
/// </summary> | ||
public class ApiKeyIsExpiredException : InvalidCredentialsException | ||
{ | ||
/// <summary> | ||
/// A generic error message for this exception. | ||
/// </summary> | ||
private const string ErrorMessage = "The specified API key is expired."; | ||
|
||
/// <summary> | ||
/// Gets the identifier of the expired API key. | ||
/// </summary> | ||
public string ApiKeyId | ||
{ | ||
get => (string)Data[nameof(ApiKeyId)]!; | ||
private set => Data[nameof(ApiKeyId)] = value; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ApiKeyIsExpiredException"/> class. | ||
/// </summary> | ||
/// <param name="apiKey">The API key that is expired.</param> | ||
public ApiKeyIsExpiredException(ApiKey apiKey) : base(BuildMessage(apiKey)) | ||
{ | ||
ApiKeyId = apiKey.Id.Value; | ||
} | ||
|
||
/// <summary> | ||
/// Builds the exception message. | ||
/// </summary> | ||
/// <param name="apiKey">The API key that is expired.</param> | ||
/// <returns>The exception message.</returns> | ||
private static string BuildMessage(ApiKey apiKey) => new ErrorMessageBuilder(ErrorMessage) | ||
.AddData(nameof(ApiKeyId), apiKey.Id) | ||
.Build(); | ||
} |
4 changes: 2 additions & 2 deletions
4
...piKeys/Events/ApiKeyAuthenticatedEvent.cs → ...ore/ApiKeys/Events/ApiKeyAuthenticated.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
using Logitar.EventSourcing; | ||
using MediatR; | ||
|
||
namespace Logitar.Identity.Domain.ApiKeys.Events; | ||
namespace Logitar.Identity.Core.ApiKeys.Events; | ||
|
||
/// <summary> | ||
/// The event raised when an API key is authenticated. | ||
/// </summary> | ||
public class ApiKeyAuthenticatedEvent : DomainEvent, INotification; | ||
public record ApiKeyAuthenticated : DomainEvent, INotification; |
26 changes: 9 additions & 17 deletions
26
...main/ApiKeys/Events/ApiKeyCreatedEvent.cs → ...tity.Core/ApiKeys/Events/ApiKeyCreated.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,40 +1,32 @@ | ||
using Logitar.EventSourcing; | ||
using Logitar.Identity.Domain.Passwords; | ||
using Logitar.Identity.Domain.Shared; | ||
using Logitar.Identity.Core.Passwords; | ||
using MediatR; | ||
|
||
namespace Logitar.Identity.Domain.ApiKeys.Events; | ||
namespace Logitar.Identity.Core.ApiKeys.Events; | ||
|
||
/// <summary> | ||
/// The event raised when a new API key is created. | ||
/// </summary> | ||
public class ApiKeyCreatedEvent : DomainEvent, INotification | ||
public record ApiKeyCreated : DomainEvent, INotification | ||
{ | ||
/// <summary> | ||
/// Gets the secret of the API key. | ||
/// </summary> | ||
public Password Secret { get; } | ||
|
||
/// <summary> | ||
/// Gets the tenant identifier of the API key. | ||
/// Gets the display name of the API key. | ||
/// </summary> | ||
public TenantId? TenantId { get; } | ||
public DisplayName DisplayName { get; } | ||
|
||
/// <summary> | ||
/// Gets the display name of the API key. | ||
/// Gets the secret of the API key. | ||
/// </summary> | ||
public DisplayNameUnit DisplayName { get; } | ||
public Password Secret { get; } | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="ApiKeyCreatedEvent"/> class. | ||
/// Initializes a new instance of the <see cref="ApiKeyCreated"/> class. | ||
/// </summary> | ||
/// <param name="displayName">The display name of the API key.</param> | ||
/// <param name="secret">The secret of the API key.</param> | ||
/// <param name="tenantId">The tenant identifier of the API key.</param> | ||
public ApiKeyCreatedEvent(DisplayNameUnit displayName, Password secret, TenantId? tenantId) | ||
public ApiKeyCreated(DisplayName displayName, Password secret) | ||
{ | ||
DisplayName = displayName; | ||
Secret = secret; | ||
TenantId = tenantId; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using Logitar.EventSourcing; | ||
using MediatR; | ||
|
||
namespace Logitar.Identity.Core.ApiKeys.Events; | ||
|
||
/// <summary> | ||
/// The event raised when an API key is deleted. | ||
/// </summary> | ||
public record ApiKeyDeleted : DomainEvent, IDeleteEvent, INotification; |
10 changes: 5 additions & 5 deletions
10
...in/ApiKeys/Events/ApiKeyRoleAddedEvent.cs → ...ty.Core/ApiKeys/Events/ApiKeyRoleAdded.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 5 additions & 5 deletions
10
.../ApiKeys/Events/ApiKeyRoleRemovedEvent.cs → ....Core/ApiKeys/Events/ApiKeyRoleRemoved.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
using Logitar.EventSourcing; | ||
using MediatR; | ||
|
||
namespace Logitar.Identity.Core.ApiKeys.Events; | ||
|
||
/// <summary> | ||
/// The event raised when an API key is updated. | ||
/// </summary> | ||
public record ApiKeyUpdated : DomainEvent, INotification | ||
{ | ||
/// <summary> | ||
/// Gets or sets the new display name of the API key. | ||
/// </summary> | ||
public DisplayName? DisplayName { get; set; } | ||
/// <summary> | ||
/// Gets or sets the new description of the API key. | ||
/// </summary> | ||
public Change<Description>? Description { get; set; } | ||
/// <summary> | ||
/// Gets or sets the new expiration date and time of the API key. | ||
/// </summary> | ||
public DateTime? ExpiresOn { get; set; } | ||
|
||
/// <summary> | ||
/// Gets or sets the custom attribute modifications of the API key. | ||
/// </summary> | ||
public Dictionary<string, string?> CustomAttributes { get; init; } = []; | ||
|
||
/// <summary> | ||
/// Gets a value indicating whether or not the API key has been updated. | ||
/// </summary> | ||
[JsonIgnore] | ||
public bool HasChanges => DisplayName != null || Description != null || ExpiresOn != null || CustomAttributes.Count > 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.