< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.BuildTools.AuthorizationAttributesAnalyzer
Assembly: CoreWCF.BuildTools.Roslyn3.11
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.BuildTools/src/AuthorizationAttributesAnalyzer.cs
Line coverage
97%
Covered lines: 89
Uncovered lines: 2
Coverable lines: 91
Total lines: 177
Line coverage: 97.8%
Branch coverage
92%
Covered branches: 26
Total branches: 28
Branch coverage: 92.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.BuildTools/src/AuthorizationAttributesAnalyzer.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.Collections.Immutable;
 5using System.Linq;
 6using Microsoft.CodeAnalysis;
 7using Microsoft.CodeAnalysis.Diagnostics;
 8
 9namespace CoreWCF.BuildTools;
 10
 11[DiagnosticAnalyzer(LanguageNames.CSharp)]
 12public sealed class AuthorizationAttributesAnalyzer : DiagnosticAnalyzer
 13{
 14    private const string AuthenticationSchemesPropertyName = "AuthenticationSchemes";
 15    private const string RolesPropertyName = "Roles";
 16    private const string AuthorizeDataTypeName = "Microsoft.AspNetCore.Authorization.IAuthorizeData";
 17    private const string AllowAnonymousTypeName = "Microsoft.AspNetCore.Authorization.IAllowAnonymous";
 18    private const string CoreWCFServiceContractAttributeTypeName = "CoreWCF.ServiceContractAttribute";
 19    private const string CoreWCFOperationContractAttributeTypeName = "CoreWCF.OperationContractAttribute";
 20    private const string SSMServiceContractAttributeTypeName = "System.ServiceModel.ServiceContractAttribute";
 21    private const string SSMOperationContractAttributeTypeName = "System.ServiceModel.OperationContractAttribute";
 22    private const string CoreWCFInjectedAttributeTypeName = "CoreWCF.InjectedAttribute";
 23    private const string MVCFromServicesAttributeTypeName = "Microsoft.AspNetCore.Mvc.FromServicesAttribute";
 24
 125    private static readonly ImmutableArray<DiagnosticDescriptor> s_supportedDiagnostics =
 126        new[]
 127            {
 128                DiagnosticDescriptors.AuthorizationAttributesAnalyzer_02XX.AllowAnonymousAttributeIsNotSupported,
 129                DiagnosticDescriptors.AuthorizationAttributesAnalyzer_02XX.AuthorizeDataAuthenticationSchemesPropertyIsN
 130                DiagnosticDescriptors.AuthorizationAttributesAnalyzer_02XX.AuthorizeDataRolesPropertyIsNotSupported
 131            }
 132            .ToImmutableArray();
 33
 34    public override void Initialize(AnalysisContext context)
 35    {
 3636        context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDia
 37#if !DEBUG
 3638        context.EnableConcurrentExecution();
 39#endif
 3640        context.RegisterCompilationStartAction(compilationStartContext =>
 3641        {
 2342            INamedTypeSymbol? allowAnonymous = compilationStartContext.Compilation.GetTypeByMetadataName(AllowAnonymousT
 2343            INamedTypeSymbol? authorizeData = compilationStartContext.Compilation.GetTypeByMetadataName(AuthorizeDataTyp
 2344            INamedTypeSymbol? ssmServiceContractAttribute = compilationStartContext.Compilation.GetTypeByMetadataName(SS
 2345            INamedTypeSymbol? coreWCFServiceContractAttribute = compilationStartContext.Compilation.GetTypeByMetadataNam
 2346            INamedTypeSymbol? ssmOperationContractAttribute = compilationStartContext.Compilation.GetTypeByMetadataName(
 2347            INamedTypeSymbol? coreWCFOperationContractAttribute = compilationStartContext.Compilation.GetTypeByMetadataN
 2348            INamedTypeSymbol? coreWCFInjectedAttribute = compilationStartContext.Compilation.GetTypeByMetadataName(CoreW
 2349            INamedTypeSymbol? mvcFromServicesAttribute = compilationStartContext.Compilation.GetTypeByMetadataName(MVCFr
 3650
 2351            compilationStartContext.RegisterSymbolAction(
 4652                context => WarnWhenAllowAnonymousOnServiceContractImplementation(context, allowAnonymous, coreWCFService
 2353                SymbolKind.NamedType);
 2354            compilationStartContext.RegisterSymbolAction(
 7055                context => WarnWhenAllowAnonymousOnOperationContractImplementation(context, allowAnonymous, ssmServiceCo
 2356                SymbolKind.Method);
 2357            compilationStartContext.RegisterSymbolAction(
 7058                context => WarnWhenAuthorizeDataWithAuthenticationSchemesOrRolesPropertySetOnOperationContractImplementa
 2359                SymbolKind.Method);
 5960        });
 3661    }
 62
 57463    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => s_supportedDiagnostics;
 64
 65    private static void WarnWhenAuthorizeDataWithAuthenticationSchemesOrRolesPropertySetOnOperationContractImplementatio
 66    {
 7067        IMethodSymbol methodSymbol = (IMethodSymbol)context.Symbol;
 7068        if (methodSymbol.IsGeneratedCode() == true)
 69        {
 1270            return;
 71        }
 72
 5873        bool hasAuthorizeData = methodSymbol.HasOneAttributeInheritFrom(authorizeData);
 5874        if (!hasAuthorizeData)
 75        {
 4676            return;
 77        }
 78
 1279        bool isOperationContractImplementation = IsOperationContractImplementation(methodSymbol, ssmServiceContractAttri
 1280        if (!isOperationContractImplementation)
 81        {
 082            return;
 83        }
 84
 1285        var arguments = from attribute in methodSymbol.GetAttributes()
 1286            where attribute.AttributeClass!.AllInterfaces.Any(@interface =>
 2487                @interface.Equals(authorizeData, SymbolEqualityComparer.Default))
 1288            from args in attribute.NamedArguments
 2089            select args;
 90
 4091        foreach (var argument in arguments)
 92        {
 893            if (argument.Key == AuthenticationSchemesPropertyName)
 94            {
 495                context.ReportDiagnostic(DiagnosticDescriptors.AuthorizationAttributesAnalyzer_02XX.AuthorizeDataAuthent
 496                continue;
 97            }
 498            if (argument.Key == RolesPropertyName)
 99            {
 4100                context.ReportDiagnostic(DiagnosticDescriptors.AuthorizationAttributesAnalyzer_02XX.AuthorizeDataRolesPr
 101            }
 102        }
 12103    }
 104
 105    private static void WarnWhenAllowAnonymousOnOperationContractImplementation(SymbolAnalysisContext context, INamedTyp
 106    {
 70107        IMethodSymbol methodSymbol = (IMethodSymbol)context.Symbol;
 70108        if (methodSymbol.IsGeneratedCode() == true)
 109        {
 12110            return;
 111        }
 112
 58113        bool hasAllowAnonymous = methodSymbol.HasOneAttributeInheritFrom(allowAnonymous);
 58114        if (!hasAllowAnonymous)
 115        {
 45116            return;
 117        }
 118
 13119        bool isOperationContractImplementation = IsOperationContractImplementation(methodSymbol, ssmServiceContractAttri
 120
 13121        if (isOperationContractImplementation)
 122        {
 12123            context.ReportDiagnostic(DiagnosticDescriptors.AuthorizationAttributesAnalyzer_02XX.AllowAnonymousAttributeI
 124        }
 13125    }
 126
 127    private static bool IsOperationContractImplementation(IMethodSymbol methodSymbol, INamedTypeSymbol? ssmServiceContra
 128    {
 25129        var serviceContracts = (from @interface in methodSymbol.ContainingType.AllInterfaces
 28130            where @interface.GetOneAttributeOf(ssmServiceContractAttribute, coreWCFServiceContractAttribute) is not null
 25131            select @interface).ToImmutableArray();
 132
 25133        if (serviceContracts.IsEmpty)
 134        {
 1135            return false;
 136        }
 137
 24138        var operationContracts = (from serviceContract in serviceContracts
 60139            from method in serviceContract.GetMembers().OfType<IMethodSymbol>()
 36140            where method.Name == methodSymbol.Name
 36141            where method.GetOneAttributeOf(coreWCFOperationContractAttribute, ssmOperationContractAttribute) is not null
 60142            select method).ToImmutableArray();
 143
 24144        var implementedMethods = methodSymbol.ContainingType.GetMembers().OfType<IMethodSymbol>()
 84145            .Where(x => x.Name == methodSymbol.Name)
 24146            .ToImmutableArray();
 147
 72148        foreach (IMethodSymbol operationContract in operationContracts)
 149        {
 24150            if (implementedMethods.Any(implementedMethod =>
 72151                    implementedMethod.IsMatchingUserProvidedMethod(operationContract, coreWCFInjectedAttribute,
 72152                        mvcFromServicesAttribute)))
 153            {
 24154                return true;
 155            }
 156        }
 157
 0158        return false;
 159    }
 160
 161    private static void WarnWhenAllowAnonymousOnServiceContractImplementation(SymbolAnalysisContext context, INamedTypeS
 162    {
 46163        INamedTypeSymbol namedTypeSymbol = (INamedTypeSymbol)context.Symbol;
 164
 46165        bool hasAllowAnonymous = namedTypeSymbol.HasOneAttributeInheritFrom(allowAnonymous);
 46166        if (!hasAllowAnonymous)
 167        {
 41168            return;
 169        }
 170
 5171        if (namedTypeSymbol.AllInterfaces.Any(x =>
 13172                x.GetOneAttributeOf(coreWCFServiceContractAttribute, ssmServiceContractAttribute) is not null))
 173        {
 4174            context.ReportDiagnostic(DiagnosticDescriptors.AuthorizationAttributesAnalyzer_02XX.AllowAnonymousAttributeI
 175        }
 5176    }
 177}