Framework/Listeners/RemoteReports/VulnDataPublisher.ps1

Set-StrictMode -Version Latest

class VulnDataPublisher: ListenerBase {

    hidden VulnDataPublisher() {
    }

    hidden static [VulnDataPublisher] $Instance = $null;

    static [VulnDataPublisher] GetInstance() {
        if ( $null  -eq [VulnDataPublisher]::Instance  ) {
            [VulnDataPublisher]::Instance = [VulnDataPublisher]::new();
        }
        return [VulnDataPublisher]::Instance
    }

    [void] RegisterEvents() {
        $this.UnregisterEvents();

        $this.RegisterEvent([AzSdkRootEvent]::GenerateRunIdentifier, {
            $currentInstance = [VulnDataPublisher]::GetInstance();
            try
            {
                $runIdentifier = [AzSdkRootEventArgument] ($Event.SourceArgs | Select-Object -First 1)
                $currentInstance.SetRunIdentifier($runIdentifier);
            }
            catch
            {
                $currentInstance.PublishException($_);
            }
        });

        $this.RegisterEvent([SVTEvent]::EvaluationCompleted, {
            $currentInstance = [VulnDataPublisher]::GetInstance();
            try
            {
                $settings = [ConfigurationManager]::GetAzSdkConfigData();
                if(!$settings.PublishVulnDataToApi) {return;}
                $invocationContext = [System.Management.Automation.InvocationInfo] $currentInstance.InvocationContext
                $featureGroup = [RemoteReportHelper]::GetFeatureGroup($invocationContext.MyCommand.Name)
                $SVTEventContexts = [SVTEventContext[]] $Event.SourceArgs
                if($featureGroup -eq [FeatureGroup]::Subscription){
                    [VulnDataPublisher]::ReportSubscriptionScan($currentInstance, $invocationContext, $SVTEventContexts)
                }elseif($featureGroup -eq [FeatureGroup]::Service){
                    [VulnDataPublisher]::ReportServiceScan($currentInstance, $invocationContext, $SVTEventContexts)
                }else{

                }
            }
            catch
            {
                $currentInstance.PublishException($_);
            }
        });
    }

    static [void] ReportSubscriptionScan(
        [VulnDataPublisher] $publisher, `
        [System.Management.Automation.InvocationInfo]  $invocationContext, `
        [SVTEventContext[]] $SVTEventContexts)
    {
        $SVTEventContext = $SVTEventContexts[0]
        $scanResult = [SubscriptionScanInfo]::new()
        $scanResult.ScanKind = [RemoteReportHelper]::GetSubscriptionScanKind($invocationContext.MyCommand.Name, $invocationContext.BoundParameters)
        $scanResult.SubscriptionId = $SVTEventContext.SubscriptionContext.SubscriptionId
        $scanResult.SubscriptionName = $SVTEventContext.SubscriptionContext.SubscriptionName
        $scanResult.Source = [RemoteReportHelper]::GetScanSource()
        $scanResult.ScannerVersion = $publisher.GetCurrentModuleVersion()
        # TODO: Figure out, temp using module version
        $scanResult.ControlVersion = $publisher.GetCurrentModuleVersion()
        $results = [System.Collections.ArrayList]::new()
        $SVTEventContexts | ForEach-Object {
            $context = $_
            if ($context.ControlItem.Enabled) {
                $result = [RemoteReportHelper]::BuildSubscriptionControlResult($context.ControlResults[0], $context.ControlItem)
                $results.Add($result)
            }
            else {
                $result = [SubscriptionControlResult]::new()
                $result.ControlId = $context.ControlItem.ControlID
                $result.ActualVerificationResult = [VerificationResult]::Disabled
                $result.AttestationStatus = [AttestationStatus]::None
                $result.VerificationResult = [VerificationResult]::Disabled
                $results.Add($result)
            }
        }
        $scanResult.ControlResults = [SubscriptionControlResult[]] $results
        [RemoteApiHelper]::PostSubscriptionScanResult($scanResult)
    }

    static [void] ReportServiceScan(
        [VulnDataPublisher] $publisher, `
        [System.Management.Automation.InvocationInfo]  $invocationContext, `
        [SVTEventContext[]] $SVTEventContexts)
    {
        $SVTEventContextFirst = $SVTEventContexts[0]
        $scanResult = [ServiceScanInfo]::new()
        $scanResult.ScanKind = [RemoteReportHelper]::GetServiceScanKind($invocationContext.MyCommand.Name, $invocationContext.BoundParameters)
        $scanResult.SubscriptionId = $SVTEventContextFirst.SubscriptionContext.SubscriptionId
        $scanResult.SubscriptionName = $SVTEventContextFirst.SubscriptionContext.SubscriptionName
        $scanResult.Source = [RemoteReportHelper]::GetScanSource()
        $scanResult.ScannerVersion = $publisher.GetCurrentModuleVersion()
        # TODO: Figure out, temp using module version
        $scanResult.ControlVersion = $publisher.GetCurrentModuleVersion()
        $scanResult.Feature = $SVTEventContextFirst.FeatureName
        $scanResult.ResourceGroup = $SVTEventContextFirst.ResourceContext.ResourceGroupName
        $scanResult.ResourceName = $SVTEventContextFirst.ResourceContext.ResourceName
        $scanResult.ResourceId = $SVTEventContextFirst.ResourceContext.ResourceId
        $results = [System.Collections.ArrayList]::new()
        $SVTEventContexts | ForEach-Object {
            $SVTEventContext = $_
            if (!$SVTEventContext.ControlItem.Enabled) {
                $result = [ServiceControlResult]::new()
                $result.ControlId = $SVTEventContext.ControlItem.ControlID
                $result.ControlSeverity = $SVTEventContext.ControlItem.ControlSeverity
                $result.ActualVerificationResult = [VerificationResult]::Disabled
                $result.AttestationStatus = [AttestationStatus]::None
                $result.VerificationResult = [VerificationResult]::Disabled
                $results.Add($result)
            }
            elseif ($SVTEventContext.ControlResults.Count -eq 1 -and `
                ($scanResult.ResourceName -eq $SVTEventContext.ControlResults[0].ChildResourceName -or `
                    [string]::IsNullOrWhiteSpace($SVTEventContext.ControlResults[0].ChildResourceName)))
            {
                $result = [RemoteReportHelper]::BuildServiceControlResult($SVTEventContext.ControlResults[0], `
                    $false, $SVTEventContext.ControlItem)
                $results.Add($result)
            }
            elseif ($SVTEventContext.ControlResults.Count -eq 1 -and `
                $scanResult.ResourceName -ne $SVTEventContext.ControlResults[0].ChildResourceName)
            {
                $result = [RemoteReportHelper]::BuildServiceControlResult($SVTEventContext.ControlResults[0], `
                     $true, $SVTEventContext.ControlItem)
                $results.Add($result)
            }
            elseif ($SVTEventContext.ControlResults.Count -gt 1)
            {
                $SVTEventContext.ControlResults | Foreach-Object {
                    $result = [RemoteReportHelper]::BuildServiceControlResult($_ , `
                         $true, $SVTEventContext.ControlItem)
                    $results.Add($result)
                }
            }
        }
        $scanResult.ControlResults = [ServiceControlResult[]] $results
        [RemoteApiHelper]::PostServiceScanResult($scanResult)
    }
}