< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.ServiceAuthorizationManager
Assembly: CoreWCF.Primitives
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/ServiceAuthorizationManager.cs
Line coverage
89%
Covered lines: 53
Uncovered lines: 6
Coverable lines: 59
Total lines: 156
Line coverage: 89.8%
Branch coverage
50%
Covered branches: 10
Total branches: 20
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor()100%11100%
CheckAccess(...)100%11100%
CheckAccessAsync()100%22100%
CheckAccess(...)50%4483.33%
CheckAccessAsync()50%4485.71%
GetAuthorizationPolicies(...)40%101075%
CheckAccessCore(...)100%11100%
CheckAccessCoreAsync(...)100%110%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Primitives/src/CoreWCF/ServiceAuthorizationManager.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Collections.Generic;
 6using System.Collections.ObjectModel;
 7using System.Linq;
 8using System.Reflection;
 9using System.Threading.Tasks;
 10using CoreWCF.Channels;
 11using CoreWCF.IdentityModel.Policy;
 12using CoreWCF.Security;
 13
 14namespace CoreWCF
 15{
 16    public class ServiceAuthorizationManager
 17    {
 18        private readonly bool _isAsyncImplementation;
 19
 720        public ServiceAuthorizationManager()
 21        {
 722            Type implementorType = GetType();
 723            var methods = implementorType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instanc
 24
 725            var checkAccessCoreAsyncMethodInfo = (from method in methods
 9126                where method.Name == nameof(CheckAccessCoreAsync)
 727                let parameters = method.GetParameters()
 728                where parameters.Length == 1
 729                let firstParameter = parameters[0]
 730                where firstParameter.ParameterType == typeof(OperationContext)
 1431                select method).SingleOrDefault();
 32
 733            var baseCheckAccessCoreAsyncMethodInfo = checkAccessCoreAsyncMethodInfo!.GetBaseDefinition();
 34
 735            bool isCheckAccessCoreAsyncOverridden = baseCheckAccessCoreAsyncMethodInfo.DeclaringType != checkAccessCoreA
 36
 737            var checkAccessAsyncWithSingleParameterMethodInfo = (from method in methods
 9138                where  method.Name == nameof(CheckAccessAsync)
 1439                let parameters = method.GetParameters()
 1440                where  parameters.Length == 1
 741                let firstParameter = parameters[0]
 742                where firstParameter.ParameterType == typeof(OperationContext)
 1443                select method).SingleOrDefault();
 44
 745            var baseCheckAccessAsyncWithSingleParameterMethodInfo =
 746                checkAccessAsyncWithSingleParameterMethodInfo!.GetBaseDefinition();
 47
 748            bool isCheckAccessAsyncWithSingleParameterOverridden =
 749                baseCheckAccessAsyncWithSingleParameterMethodInfo.DeclaringType != checkAccessAsyncWithSingleParameterMe
 50
 751            _isAsyncImplementation = isCheckAccessCoreAsyncOverridden || isCheckAccessAsyncWithSingleParameterOverridden
 752        }
 53
 54        // This is the API called by framework to perform CheckAccess.
 55        // The API is responsible for ...
 56        // 1) Evaluate all policies (Forward\Backward)
 57        // 2) Optionally wire up the resulting AuthorizationContext
 58        //    to ServiceSecurityContext.
 59        // 3) An availability of message content to make an authoritive decision.
 60        // 4) Return the authoritive decision true/false (allow/deny).
 61        [Obsolete("Implementers should override CheckAccessAsync.")]
 1562        public virtual bool CheckAccess(OperationContext operationContext, ref Message message) => CheckAccess(operation
 63
 64        public virtual async ValueTask<(bool isAuthorized, Message message)> CheckAccessAsync(OperationContext operation
 65        {
 1766            if (_isAsyncImplementation)
 67            {
 268                var isAuthorized = await CheckAccessAsync(operationContext);
 269                return (isAuthorized, message);
 70            }
 71
 72            // delegate to matching sync call overload
 1573            bool checkAccessResult = CheckAccess(operationContext, ref message);
 1574            return (checkAccessResult, message);
 1775        }
 76
 77        [Obsolete("Implementers should override CheckAccessAsync.")]
 78        public virtual bool CheckAccess(OperationContext operationContext)
 79        {
 1580            if (operationContext == null)
 81            {
 082                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(operationContext));
 83            }
 84
 85            // default to forward-chaining implementation
 86            // 1) Get policies that will participate in chain process.
 87            //    We provide a safe default policies set below.
 1588            ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = GetAuthorizationPolicies(operationContext);
 89
 90            // 2) Do forward chaining and wire the new ServiceSecurityContext
 1591            operationContext.IncomingMessageProperties.Security.ServiceSecurityContext =
 1592                new ServiceSecurityContext(authorizationPolicies ?? EmptyReadOnlyCollection<IAuthorizationPolicy>.Instan
 93
 94            // 3) Call the CheckAccessCore(OperationContext operationContext)
 1595            return CheckAccessCore(operationContext);
 96        }
 97
 98        public virtual async ValueTask<bool> CheckAccessAsync(OperationContext operationContext)
 99        {
 2100            if (operationContext == null)
 101            {
 0102                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(operationContext));
 103            }
 104
 105            // default to forward-chaining implementation
 106            // 1) Get policies that will participate in chain process.
 107            //    We provide a safe default policies set below.
 2108            ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = GetAuthorizationPolicies(operationContext);
 109
 110            // 2) Do forward chaining and wire the new ServiceSecurityContext
 2111            operationContext.IncomingMessageProperties.Security.ServiceSecurityContext =
 2112                new ServiceSecurityContext(authorizationPolicies ?? EmptyReadOnlyCollection<IAuthorizationPolicy>.Instan
 113
 114            // 3) Call the CheckAccessCoreAsync(OperationContext operationContext)
 2115            return await CheckAccessCoreAsync(operationContext);
 2116        }
 117
 118        // Define the set of policies taking part in chaining.  We will provide
 119        // the safe default set (primary token + all supporting tokens except token with
 120        // with SecurityTokenAttachmentMode.Signed + transport token). Implementor
 121        // can override and provide different selection of policies set.
 122        protected virtual ReadOnlyCollection<IAuthorizationPolicy> GetAuthorizationPolicies(OperationContext operationCo
 123        {
 17124            SecurityMessageProperty security = operationContext.IncomingMessageProperties.Security;
 17125            if (security == null)
 126            {
 0127                return EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
 128            }
 129
 17130            ReadOnlyCollection<IAuthorizationPolicy> externalPolicies = security.ExternalAuthorizationPolicies;
 17131            if (security.ServiceSecurityContext == null)
 132            {
 0133                return externalPolicies ?? EmptyReadOnlyCollection<IAuthorizationPolicy>.Instance;
 134            }
 135
 17136            ReadOnlyCollection<IAuthorizationPolicy> authorizationPolicies = security.ServiceSecurityContext.Authorizati
 17137            if (externalPolicies == null || externalPolicies.Count <= 0)
 138            {
 0139                return authorizationPolicies;
 140            }
 141
 142            // Combine
 17143            List<IAuthorizationPolicy> policies = new(authorizationPolicies);
 17144            policies.AddRange(externalPolicies);
 17145            return policies.AsReadOnly();
 146        }
 147
 148        [Obsolete("Implementers should override CheckAccessCoreAsync.")]
 13149        protected virtual bool CheckAccessCore(OperationContext operationContext) => true;
 150
 151        // Implementor overrides this API to make authoritive decision.
 152        // The AuthorizationContext in opContext is generally the result from forward chain.
 0153        protected virtual ValueTask<bool> CheckAccessCoreAsync(OperationContext operationContext) => new (true);
 154
 155    }
 156}