Skip to content

Commit

Permalink
Reimplemented Infrastructure Layer & Unit Tests. (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
Utar94 authored Dec 22, 2024
1 parent 2f6c3a2 commit 598e9a0
Show file tree
Hide file tree
Showing 160 changed files with 2,427 additions and 4,038 deletions.
31 changes: 31 additions & 0 deletions Identity.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logitar.Identity.Core", "li
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logitar.Identity.Contracts", "lib\Logitar.Identity.Contracts\Logitar.Identity.Contracts.csproj", "{2B1BB7B6-DE55-41FB-863E-D6D230A833FB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{3544F58B-1C4B-46B4-9931-8F9737D46717}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logitar.Identity.Core.UnitTests", "tests\Logitar.Identity.Core.UnitTests\Logitar.Identity.Core.UnitTests.csproj", "{0427E96B-E9A4-4771-B0FC-1043372FC68E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logitar.Identity.Tests", "tests\Logitar.Identity.Tests\Logitar.Identity.Tests.csproj", "{E54EBE14-3B81-48B8-8504-B833236F0136}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logitar.Identity.Infrastructure", "lib\Logitar.Identity.Infrastructure\Logitar.Identity.Infrastructure.csproj", "{AC5F10DD-1467-4674-B71B-26FDA41A0242}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Logitar.Identity.Infrastructure.UnitTests", "tests\Logitar.Identity.Infrastructure.UnitTests\Logitar.Identity.Infrastructure.UnitTests.csproj", "{2B60FA82-D67E-4AB6-9FE5-6682F7AD875C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -32,10 +42,31 @@ Global
{2B1BB7B6-DE55-41FB-863E-D6D230A833FB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B1BB7B6-DE55-41FB-863E-D6D230A833FB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B1BB7B6-DE55-41FB-863E-D6D230A833FB}.Release|Any CPU.Build.0 = Release|Any CPU
{0427E96B-E9A4-4771-B0FC-1043372FC68E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0427E96B-E9A4-4771-B0FC-1043372FC68E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0427E96B-E9A4-4771-B0FC-1043372FC68E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0427E96B-E9A4-4771-B0FC-1043372FC68E}.Release|Any CPU.Build.0 = Release|Any CPU
{E54EBE14-3B81-48B8-8504-B833236F0136}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E54EBE14-3B81-48B8-8504-B833236F0136}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E54EBE14-3B81-48B8-8504-B833236F0136}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E54EBE14-3B81-48B8-8504-B833236F0136}.Release|Any CPU.Build.0 = Release|Any CPU
{AC5F10DD-1467-4674-B71B-26FDA41A0242}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AC5F10DD-1467-4674-B71B-26FDA41A0242}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AC5F10DD-1467-4674-B71B-26FDA41A0242}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AC5F10DD-1467-4674-B71B-26FDA41A0242}.Release|Any CPU.Build.0 = Release|Any CPU
{2B60FA82-D67E-4AB6-9FE5-6682F7AD875C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B60FA82-D67E-4AB6-9FE5-6682F7AD875C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B60FA82-D67E-4AB6-9FE5-6682F7AD875C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B60FA82-D67E-4AB6-9FE5-6682F7AD875C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{0427E96B-E9A4-4771-B0FC-1043372FC68E} = {3544F58B-1C4B-46B4-9931-8F9737D46717}
{E54EBE14-3B81-48B8-8504-B833236F0136} = {3544F58B-1C4B-46B4-9931-8F9737D46717}
{2B60FA82-D67E-4AB6-9FE5-6682F7AD875C} = {3544F58B-1C4B-46B4-9931-8F9737D46717}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {45FD7647-C5AB-4CE1-A93C-59A73FDD2196}
EndGlobalSection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TargetFramework>netstandard2.1</TargetFramework>
<LangVersion>10</LangVersion>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>Logitar.Identity.Contracts</Title>
<Authors>Francis Pion</Authors>
<Company>Logitar</Company>
Expand Down
19 changes: 14 additions & 5 deletions lib/Logitar.Identity.Core/ApiKeys/ApiKey.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,12 +282,15 @@ public void SetCustomAttribute(Identifier key, string value)
{
RemoveCustomAttribute(key);
}
value = value.Trim();

if (!_customAttributes.TryGetValue(key, out string? existingValue) || existingValue != value)
else
{
_customAttributes[key] = value;
_updated.CustomAttributes[key] = value;
value = value.Trim();

if (!_customAttributes.TryGetValue(key, out string? existingValue) || existingValue != value)
{
_customAttributes[key] = value;
_updated.CustomAttributes[key] = value;
}
}
}

Expand Down Expand Up @@ -334,4 +337,10 @@ protected virtual void Handle(ApiKeyUpdated @event)
}
}
}

/// <summary>
/// Returns a string representation of the API key.
/// </summary>
/// <returns>The string representation.</returns>
public override string ToString() => $"{DisplayName} | {base.ToString()}";
}
35 changes: 22 additions & 13 deletions lib/Logitar.Identity.Core/ApiKeys/ApiKeyId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ namespace Logitar.Identity.Core.ApiKeys;
/// </summary>
public readonly struct ApiKeyId
{
/// <summary>
/// The separator between the tenant ID and the entity ID.
/// </summary>
private const char Separator = ':';

/// <summary>
/// Gets the identifier of the event stream.
/// </summary>
Expand All @@ -30,35 +35,39 @@ public readonly struct ApiKeyId
/// </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)
public ApiKeyId(TenantId? tenantId, EntityId entityId)
{
StreamId = new(tenantId == null ? entityId.Value : string.Join(Separator, tenantId, entityId));
TenantId = tenantId;
EntityId = new(entityId);
StreamId = new(tenantId.HasValue ? $"{tenantId}:{entityId}" : entityId);
EntityId = entityId;
}

/// <summary>
/// Initializes a new instance of the <see cref="ApiKeyId"/> struct.
/// </summary>
/// <param name="streamId">A stream identifier.</param>
/// <param name="streamId">The identifier of the event stream.</param>
public ApiKeyId(StreamId streamId)
{
StreamId = streamId;

string[] values = streamId.Value.Split(Separator);
if (values.Length > 2)
{
throw new ArgumentException($"The value '{streamId}' is not a valid API key ID.", nameof(streamId));
}
else if (values.Length == 2)
{
TenantId = new(values.First());
}
EntityId = new(values.Last());
}

/// <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());
public static ApiKeyId NewId(TenantId? tenantId = null) => new(tenantId, EntityId.NewId());

/// <summary>
/// Returns a value indicating whether or not the specified identifiers are equal.
Expand Down
4 changes: 3 additions & 1 deletion lib/Logitar.Identity.Core/DependencyInjectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Logitar.Identity.Core.Roles;
using Logitar.EventSourcing;
using Logitar.Identity.Core.Roles;
using Logitar.Identity.Core.Settings;
using Logitar.Identity.Core.Users;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -18,6 +19,7 @@ public static class DependencyInjectionExtensions
public static IServiceCollection AddLogitarIdentityCore(this IServiceCollection services)
{
return services
.AddLogitarEventSourcing()
.AddSingleton<IAddressHelper, AddressHelper>()
.AddSingleton<IRoleSettingsResolver, RoleSettingsResolver>()
.AddSingleton<IUserSettingsResolver, UserSettingsResolver>()
Expand Down
2 changes: 1 addition & 1 deletion lib/Logitar.Identity.Core/Logitar.Identity.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>Logitar.Identity.Core</Title>
<Authors>Francis Pion</Authors>
<Company>Logitar</Company>
Expand Down
3 changes: 1 addition & 2 deletions lib/Logitar.Identity.Core/Passwords/OneTimePassword.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using Logitar.EventSourcing;
using Logitar.Identity.Core.ApiKeys;
using Logitar.Identity.Core.Passwords.Events;

namespace Logitar.Identity.Core.Passwords;
Expand All @@ -23,7 +22,7 @@ public class OneTimePassword : AggregateRoot
/// <summary>
/// Gets the identifier of the One-Time Password (OTP).
/// </summary>
public new ApiKeyId Id => new(base.Id);
public new OneTimePasswordId Id => new(base.Id);
/// <summary>
/// Gets the tenant identifier of the One-Time Password (OTP).
/// </summary>
Expand Down
37 changes: 23 additions & 14 deletions lib/Logitar.Identity.Core/Passwords/OneTimePasswordId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ namespace Logitar.Identity.Core.Passwords;
/// </summary>
public readonly struct OneTimePasswordId
{
/// <summary>
/// The separator between the tenant ID and the entity ID.
/// </summary>
private const char Separator = ':';

/// <summary>
/// Gets the identifier of the event stream.
/// </summary>
Expand All @@ -30,35 +35,39 @@ public readonly struct OneTimePasswordId
/// </summary>
/// <param name="tenantId">The tenant identifier.</param>
/// <param name="entityId">The entity identifier.</param>
public OneTimePasswordId(TenantId? tenantId, Guid entityId) : this(tenantId, Convert.ToBase64String(entityId.ToByteArray()).ToUriSafeBase64())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="OneTimePasswordId"/> struct.
/// </summary>
/// <param name="tenantId">The tenant identifier.</param>
/// <param name="entityId">The entity identifier.</param>
public OneTimePasswordId(TenantId? tenantId, string entityId)
public OneTimePasswordId(TenantId? tenantId, EntityId entityId)
{
StreamId = new(tenantId == null ? entityId.Value : string.Join(Separator, tenantId, entityId));
TenantId = tenantId;
EntityId = new(entityId);
StreamId = new(tenantId.HasValue ? $"{tenantId}:{entityId}" : entityId);
EntityId = entityId;
}

/// <summary>
/// Initializes a new instance of the <see cref="OneTimePasswordId"/> struct.
/// </summary>
/// <param name="streamId">A stream identifier.</param>
/// <param name="streamId">The identifier of the event stream.</param>
public OneTimePasswordId(StreamId streamId)
{
StreamId = streamId;

string[] values = streamId.Value.Split(Separator);
if (values.Length > 2)
{
throw new ArgumentException($"The value '{streamId}' is not a valid session ID.", nameof(streamId));
}
else if (values.Length == 2)
{
TenantId = new(values.First());
}
EntityId = new(values.Last());
}

/// <summary>
/// Randomly generates a new One-Time Password (OTP) identifier.
/// Randomly generates a new session identifier.
/// </summary>
/// <param name="tenantId">The tenant identifier.</param>
/// <returns>The generated identifier.</returns>
public static OneTimePasswordId NewId(TenantId? tenantId = null) => new(tenantId, Guid.NewGuid());
public static OneTimePasswordId NewId(TenantId? tenantId = null) => new(tenantId, EntityId.NewId());

/// <summary>
/// Returns a value indicating whether or not the specified identifiers are equal.
Expand Down
15 changes: 9 additions & 6 deletions lib/Logitar.Identity.Core/Roles/Role.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,15 @@ public void SetCustomAttribute(Identifier key, string value)
{
RemoveCustomAttribute(key);
}
value = value.Trim();

if (!_customAttributes.TryGetValue(key, out string? existingValue) || existingValue != value)
else
{
_customAttributes[key] = value;
_updated.CustomAttributes[key] = value;
value = value.Trim();

if (!_customAttributes.TryGetValue(key, out string? existingValue) || existingValue != value)
{
_customAttributes[key] = value;
_updated.CustomAttributes[key] = value;
}
}
}

Expand All @@ -161,7 +164,7 @@ public void SetCustomAttribute(Identifier key, string value)
/// </summary>
/// <param name="uniqueName">The unique name.</param>
/// <param name="actorId">The actor identifier.</param>
public void SetUniqueName(UniqueName uniqueName, ActorId? actorId)
public void SetUniqueName(UniqueName uniqueName, ActorId? actorId = null)
{
if (_uniqueName != uniqueName)
{
Expand Down
35 changes: 22 additions & 13 deletions lib/Logitar.Identity.Core/Roles/RoleId.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ namespace Logitar.Identity.Core.Roles;
/// </summary>
public readonly struct RoleId
{
/// <summary>
/// The separator between the tenant ID and the entity ID.
/// </summary>
private const char Separator = ':';

/// <summary>
/// Gets the identifier of the event stream.
/// </summary>
Expand All @@ -30,35 +35,39 @@ public readonly struct RoleId
/// </summary>
/// <param name="tenantId">The tenant identifier.</param>
/// <param name="entityId">The entity identifier.</param>
public RoleId(TenantId? tenantId, Guid entityId) : this(tenantId, Convert.ToBase64String(entityId.ToByteArray()).ToUriSafeBase64())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RoleId"/> struct.
/// </summary>
/// <param name="tenantId">The tenant identifier.</param>
/// <param name="entityId">The entity identifier.</param>
public RoleId(TenantId? tenantId, string entityId)
public RoleId(TenantId? tenantId, EntityId entityId)
{
StreamId = new(tenantId == null ? entityId.Value : string.Join(Separator, tenantId, entityId));
TenantId = tenantId;
EntityId = new(entityId);
StreamId = new(tenantId.HasValue ? $"{tenantId}:{entityId}" : entityId);
EntityId = entityId;
}

/// <summary>
/// Initializes a new instance of the <see cref="RoleId"/> struct.
/// </summary>
/// <param name="streamId">A stream identifier.</param>
/// <param name="streamId">The identifier of the event stream.</param>
public RoleId(StreamId streamId)
{
StreamId = streamId;

string[] values = streamId.Value.Split(Separator);
if (values.Length > 2)
{
throw new ArgumentException($"The value '{streamId}' is not a valid role ID.", nameof(streamId));
}
else if (values.Length == 2)
{
TenantId = new(values.First());
}
EntityId = new(values.Last());
}

/// <summary>
/// Randomly generates a new role identifier.
/// </summary>
/// <param name="tenantId">The tenant identifier.</param>
/// <returns>The generated identifier.</returns>
public static RoleId NewId(TenantId? tenantId = null) => new(tenantId, Guid.NewGuid());
public static RoleId NewId(TenantId? tenantId = null) => new(tenantId, EntityId.NewId());

/// <summary>
/// Returns a value indicating whether or not the specified identifiers are equal.
Expand Down
Loading

0 comments on commit 598e9a0

Please sign in to comment.