< Summary

Information
Class: Elsa.Abstractions.EndpointSecurity
Assembly: Elsa.Api.Common
File(s): /home/runner/work/elsa-core/elsa-core/src/common/Elsa.Api.Common/Abstractions/EndpointSecurity.cs
Line coverage
68%
Covered lines: 15
Uncovered lines: 7
Coverable lines: 22
Total lines: 72
Line coverage: 68.1%
Branch coverage
50%
Covered branches: 6
Total branches: 12
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%210%
RequirePermission(...)62.5%8883.33%
RequireAuthenticatedOnly(...)50%2260%
ConfigurePermissions(...)0%620%

File(s)

/home/runner/work/elsa-core/elsa-core/src/common/Elsa.Api.Common/Abstractions/EndpointSecurity.cs

#LineLine coverage
 1using Elsa.Authorization;
 2using FastEndpoints;
 3using Microsoft.AspNetCore.Builder;
 4using Microsoft.AspNetCore.Http;
 5using Microsoft.Extensions.DependencyInjection;
 6
 7namespace Elsa.Abstractions;
 8
 9/// <summary>
 10/// The one implementation behind every base class's security helpers. The base classes cannot share a
 11/// common ancestor of their own, so the logic lives here rather than being copied six times.
 12/// </summary>
 13internal static class EndpointSecurity
 14{
 15    /// <summary>Used when the host has registered no evaluator of its own. Stateless, so sharing is safe.</summary>
 016    private static readonly IPermissionEvaluator SharedEvaluator = new PermissionEvaluator();
 17
 18    /// <summary>
 19    /// Requires a permission satisfying <paramref name="resource"/> and <paramref name="verb"/>. The
 20    /// requirement is attached as an inline policy so it needs no separate policy registration, and it is
 21    /// evaluated by <see cref="IPermissionEvaluator"/> like every other permission decision.
 22    /// </summary>
 23    public static void RequirePermission(EndpointDefinition definition, string resource, string verb)
 24    {
 32425        if (!EndpointSecurityOptions.SecurityIsEnabled)
 26        {
 1227            definition.AllowAnonymous();
 1228            return;
 29        }
 30
 31231        var permission = new Permission(resource, verb);
 32
 31233        EndpointPermissionRegistry.Record(definition.EndpointType, permission);
 34
 35        // Evaluated inline rather than through a registered IAuthorizationHandler. A handler would make
 36        // enforcement depend on the host having called AddElsaAuthorization: miss it, and every endpoint
 37        // answers 403 with nothing to indicate why. Hosts that wire FastEndpoints themselves -- several
 38        // test hosts among them -- do exactly that. The evaluator is stateless, so falling back to a shared
 39        // instance is safe, while a host that registers its own still wins.
 103240        definition.Options(x => x.RequireAuthorization(policy => policy.RequireAssertion(context =>
 103241        {
 3042            var evaluator = (context.Resource as HttpContext)?.RequestServices.GetService<IPermissionEvaluator>() ?? Sha
 103243
 3044            return evaluator.HasPermission(context.User, permission);
 103245        })));
 31246    }
 47
 48    /// <summary>
 49    /// Requires an authenticated caller but no permission. FR-019's third declaration state: it exists so
 50    /// that a deliberate "needs an identity, needs no grant" choice is distinguishable from an author who
 51    /// forgot to declare anything, which the coverage gate would otherwise have to treat alike.
 52    /// </summary>
 53    public static void RequireAuthenticatedOnly(EndpointDefinition definition)
 54    {
 355        if (!EndpointSecurityOptions.SecurityIsEnabled)
 56        {
 057            definition.AllowAnonymous();
 058            return;
 59        }
 60
 961        definition.Options(x => x.RequireAuthorization(policy => policy.RequireAuthenticatedUser()));
 362    }
 63
 64    /// <summary>The legacy string-based declaration, preserved for modules outside this repository.</summary>
 65    public static void ConfigurePermissions(EndpointDefinition definition, string[] permissions)
 66    {
 067        if (!EndpointSecurityOptions.SecurityIsEnabled)
 068            definition.AllowAnonymous();
 69        else
 070            definition.Permissions([PermissionNames.All, .. permissions]);
 071    }
 72}