pwsh/prerequisites.ps1 (182 lines of code) (raw):
#20220521_1
#This script should be run in Azure DevOps Pipelines and GitHub Actions only
param(
[string]
$OutputPath = 'wiki'
)
if ($env:SYSTEM_TEAMPROJECTID -and $env:BUILD_REPOSITORY_ID) {
$codeRunPlatform = 'AzureDevOps'
}
elseif ($env:GITHUB_ACTIONS) {
$codeRunPlatform = 'GitHubActions'
}
else {
$codeRunPlatform = "not 'AzureDevOps', not 'GitHubActions'"
}
Write-Host 'CodeRunPlatform:' $codeRunPlatform
if ($codeRunPlatform -eq 'GitHubActions') {
$repoUri = "https://github.com/$($env:GITHUB_REPOSITORY)"
Write-Host "Testing if repository '$($repoUri)' is accessible from the public"
try {
$res = Invoke-WebRequest -Uri $repoUri
$statusCode = $res.StatusCode
}
catch {
$statusCode = $_.Exception.Response.StatusCode.value__
}
finally {
if ($statusCode -eq 404) {
Write-Host "Test returned statusCode: '$statusCode' - '$($repoUri)' seems not accessible from the public - proceed"
}
elseif ($statusCode -eq 200) {
Write-Host "Test returned statusCode: '$statusCode' - '$($repoUri)' is accessible from the public!"
Write-Host 'Assuming and insisting that you do not want to publish your tenant insights to the public - throw'
throw
}
else {
Write-Host "Test returned statusCode: '$statusCode' - skipping this test"
}
}
Write-Host "outputpath is '$OutputPath'"
if (-not (Test-Path -Path ".\$OutputPath")) {
#Assuming this is the initial run
#Create the outputpath dir
Write-Host "Creating directory '$OutputPath'"
New-Item -ItemType Directory -Force -Path $OutputPath
Get-ChildItem
}
else {
Write-Host "outputpath dir '$OutputPath' already exists"
}
}
if ($codeRunPlatform -eq 'AzureDevOps') {
Write-Host "outputpath is '$($OutputPath)'"
if (-not (Test-Path -Path "$($env:SYSTEM_DEFAULTWORKINGDIRECTORY)/$($OutputPath)")) {
#Assuming this is the initial run
#Create the outputpath dir
Write-Host "Creating directory '$($OutputPath)'"
New-Item -ItemType Directory -Force -Path "$($env:SYSTEM_DEFAULTWORKINGDIRECTORY)/$($OutputPath)"
#Repository permission check
Write-Host 'Repository access check'
#createHeader
$pat = $env:SYSTEM_ACCESSTOKEN #$(System.AccessToken)
$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($pat)"))
$header = @{authorization = "Basic $token" }
$collectionUri = $env:SYSTEM_COLLECTIONURI #$(System.CollectionUri)
$project = $env:SYSTEM_TEAMPROJECT #$(System.TeamProject)
#region listRepos
$uri = "$($collectionUri)/$($project)/_apis/git/repositories?api-version=5.1"
$repos = Invoke-RestMethod -Uri $uri -Method 'get' -Headers $header -ContentType 'application/json'
$htRepos = @{}
foreach ($repo in $repos.value) {
$htRepos.($repo.id) = @{}
$htRepos.($repo.id).name = $repo.name
}
#endregion listRepos
#region gettingSubjectDescriptor
$organization = $collectionUri.Substring(0, $collectionUri.Length - 1) -replace '.*/'
$buildServiceAccountId = $env:SYSTEM_TEAMPROJECTID #$(System.TeamProjectId)
#either 'Project Collection Build Service ($($organization))' OR '$($project) Build Service ($($organization))'
$buildAccount = "Project Collection Build Service ($($organization))"
Write-Host "Checking: $buildAccount"
$uri = "https://vssps.dev.azure.com/$($organization)/_apis/identities?searchFilter=General&filterValue=$($buildAccount)&queryMembership=None&api-version=6.0"
try {
$res = Invoke-RestMethod -Uri $uri -Method 'GET' -Headers $header -ContentType 'application/json'
}
catch {
Write-Host "Checking: $buildAccount failed:"
$_
Write-Host "Checking: $buildAccount failed; skipping check"
$skipCheck = $true
}
if (-not $skipCheck) {
$providerDisplayName = $res.value.providerDisplayName
$providerDisplayNameProjectCollectionBuildService = $providerDisplayName
$subjectDescriptor = $res.value.subjectDescriptor
if ($providerDisplayName -ne $buildServiceAccountId) {
$buildAccount = "$($project) Build Service ($($organization))"
Write-Host "Checking: $buildAccount"
$uri = "https://vssps.dev.azure.com/$($organization)/_apis/identities?searchFilter=General&filterValue=$($buildAccount)&queryMembership=None&api-version=6.0"
$res = Invoke-RestMethod -Uri $uri -Method 'GET' -Headers $header -ContentType 'application/json'
$providerDisplayName = $res.value.providerDisplayName
$providerDisplayNameProjectBuildService = $providerDisplayName
$subjectDescriptor = $res.value.subjectDescriptor
}
#endregion gettingSubjectDescriptor
if ($providerDisplayName -ne $buildServiceAccountId) {
Write-Host "Neighter 'Project Collection Build Service ($($organization)) $($providerDisplayNameProjectCollectionBuildService)' nore '$($project) Build Service ($($organization))' $providerDisplayNameProjectBuildService matching Id: $($buildServiceAccountId)"
}
else {
Write-Host "subjectDescriptor for '$($buildAccount)':" $subjectDescriptor
#region gettingPermissions
$repositoryId = $env:BUILD_REPOSITORY_ID #$(Build.Repository.ID)
$permissionSetId = '2e9eb7ed-3c0a-47d4-87c1-0ffdd275fd87' #Git Repositories
$uri = "$($collectionUri)/_apis/Contribution/HierarchyQuery?api-version=5.0-preview.1"
$body = @"
{
"contributionIds": [
"ms.vss-admin-web.security-view-permissions-data-provider"
],
"dataProviderContext": {
"properties": {
"subjectDescriptor": "$($subjectDescriptor)",
"permissionSetId": "$($permissionSetId)",
"permissionSetToken": "repoV2/$($buildServiceAccountId)/$($repositoryId)"
}
}
}
"@
$permissions = Invoke-RestMethod -Uri $uri -Method 'post' -Body $body -Headers $header -ContentType 'application/json'
$htPermissionsRef = @{}
$htPermissionsRef.'1' = 'allow'
$htPermissionsRef.'2' = 'deny'
$htPermissionsRef.'3' = 'allow(inherited)'
Write-Host "'$($buildAccount)' ($buildServiceAccountId) permissions for Repository: $($htRepos.($repositoryId).name) ($repositoryId)"
$contributePermissionState = ($permissions.dataProviders.'ms.vss-admin-web.security-view-permissions-data-provider'.subjectPermissions).where( { $_.displayName -eq 'Contribute' } ).effectivePermissionValue
if ($contributePermissionState -eq 1 -or $contributePermissionState -eq 3) {
Write-Host " Contribute: $($htPermissionsRef."$contributePermissionState") ($($contributePermissionState))"
}
else {
if ($contributePermissionState) {
Write-Host " Contribute: $($htPermissionsRef."$contributePermissionState") ($($contributePermissionState))"
}
else {
Write-Host ' Contribute: not set'
}
$testResult = 'FAILED'
}
Write-Host 'All permissions:'
foreach ($permission in $permissions.dataProviders.'ms.vss-admin-web.security-view-permissions-data-provider'.subjectPermissions) {
if ($permission.effectivePermissionValue) {
Write-Host " $($permission.displayName): $($htPermissionsRef."$($permission.effectivePermissionValue)") ($($permission.effectivePermissionValue))"
}
else {
Write-Host " $($permission.displayName): not set"
}
}
if ($testResult -eq 'FAILED') {
Write-Host ''
Write-Host '- - - - - - - - - - - - - - - - -'
Write-Host 'Repository permission test failed'
Write-Host "You must grant the Account '$($buildAccount)' ($buildServiceAccountId) with 'Contribute' permissions on the Repository '$($htRepos.($repositoryId).name)'' ($repositoryId)"
Write-Host 'Instructions: https://github.com/Azure/Azure-Governance-Visualizer/blob/master/setup.md#grant-permissions-on-azgovviz-azdo-repository'
Write-Error 'Error'
}
else {
$timestamp = Get-Date -Format 'yyyy-MM-dd_HH:mm:ss'
$fileContent = @"
Repository access check result:
Date: $($timestamp)
Build Account: '$($buildAccount)' ($buildServiceAccountId)
Permission 'Contribute' for Repository '$($htRepos.($repositoryId).name) ($repositoryId)': $($contributePermissionState)
"@
$fileContent | Set-Content -Path "$($env:SYSTEM_DEFAULTWORKINGDIRECTORY)/AzGovViz_RepositoryPermissionCheck.log" -Encoding utf8 -Force
}
#endregion gettingPermissions
}
}
}
else {
Write-Host "outputpath dir '$($OutputPath)' already exists"
}
}