Private/Add-FylgyrEvidence.ps1
|
function Add-FylgyrEvidence { [CmdletBinding()] [OutputType([PSCustomObject[]])] param( [Parameter(Mandatory)] [PSCustomObject[]]$Results, [PSCustomObject[]]$WorkflowFiles = @(), [Parameter(Mandatory)] [ValidatePattern('^[a-zA-Z0-9._-]+$')] [string]$Owner, [Parameter(Mandatory)] [ValidatePattern('^[a-zA-Z0-9._-]+$')] [string]$Repo, [Parameter(Mandatory)] [string]$Token ) $scanTime = [datetime]::UtcNow $commitSha = $null try { $repoInfo = Invoke-GitHubApi -Endpoint "repos/$Owner/$Repo" -Token $Token $defaultBranch = if ($repoInfo -and $repoInfo.default_branch) { [string]$repoInfo.default_branch } else { 'main' } $headCommit = Invoke-GitHubApi -Endpoint "repos/$Owner/$Repo/commits/$defaultBranch" -Token $Token if ($headCommit -and $headCommit.sha) { $commitSha = [string]$headCommit.sha } } catch { Write-Verbose "Unable to resolve commit SHA for evidence: $($_.Exception.Message)" } $workflowContentByPath = @{} foreach ($workflowFile in @($WorkflowFiles)) { if ($workflowFile -and $workflowFile.Path -and $workflowFile.Content) { $workflowContentByPath[[string]$workflowFile.Path] = [string]$workflowFile.Content } } foreach ($result in $Results) { if (-not $result) { continue } $resource = [string]$result.Resource $path = $null $line = $null if ($resource -match '^(.+):(\d+)$') { $path = [string]$Matches[1] $line = [int]$Matches[2] } elseif ($resource -like '.github/workflows/*') { $path = $resource } $yamlSnippet = $null if ($path -and $workflowContentByPath.ContainsKey($path)) { $yamlSnippet = Get-FylgyrYamlSnippet -Content $workflowContentByPath[$path] -Line $line } $permalink = $null if ($commitSha) { if ($path) { $permalink = "https://github.com/$Owner/$Repo/blob/$commitSha/$path" if ($line -and $line -gt 0) { $permalink = "$permalink#L$line" } } else { $permalink = "https://github.com/$Owner/$Repo/tree/$commitSha" } } $evidence = [ordered]@{ YamlSnippet = $yamlSnippet ApiResponse = $null CommitSha = $commitSha ScanTime = $scanTime Permalink = $permalink } $result | Add-Member -NotePropertyName 'Evidence' -NotePropertyValue $evidence -Force } return $Results } function Get-FylgyrYamlSnippet { [CmdletBinding()] [OutputType([string])] param( [Parameter(Mandatory)] [string]$Content, [int]$Line ) $rawLines = @($Content -split "`n") $lines = [System.Collections.Generic.List[string]]::new() foreach ($rawLine in $rawLines) { $lines.Add(($rawLine -replace "`r$", '')) } if ($lines.Count -eq 0) { return $null } if (-not $Line -or $Line -lt 1) { $startLine = 1 $endLine = [Math]::Min(5, $lines.Count) } else { $startLine = [Math]::Max(1, $Line - 2) $endLine = [Math]::Min($lines.Count, $Line + 2) } $snippetLines = [System.Collections.Generic.List[string]]::new() for ($idx = $startLine; $idx -le $endLine; $idx++) { $snippetLines.Add(('{0:D4}: {1}' -f $idx, $lines[$idx - 1])) } return ($snippetLines -join "`n") } |