Skip to content

Commit

Permalink
TenantMismatchException
Browse files Browse the repository at this point in the history
  • Loading branch information
Utar94 committed Dec 15, 2024
1 parent 86b8d73 commit 6e278bc
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 28 deletions.
18 changes: 13 additions & 5 deletions lib/Logitar.Identity.Core/ApiKeys/ApiKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ public class ApiKey : AggregateRoot
/// Gets the identifier of the API key.
/// </summary>
public new ApiKeyId Id => new(base.Id);
/// <summary>
/// Gets the tenant identifier of the API key.
/// </summary>
public TenantId? TenantId => Id.TenantId;
/// <summary>
/// Gets the entity identifier of the API key. This identifier is unique within the tenant.
/// </summary>
public EntityId? EntityId => Id.EntityId;

/// <summary>
/// The display name of the API key.
Expand Down Expand Up @@ -108,13 +116,13 @@ public DateTime? ExpiresOn
/// </summary>
/// <param name="role">The role to be added.</param>
/// <param name="actorId">The actor identifier.</param>
/// <exception cref="TenantMismatchException">The role and API key tenant identifiers do not match.</exception>
public void AddRole(Role role, ActorId actorId = default)
{
//<exception cref="TenantMismatchException">The role and API key tenant identifiers do not match.</exception>
//if (role.TenantId != TenantId)
//{
// throw new TenantMismatchException(TenantId, role.TenantId);
//} // TODO(fpion): implement
if (role.TenantId != TenantId)
{
throw new TenantMismatchException(TenantId, role.TenantId);
}

if (!HasRole(role))
{
Expand Down
33 changes: 20 additions & 13 deletions lib/Logitar.Identity.Core/ApiKeys/ApiKeyId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,33 @@ public readonly struct ApiKeyId
/// </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="value">A Guid value.</param>
public ApiKeyId(Guid value)
/// <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())
{
StreamId = new StreamId(value);
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiKeyId"/> struct.
/// </summary>
/// <param name="value">A string value.</param>
public ApiKeyId(string value)
/// <param name="tenantId">The tenant identifier.</param>
/// <param name="entityId">The entity identifier.</param>
public ApiKeyId(TenantId? tenantId, string entityId)
{
StreamId = new StreamId(value);
TenantId = tenantId;
EntityId = new(entityId);
StreamId = new(tenantId.HasValue ? $"{tenantId}:{entityId}" : entityId);
}
/// <summary>
/// Initializes a new instance of the <see cref="ApiKeyId"/> struct.
Expand All @@ -44,14 +56,9 @@ public ApiKeyId(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() => new(StreamId.NewId());

/// <summary>
/// Converts the identifier to a <see cref="Guid"/>. The conversion will fail if the identifier has not been created from a <see cref="Guid"/>.
/// </summary>
/// <returns>The resulting Guid.</returns>
public Guid ToGuid() => StreamId.ToGuid();
public static ApiKeyId NewId(TenantId? tenantId = null) => new(tenantId, Guid.NewGuid());

/// <summary>
/// Returns a value indicating whether or not the specified identifiers are equal.
Expand Down
10 changes: 5 additions & 5 deletions lib/Logitar.Identity.Core/ApiKeys/ApiKeyIsExpiredException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ public class ApiKeyIsExpiredException : InvalidCredentialsException
/// <summary>
/// Gets the identifier of the expired API key.
/// </summary>
public ApiKeyId ApiKeyId // TODO(fpion): do we really want this?
public string ApiKeyId
{
get => new((string)Data[nameof(ApiKeyId)]!);
private set => Data[nameof(ApiKeyId)] = value.Value;
get => (string)Data[nameof(ApiKeyId)]!;
private set => Data[nameof(ApiKeyId)] = value;
}

/// <summary>
Expand All @@ -25,7 +25,7 @@ public class ApiKeyIsExpiredException : InvalidCredentialsException
/// <param name="apiKey">The API key that is expired.</param>
public ApiKeyIsExpiredException(ApiKey apiKey) : base(BuildMessage(apiKey))
{
ApiKeyId = apiKey.Id;
ApiKeyId = apiKey.Id.Value;
}

/// <summary>
Expand All @@ -34,6 +34,6 @@ public ApiKeyIsExpiredException(ApiKey apiKey) : base(BuildMessage(apiKey))
/// <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.Value)
.AddData(nameof(ApiKeyId), apiKey.Id)
.Build();
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ public class IncorrectApiKeySecretException : InvalidCredentialsException
/// <summary>
/// Gets or sets the identifier of the API key.
/// </summary>
public ApiKeyId ApiKeyId // TODO(fpion): do we really want this?
public string ApiKeyId
{
get => new((string)Data[nameof(ApiKeyId)]!);
private set => Data[nameof(ApiKeyId)] = value.Value;
get => (string)Data[nameof(ApiKeyId)]!;
private set => Data[nameof(ApiKeyId)] = value;
}
/// <summary>
/// Gets or sets the attempted secret.
Expand All @@ -35,7 +35,7 @@ public string AttemptedSecret
public IncorrectApiKeySecretException(ApiKey apiKey, string attemptedSecret)
: base(BuildMessage(apiKey, attemptedSecret))
{
ApiKeyId = apiKey.Id;
ApiKeyId = apiKey.Id.Value;
AttemptedSecret = attemptedSecret;
}

Expand All @@ -46,7 +46,7 @@ public IncorrectApiKeySecretException(ApiKey apiKey, string attemptedSecret)
/// <param name="attemptedSecret">The attempted secret.</param>
/// <returns>The exception message.</returns>
private static string BuildMessage(ApiKey apiKey, string attemptedSecret) => new ErrorMessageBuilder(ErrorMessage)
.AddData(nameof(ApiKeyId), apiKey.Id.Value)
.AddData(nameof(ApiKeyId), apiKey.Id)
.AddData(nameof(AttemptedSecret), attemptedSecret)
.Build();
}
52 changes: 52 additions & 0 deletions lib/Logitar.Identity.Core/TenantMismatchException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace Logitar.Identity.Core;

/// <summary>
/// The exception raised when an association is made between two entities in different tenants.
/// </summary>
public class TenantMismatchException : Exception
{
/// <summary>
/// A generic error message for this exception.
/// </summary>
private const string ErrorMessage = "The specified tenant identifier was not expected.";

/// <summary>
/// Gets or sets the expected tenant identifier.
/// </summary>
public string? ExpectedTenantId
{
get => (string?)Data[nameof(ExpectedTenantId)];
private set => Data[nameof(ExpectedTenantId)] = value;
}
/// <summary>
/// Gets or sets the actual tenant identifier.
/// </summary>
public string? ActualTenantId
{
get => (string?)Data[nameof(ActualTenantId)];
private set => Data[nameof(ActualTenantId)] = value;
}

/// <summary>
/// Initializes a new instance of the <see cref="TenantMismatchException"/> class.
/// </summary>
/// <param name="expected">The expected tenant identifier.</param>
/// <param name="actual">The actual tenant identifier.</param>
public TenantMismatchException(TenantId? expected, TenantId? actual)
: base(BuildMessage(expected, actual))
{
ExpectedTenantId = expected?.Value;
ActualTenantId = actual?.Value;
}

/// <summary>
/// Builds the exception message.
/// </summary>
/// <param name="expected">The expected tenant identifier.</param>
/// <param name="actual">The actual tenant identifier.</param>
/// <returns>The exception message.</returns>
private static string BuildMessage(TenantId? expected, TenantId? actual) => new ErrorMessageBuilder(ErrorMessage)
.AddData(nameof(ExpectedTenantId), expected, "<null>")
.AddData(nameof(ActualTenantId), actual, "<null>")
.Build();
}

0 comments on commit 6e278bc

Please sign in to comment.