Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reimplemented Infrastructure Layer & Unit Tests. #70

Merged
merged 6 commits into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading