< Summary

Information
Class: Elsa.Authorization.PermissionMatcher
Assembly: Elsa.Api.Common
File(s): /home/runner/work/elsa-core/elsa-core/src/common/Elsa.Api.Common/Authorization/PermissionMatcher.cs
Line coverage
100%
Covered lines: 15
Uncovered lines: 0
Coverable lines: 15
Total lines: 46
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Satisfies(...)100%22100%
Satisfies(...)100%11100%
ResourceMatches(...)100%1212100%
VerbMatches(...)100%22100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/common/Elsa.Api.Common/Authorization/PermissionMatcher.cs

#LineLine coverage
 1namespace Elsa.Authorization;
 2
 3/// <summary>
 4/// Decides whether a held permission satisfies a required one. One matching rule shape on both axes:
 5/// exact match, or a wildcard.
 6/// </summary>
 7public static class PermissionMatcher
 8{
 9    /// <summary>Whether <paramref name="granted"/> satisfies <paramref name="required"/>.</summary>
 10    public static bool Satisfies(Permission granted, Permission required) =>
 7711        ResourceMatches(granted.Resource, required.Resource) && VerbMatches(granted.Verb, required.Verb);
 12
 13    /// <summary>Whether any of <paramref name="granted"/> satisfies <paramref name="required"/>.</summary>
 14    public static bool Satisfies(IEnumerable<Permission> granted, Permission required) =>
 2415        granted.Any(x => Satisfies(x, required));
 16
 17    /// <summary>
 18    /// Whether a granted resource pattern covers a required resource. A trailing <c>/*</c> matches the
 19    /// named node and every descendant at any depth; a bare <c>*</c> matches everything.
 20    /// </summary>
 21    public static bool ResourceMatches(string granted, string required)
 22    {
 9023        if (granted == Permission.Wildcard)
 3924            return true;
 25
 5126        if (string.Equals(granted, required, StringComparison.Ordinal))
 1727            return true;
 28
 3429        if (!granted.EndsWith($"{Permission.PathSeparator}{Permission.Wildcard}", StringComparison.Ordinal))
 1030            return false;
 31
 32        // 'workflows/*' covers 'workflows' itself as well as everything beneath it.
 2433        var prefix = granted[..^2];
 34
 2435        if (string.Equals(prefix, required, StringComparison.Ordinal))
 236            return true;
 37
 2238        return required.Length > prefix.Length
 2239               && required.StartsWith(prefix, StringComparison.Ordinal)
 2240               && required[prefix.Length] == Permission.PathSeparator;
 41    }
 42
 43    /// <summary>Whether a granted verb covers a required verb.</summary>
 44    public static bool VerbMatches(string granted, string required) =>
 6145        granted == Permission.Wildcard || string.Equals(granted, required, StringComparison.Ordinal);
 46}