From 1e7035bf7012e36346506d11b550deac63512688 Mon Sep 17 00:00:00 2001 From: Richard Beauchamp Date: Thu, 22 Aug 2024 11:18:28 -0700 Subject: [PATCH] test: remove unused classes until tested (#48) --- .../Extensions/GraphQLBuilderExtensions.cs | 9 +- .../Extensions/ReplicationOptions.cs | 9 - src/RxDBDotNet/Security/AccessPolicy.cs | 30 --- src/RxDBDotNet/Security/AccessRequirement.cs | 15 -- .../Security/AccessRequirementHandler.cs | 37 ---- src/RxDBDotNet/Security/AccessType.cs | 41 ---- .../Security/ClaimsPrincipalExtensions.cs | 41 ---- src/RxDBDotNet/Security/SecurityOptions.cs | 187 ------------------ .../TestSecurityOptions.cs | 26 --- 9 files changed, 1 insertion(+), 394 deletions(-) delete mode 100644 src/RxDBDotNet/Extensions/ReplicationOptions.cs delete mode 100644 src/RxDBDotNet/Security/AccessPolicy.cs delete mode 100644 src/RxDBDotNet/Security/AccessRequirement.cs delete mode 100644 src/RxDBDotNet/Security/AccessRequirementHandler.cs delete mode 100644 src/RxDBDotNet/Security/AccessType.cs delete mode 100644 src/RxDBDotNet/Security/ClaimsPrincipalExtensions.cs delete mode 100644 src/RxDBDotNet/Security/SecurityOptions.cs delete mode 100644 tests/RxDBDotNet.Tests.Setup/TestSecurityOptions.cs diff --git a/src/RxDBDotNet/Extensions/GraphQLBuilderExtensions.cs b/src/RxDBDotNet/Extensions/GraphQLBuilderExtensions.cs index 40f0d31..51f7b49 100644 --- a/src/RxDBDotNet/Extensions/GraphQLBuilderExtensions.cs +++ b/src/RxDBDotNet/Extensions/GraphQLBuilderExtensions.cs @@ -48,9 +48,6 @@ public static IRequestExecutorBuilder AddReplicationServer(this IRequestExecutor /// /// The type of document to support, which must implement IReplicatedDocument. /// The HotChocolate IRequestExecutorBuilder to configure. - /// - /// An optional configuration action to customize the replication options for the document type. - /// /// The configured IRequestExecutorBuilder for method chaining. /// /// @@ -69,13 +66,9 @@ public static IRequestExecutorBuilder AddReplicationServer(this IRequestExecutor /// /// public static IRequestExecutorBuilder AddReplicatedDocument( - this IRequestExecutorBuilder builder, - Action>? configure = null) + this IRequestExecutorBuilder builder) where TDocument : class, IReplicatedDocument { - var options = new ReplicationOptions(); - configure?.Invoke(options); - return builder .AddResolver>() .AddResolver>() diff --git a/src/RxDBDotNet/Extensions/ReplicationOptions.cs b/src/RxDBDotNet/Extensions/ReplicationOptions.cs deleted file mode 100644 index 5d12f74..0000000 --- a/src/RxDBDotNet/Extensions/ReplicationOptions.cs +++ /dev/null @@ -1,9 +0,0 @@ -using RxDBDotNet.Documents; -using RxDBDotNet.Security; - -namespace RxDBDotNet.Extensions; - -public sealed class ReplicationOptions where TDocument : class, IReplicatedDocument -{ - public SecurityOptions Security { get; } = new SecurityOptions(); -} diff --git a/src/RxDBDotNet/Security/AccessPolicy.cs b/src/RxDBDotNet/Security/AccessPolicy.cs deleted file mode 100644 index 41e05ff..0000000 --- a/src/RxDBDotNet/Security/AccessPolicy.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Security.Claims; - -namespace RxDBDotNet.Security; - -/// -/// Represents a security policy for a specific type of access to a document. -/// -public sealed class AccessPolicy -{ - /// - /// Gets the type of access this policy applies to. - /// - public AccessType Type { get; } - - /// - /// Gets the requirement function that determines if access should be granted. - /// - public Func Requirement { get; } - - /// - /// Initializes a new instance of the AccessPolicy class. - /// - /// The type of access this policy applies to. - /// A function that takes a ClaimsPrincipal and returns a boolean indicating if the requirement is met. - public AccessPolicy(AccessType type, Func requirement) - { - Type = type; - Requirement = requirement; - } -} diff --git a/src/RxDBDotNet/Security/AccessRequirement.cs b/src/RxDBDotNet/Security/AccessRequirement.cs deleted file mode 100644 index d8fe8f3..0000000 --- a/src/RxDBDotNet/Security/AccessRequirement.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Microsoft.AspNetCore.Authorization; - -namespace RxDBDotNet.Security; - -public sealed class AccessRequirement : IAuthorizationRequirement -{ - public AccessType Type { get; } - public SecurityOptions SecurityOptions { get; } - - public AccessRequirement(AccessType type, SecurityOptions securityOptions) - { - Type = type; - SecurityOptions = securityOptions; - } -} diff --git a/src/RxDBDotNet/Security/AccessRequirementHandler.cs b/src/RxDBDotNet/Security/AccessRequirementHandler.cs deleted file mode 100644 index 81bc420..0000000 --- a/src/RxDBDotNet/Security/AccessRequirementHandler.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.AspNetCore.Authorization; - -namespace RxDBDotNet.Security; - -/// -/// Handles the evaluation of access requirements for RxDBDotNet documents. -/// -public sealed class AccessRequirementHandler : AuthorizationHandler -{ - /// - /// Handles the evaluation of an access requirement. - /// - /// The authorization context. - /// The access requirement to evaluate. - /// A task that represents the asynchronous authorization operation. - protected override Task HandleRequirementAsync( - AuthorizationHandlerContext context, - AccessRequirement requirement) - { - ArgumentNullException.ThrowIfNull(context); - ArgumentNullException.ThrowIfNull(requirement); - - var user = context.User; - - var policies = requirement.SecurityOptions.Policies - .Where(p => p.Type.HasFlag(requirement.Type)); - - if (policies.Any(policy => !policy.Requirement(user))) - { - return Task.CompletedTask; - } - - context.Succeed(requirement); - - return Task.CompletedTask; - } -} diff --git a/src/RxDBDotNet/Security/AccessType.cs b/src/RxDBDotNet/Security/AccessType.cs deleted file mode 100644 index ec2bacb..0000000 --- a/src/RxDBDotNet/Security/AccessType.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace RxDBDotNet.Security; - -/// -/// Defines the types of access that can be controlled in the RxDBDotNet security system. -/// -[Flags] -public enum AccessType -{ - /// - /// Represents no access rights. - /// - None = 0, - - /// - /// Represents read access to replicated documents. - /// This includes operations like queries and subscriptions. - /// - Read = 1 << 0, - - /// - /// Represents write access to replicated documents. - /// This includes operations like creating new replicated documents and updating existing ones. - /// - Write = 1 << 1, - - /// - /// Represents delete access to replicated documents. - /// This allows for the deletion of replicated documents. - /// - Delete = 1 << 2, - - /// - /// Represents both read and write access to replicated documents. - /// - ReadWrite = Read | Write, - - /// - /// Represents full access to replicated documents, including read, write, and delete operations. - /// - All = Read | Write | Delete, -} diff --git a/src/RxDBDotNet/Security/ClaimsPrincipalExtensions.cs b/src/RxDBDotNet/Security/ClaimsPrincipalExtensions.cs deleted file mode 100644 index a744c3d..0000000 --- a/src/RxDBDotNet/Security/ClaimsPrincipalExtensions.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Globalization; -using System.Security.Claims; - -namespace RxDBDotNet.Security; - -/// -/// Provides extension methods for ClaimsPrincipal to work with role-based security in RxDBDotNet. -/// -public static class ClaimsPrincipalExtensions -{ - /// - /// Checks if the principal has a role that is equal to or higher than the specified minimum role. - /// - /// The enum type representing user roles. Must be defined with roles in ascending order of authority. - /// The ClaimsPrincipal to check. - /// The minimum role to check against. - /// True if the principal has a role equal to or higher than the minimum role, false otherwise. - /// - /// This method assumes that the TRole enum is defined with roles in ascending order of authority, - /// where higher enum values correspond to higher levels of access. - /// - public static bool IsInRoleOrHigher(this ClaimsPrincipal principal, TRole minimumRole) - where TRole : struct, Enum - { - ArgumentNullException.ThrowIfNull(principal); - - var userRoleClaim = principal.FindFirst(ClaimTypes.Role); - if (userRoleClaim == null) - { - return false; - } - - if (Enum.TryParse(userRoleClaim.Value, out var userRole)) - { - return Convert.ToInt32(userRole, CultureInfo.InvariantCulture) >= - Convert.ToInt32(minimumRole, CultureInfo.InvariantCulture); - } - - return false; - } -} diff --git a/src/RxDBDotNet/Security/SecurityOptions.cs b/src/RxDBDotNet/Security/SecurityOptions.cs deleted file mode 100644 index 88d788e..0000000 --- a/src/RxDBDotNet/Security/SecurityOptions.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System.Security.Claims; - -namespace RxDBDotNet.Security; - -/// -/// Provides configuration options for setting up security policies in RxDBDotNet. -/// This class allows for fine-grained control over access to replicated documents. -/// -/// -/// When using the 'RequireMinimum...' methods, the TRole enum must be defined with the roles -/// in ascending order of authority. The enum values should correspond to the level of access, -/// with higher values indicating more authority. -/// -/// Example of a correctly defined role enum: -/// -/// public enum UserRole -/// { -/// StandardUser = 0, -/// WorkspaceAdmin = 1, -/// SystemAdmin = 2 -/// } -/// -/// -/// With this enum, RequireMinimumRoleToRead(UserRole.StandardUser) would allow -/// StandardUser, WorkspaceAdmin, and SystemAdmin to read, while -/// RequireMinimumRoleToWrite(UserRole.WorkspaceAdmin) would only allow -/// WorkspaceAdmin and SystemAdmin to write. -/// -public sealed class SecurityOptions -{ - internal List Policies { get; } = []; - - /// - /// Requires a minimum role for read access to the replicated document. - /// - /// The enum type representing user roles. Must be defined with roles in ascending order of authority. - /// The minimum role required for read access. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireMinimumRoleToRead(TRole minimumRole) - where TRole : struct, Enum - { - RequireAccess(AccessType.Read, user => user.IsInRoleOrHigher(minimumRole)); - return this; - } - - /// - /// Requires a minimum role for write access to the replicated document. - /// - /// The enum type representing user roles. Must be defined with roles in ascending order of authority. - /// The minimum role required for write access. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireMinimumRoleToWrite(TRole minimumRole) - where TRole : struct, Enum - { - RequireAccess(AccessType.Write, user => user.IsInRoleOrHigher(minimumRole)); - return this; - } - - /// - /// Requires a minimum role for delete access to the replicated document. - /// - /// The enum type representing user roles. Must be defined with roles in ascending order of authority. - /// The minimum role required for delete access. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireMinimumRoleToDelete(TRole minimumRole) - where TRole : struct, Enum - { - RequireAccess(AccessType.Delete, user => user.IsInRoleOrHigher(minimumRole)); - return this; - } - - /// - /// Requires a minimum role for specified access types to the replicated document. - /// - /// The enum type representing user roles. Must be defined with roles in ascending order of authority. - /// The minimum role required for the specified access types. - /// The types of access to require the minimum role for. Defaults to all access types. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireMinimumRole(TRole minimumRole, AccessType accessType = AccessType.All) - where TRole : struct, Enum - { - if (accessType.HasFlag(AccessType.Read)) - { - RequireMinimumRoleToRead(minimumRole); - } - if (accessType.HasFlag(AccessType.Write)) - { - RequireMinimumRoleToWrite(minimumRole); - } - if (accessType.HasFlag(AccessType.Delete)) - { - RequireMinimumRoleToDelete(minimumRole); - } - return this; - } - - /// - /// Requires a custom condition to be met for read access to the replicated document. - /// - /// A function that takes a ClaimsPrincipal and returns a boolean indicating if the requirement is met. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireReadAccess(Func requirement) - { - return RequireAccess(AccessType.Read, requirement); - } - - /// - /// Requires a custom condition to be met for write access to the replicated document. - /// - /// A function that takes a ClaimsPrincipal and returns a boolean indicating if the requirement is met. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireWriteAccess(Func requirement) - { - return RequireAccess(AccessType.Write, requirement); - } - - /// - /// Requires a custom condition to be met for delete access to the replicated document. - /// - /// A function that takes a ClaimsPrincipal and returns a boolean indicating if the requirement is met. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireDeleteAccess(Func requirement) - { - return RequireAccess(AccessType.Delete, requirement); - } - - /// - /// Requires a specific claim for read access to the replicated document. - /// - /// The type of the required claim. - /// The required value of the claim. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireClaimForRead(string claimType, string claimValue) - { - return RequireAccess(AccessType.Read, user => user.HasClaim(claimType, claimValue)); - } - - /// - /// Requires a specific claim for write access to the replicated document. - /// - /// The type of the required claim. - /// The required value of the claim. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireClaimForWrite(string claimType, string claimValue) - { - return RequireAccess(AccessType.Write, user => user.HasClaim(claimType, claimValue)); - } - - /// - /// Requires a specific claim for delete access to the replicated document. - /// - /// The type of the required claim. - /// The required value of the claim. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireClaimForDelete(string claimType, string claimValue) - { - return RequireAccess(AccessType.Delete, user => user.HasClaim(claimType, claimValue)); - } - - /// - /// Requires the user to be authenticated for the specified access types. - /// - /// The types of access to require authentication for. Defaults to all access types. - /// The current SecurityOptions instance for method chaining. - public SecurityOptions RequireAuthentication(AccessType accessType = AccessType.All) - { - if (accessType.HasFlag(AccessType.Read)) - { - RequireAccess(AccessType.Read, user => user.Identity?.IsAuthenticated ?? false); - } - if (accessType.HasFlag(AccessType.Write)) - { - RequireAccess(AccessType.Write, user => user.Identity?.IsAuthenticated ?? false); - } - if (accessType.HasFlag(AccessType.Delete)) - { - RequireAccess(AccessType.Delete, user => user.Identity?.IsAuthenticated ?? false); - } - return this; - } - - private SecurityOptions RequireAccess(AccessType accessType, Func requirement) - { - Policies.Add(new AccessPolicy(accessType, requirement)); - return this; - } -} diff --git a/tests/RxDBDotNet.Tests.Setup/TestSecurityOptions.cs b/tests/RxDBDotNet.Tests.Setup/TestSecurityOptions.cs deleted file mode 100644 index 307eaf5..0000000 --- a/tests/RxDBDotNet.Tests.Setup/TestSecurityOptions.cs +++ /dev/null @@ -1,26 +0,0 @@ -using RxDBDotNet.Security; -using LiveDocs.GraphQLApi.Models.Shared; - -namespace RxDBDotNet.Tests.Setup; - -public class TestSecurityOptions -{ - public Action? UserSecurityConfig { get; set; } - public Action? WorkspaceSecurityConfig { get; set; } - public Action? LiveDocSecurityConfig { get; set; } - - public static TestSecurityOptions Default => new() - { - UserSecurityConfig = options => options - .RequireMinimumRoleToRead(UserRole.StandardUser) - .RequireMinimumRoleToWrite(UserRole.WorkspaceAdmin) - .RequireMinimumRoleToDelete(UserRole.WorkspaceAdmin), - - WorkspaceSecurityConfig = options => options - .RequireMinimumRoleToRead(UserRole.StandardUser) - .RequireMinimumRoleToWrite(UserRole.SystemAdmin), - - LiveDocSecurityConfig = options => options - .RequireMinimumRole(UserRole.StandardUser), - }; -}