Skip to content
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
10 changes: 5 additions & 5 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
<PackageVersion Include="IvAt.CommonFramework.RelativePath" Version="2.2.1" />
<PackageVersion Include="IvAt.CommonFramework.VisualIdentitySource" Version="2.2.1" />
<PackageVersion Include="IvAt.CommonFramework.VisualIdentitySource.Abstractions" Version="2.2.1" />
<PackageVersion Include="IvAt.GenericQueryable.Abstractions" Version="2.2.1" />
<PackageVersion Include="IvAt.GenericQueryable.EntityFramework" Version="2.2.1" />
<PackageVersion Include="IvAt.HierarchicalExpand" Version="2.2.1" />
<PackageVersion Include="IvAt.HierarchicalExpand.Abstractions" Version="2.2.1" />
<PackageVersion Include="IvAt.GenericQueryable.Abstractions" Version="2.2.2" />
<PackageVersion Include="IvAt.GenericQueryable.EntityFramework" Version="2.2.2" />
<PackageVersion Include="IvAt.HierarchicalExpand" Version="2.2.2" />
<PackageVersion Include="IvAt.HierarchicalExpand.Abstractions" Version="2.2.2" />
<PackageVersion Include="Microsoft.AspNetCore.Authentication.Negotiate" Version="10.0.3" />
<PackageVersion Include="Microsoft.AspNetCore.Http" Version="2.3.9" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.6" />
Expand All @@ -21,7 +21,7 @@
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.1.2" />
<PackageVersion Include="Swashbuckle.AspNetCore" Version="10.1.3" />
</ItemGroup>
<!-- Tests -->
<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class FakePrincipalManagementService : IPrincipalManagementService
{
public Type PrincipalType => throw new InvalidOperationException();

public Task<PrincipalData> CreatePrincipalAsync(string principalName, IEnumerable<ManagedPermission> typedPermissions, CancellationToken cancellationToken = default)
public Task<PrincipalData> CreatePrincipalAsync(string principalName, IEnumerable<ManagedPermission> managedPermissions, CancellationToken cancellationToken = default)
{
throw new InvalidOperationException();
}
Expand All @@ -23,7 +23,7 @@ public Task<PrincipalData> RemovePrincipalAsync(UserCredential userCredential, b
throw new InvalidOperationException();
}

public Task<MergeResult<PermissionData, PermissionData>> UpdatePermissionsAsync(UserCredential userCredential, IEnumerable<ManagedPermission> typedPermissions, CancellationToken cancellationToken)
public Task<MergeResult<PermissionData, PermissionData>> UpdatePermissionsAsync(UserCredential userCredential, IEnumerable<ManagedPermission> managedPermissions, CancellationToken cancellationToken)
{
throw new InvalidOperationException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ public interface IPrincipalManagementService
{
Type PrincipalType { get; }

Task<PrincipalData> CreatePrincipalAsync(string principalName, IEnumerable<ManagedPermission> typedPermissions, CancellationToken cancellationToken = default);
Task<PrincipalData> CreatePrincipalAsync(string principalName, IEnumerable<ManagedPermission> managedPermissions, CancellationToken cancellationToken = default);

Task<PrincipalData> UpdatePrincipalNameAsync(UserCredential userCredential, string principalName, CancellationToken cancellationToken);

Task<PrincipalData> RemovePrincipalAsync(UserCredential userCredential, bool force, CancellationToken cancellationToken = default);

Task<MergeResult<PermissionData, PermissionData>> UpdatePermissionsAsync(UserCredential userCredential, IEnumerable<ManagedPermission> typedPermissions,
Task<MergeResult<PermissionData, PermissionData>> UpdatePermissionsAsync(UserCredential userCredential, IEnumerable<ManagedPermission> managedPermissions,
CancellationToken cancellationToken = default);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,36 @@
namespace SecuritySystem.ExternalSystem.Management;
using System.Collections.Immutable;

public record ManagedPermission : ManagedPermissionData
namespace SecuritySystem.ExternalSystem.Management;

public record ManagedPermission
{
public required SecurityIdentity Identity { get; init; }

public required bool IsVirtual { get; init; }
public bool ForceApplyIdentity { get; init; }

public bool IsVirtual { get; init; }

public required SecurityRole SecurityRole { get; init; }

public PermissionPeriod Period { get; init; } = PermissionPeriod.Eternity;

public string Comment { get; init; } = "";

public SecurityIdentity DelegatedFrom { get; init; } = SecurityIdentity.Default;

public ImmutableDictionary<Type, Array> Restrictions { get; init; } = [];

public ImmutableDictionary<string, object> ExtendedData { get; init; } = [];


public static implicit operator ManagedPermission(SecurityRole securityRole) => new() { SecurityRole = securityRole, Identity = SecurityIdentity.Default };

public ManagedPermission WithExtendedData(string key, object value)
{
var newExtendedData = this.ExtendedData.ToDictionary();

newExtendedData[key] = value;

return this with { ExtendedData = newExtendedData.ToImmutableDictionary() };
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
namespace SecuritySystem.ExternalSystem.Management;
using System.Collections.Immutable;

public record ManagedPrincipal(ManagedPrincipalHeader Header, IReadOnlyList<ManagedPermission> Permissions);
namespace SecuritySystem.ExternalSystem.Management;

public record ManagedPrincipal(ManagedPrincipalHeader Header, ImmutableArray<ManagedPermission> Permissions);
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
namespace SecuritySystem.ExternalSystem.Management;
using System.Collections.Immutable;

namespace SecuritySystem.ExternalSystem.Management;

public abstract record PermissionData
{
public abstract Type PermissionTypeType { get; }
public abstract Type PermissionType { get; }
}

public abstract record PermissionData<TPermission>(TPermission Permission) : PermissionData
{
public override Type PermissionTypeType { get; } = typeof(TPermission);
public override Type PermissionType { get; } = typeof(TPermission);
}

public record PermissionData<TPermission, TPermissionRestriction>(TPermission Permission, IReadOnlyList<TPermissionRestriction> Restrictions)
public record PermissionData<TPermission, TPermissionRestriction>(TPermission Permission, ImmutableArray<TPermissionRestriction> Restrictions)
: PermissionData<TPermission>(Permission)
{
public PermissionData(TPermission permission, IEnumerable<TPermissionRestriction> restrictions)
: this(permission, restrictions.ToList())
: this(permission, [..restrictions])
{
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace SecuritySystem.ExternalSystem.Management;
using System.Collections.Immutable;

namespace SecuritySystem.ExternalSystem.Management;

public abstract record PrincipalData
{
Expand All @@ -11,10 +13,10 @@ public abstract record PrincipalData

public record PrincipalData<TPrincipal, TPermission, TPermissionRestriction>(
TPrincipal Principal,
IReadOnlyList<PermissionData<TPermission, TPermissionRestriction>> PermissionDataList) : PrincipalData<TPrincipal>(Principal)
ImmutableArray<PermissionData<TPermission, TPermissionRestriction>> PermissionDataList) : PrincipalData<TPrincipal>(Principal)
{
public PrincipalData(TPrincipal principal, IEnumerable<PermissionData<TPermission, TPermissionRestriction>> permissionDataList)
: this(principal, permissionDataList.ToList())
: this(principal, [..permissionDataList])
{
}

Expand Down
11 changes: 11 additions & 0 deletions src/SecuritySystem.Abstractions/PermissionPeriod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,16 @@ public bool IsIntersected(PermissionPeriod otherPeriod)
return start1 <= end2 && start2 <= end1;
}

public bool Contains(PermissionPeriod otherPeriod)
{
var start1 = this.StartDate ?? DateTime.MinValue;
var end1 = this.EndDate ?? DateTime.MaxValue;

var start2 = otherPeriod.StartDate ?? DateTime.MinValue;
var end2 = otherPeriod.EndDate ?? DateTime.MaxValue;

return start1 <= start2 && end2 <= end1;
}

public static PermissionPeriod Eternity { get; } = new (null, null);
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
namespace SecuritySystem.SecurityAccessor;
using System.Collections.Immutable;

namespace SecuritySystem.SecurityAccessor;

public abstract record SecurityAccessorData
{
public static SecurityAccessorData Infinity { get; } = new InfinitySecurityAccessorData();

public static SecurityAccessorData Empty { get; } = Return();

public static SecurityAccessorData Return(params string[] items) => new FixedSecurityAccessorData(items);
public static SecurityAccessorData Return(params string[] items) => new FixedSecurityAccessorData([..items]);

public static SecurityAccessorData Return(IEnumerable<string> items) => Return(items.ToArray());

public static SecurityAccessorData TryReturn(string? item) => string.IsNullOrWhiteSpace(item) ? Empty : Return(item);

public record FixedSecurityAccessorData(IReadOnlyList<string> Items) : SecurityAccessorData;
public record FixedSecurityAccessorData(ImmutableArray<string> Items) : SecurityAccessorData;

public record InfinitySecurityAccessorData : SecurityAccessorData;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// ReSharper disable once CheckNamespace
using System.Collections.Immutable;

// ReSharper disable once CheckNamespace
namespace SecuritySystem;

public interface ISecurityContextInfoSource
{
IReadOnlyList<SecurityContextInfo> SecurityContextInfoList { get; }
ImmutableArray<SecurityContextInfo> SecurityContextInfoList { get; }

SecurityContextInfo GetSecurityContextInfo(Type type);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// ReSharper disable once CheckNamespace
using System.Collections.Immutable;

// ReSharper disable once CheckNamespace
namespace SecuritySystem;

public interface ISecurityRoleSource
{
IReadOnlyList<FullSecurityRole> SecurityRoles { get; }
ImmutableArray<FullSecurityRole> SecurityRoles { get; }

FullSecurityRole GetSecurityRole(SecurityRole securityRole);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using HierarchicalExpand;
using System.Collections.Immutable;
using HierarchicalExpand;

// ReSharper disable once CheckNamespace
namespace SecuritySystem;
Expand All @@ -9,9 +10,9 @@ public record SecurityRoleInfo(TypedSecurityIdentity Identity)

public SecurityPathRestriction Restriction { get; init; } = SecurityPathRestriction.Default;

public IReadOnlyList<SecurityOperation> Operations { get; init; } = [];
public ImmutableArray<SecurityOperation> Operations { get; init; } = [];

public IReadOnlyList<SecurityRole> Children { get; init; } = [];
public ImmutableArray<SecurityRole> Children { get; init; } = [];

public string? Description { get; init; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ public TSecurityRule TryApply(HierarchicalExpandType? customExpandType) =>
customExpandType == null || securityRule.CustomExpandType != null
? securityRule
: securityRule with { CustomExpandType = customExpandType };

public TSecurityRule WithDefaultCustoms() =>
securityRule.CustomCredential == null && securityRule.CustomExpandType == null && securityRule.CustomRestriction == null
? securityRule
: securityRule with { CustomCredential = null, CustomExpandType = null, CustomRestriction = null };
}


Expand All @@ -178,7 +183,7 @@ public TSecurityRule ForceApply(SecurityRuleCredential? customCredential) =>
: securityRule with { CustomCredential = customCredential };

public TSecurityRule WithDefaultCredential() =>
securityRule with { CustomCredential = null };
securityRule.CustomCredential == null ? securityRule : securityRule with { CustomCredential = null };

public TResult WithDefaultCredential<TResult>(Func<TSecurityRule, TResult> selector)
where TResult : SecurityRule =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
namespace SecuritySystem.Services;
using System.Collections.Immutable;

namespace SecuritySystem.Services;

public interface ISecurityRolesIdentsResolver
{
IReadOnlyDictionary<Type, Array> Resolve(DomainSecurityRule.RoleBaseSecurityRule securityRule, bool includeVirtual = false);
ImmutableDictionary<Type, Array> Resolve(DomainSecurityRule.RoleBaseSecurityRule securityRule, bool includeVirtual = false);
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ private async Task<List<PermissionDto>> GetPermissionsAsync(UserCredential userC
Role = permission.SecurityRole.Name,
RoleId = securityRoleSource.GetSecurityRole(permission.SecurityRole).Identity.GetId().ToString()!,
Comment = permission.Comment,
StartDate = permission.Period.StartDate,
DelegatedFromId = permission.DelegatedFrom.GetId().ToString()!,
StartDate = permission.Period.StartDate,
EndDate = permission.Period.EndDate,
Contexts = permission
.Restrictions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ public async Task Execute(HttpContext context, CancellationToken cancellationTok

var permissions = await this.ParseRequestBodyAsync<List<RequestBodyDto>>(context);

var typedPermissions = permissions.Select(this.ToManagedPermission).ToList();
var managedPermissions = permissions.Select(this.ToManagedPermission).ToList();

var mergeResult = await principalManagementService.UpdatePermissionsAsync(context.ExtractSecurityIdentity(), typedPermissions, cancellationToken);
var mergeResult = await principalManagementService.UpdatePermissionsAsync(context.ExtractSecurityIdentity(), managedPermissions, cancellationToken);

if (configuratorIntegrationEvents != null)
{
Expand Down Expand Up @@ -66,6 +66,7 @@ from restriction in permission.Contexts
SecurityRole = securityRoleSource.GetSecurityRole(new UntypedSecurityIdentity(permission.RoleId)),
Period = new PermissionPeriod(permission.StartDate, permission.EndDate),
Comment = permission.Comment,
DelegatedFrom = new UntypedSecurityIdentity(permission.DelegatedFromId),
Restrictions = restrictionsRequest.ToImmutableDictionary()
};
}
Expand All @@ -86,6 +87,8 @@ private class RequestBodyDto

public List<ContextDto> Contexts { get; set; } = default!;

public string DelegatedFromId { get; set; } = default!;

public class ContextDto
{
public string Id { get; set; } = default!;
Expand Down
2 changes: 2 additions & 0 deletions src/SecuritySystem.Configurator/Models/PermissionDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public record PermissionDto

public required string Comment { get; init; }

public required string DelegatedFromId { get; init; }

public required IReadOnlyList<ContextDto> Contexts { get; init; }

public required DateTime? StartDate { get; init; }
Expand Down
Loading
Loading