Providers/Authentik/Public/New-AuthentikScopeMapping.ps1
|
function New-AuthentikScopeMapping { <# .EXTERNALHELP TestEnvironment-Help.xml .SYNOPSIS Creates the seeded OAuth2 scope mappings from Data\AuthentikScopeMappings.csv and attaches them to providers #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] [OutputType([PSCustomObject])] param( [Parameter()] [string[]]$MappingName, [Parameter()] [switch]$SkipProvider, [Parameter()] [switch]$PassThru ) $connection = Get-AuthentikConnection $marker = Get-AuthentikSeedMarker -Connection $connection $csvPath = Join-Path -Path (Get-AuthentikDataPath) -ChildPath 'AuthentikScopeMappings.csv' $rows = @(Import-Csv -Path $csvPath -Encoding UTF8) if ($MappingName) { $rows = @($rows | Where-Object { $MappingName -contains $_.Name }) $unknown = @($MappingName | Where-Object { $rows.Name -notcontains $_ }) if ($unknown) { throw "No definition in $csvPath for: $($unknown -join ', ')" } } $result = [PSCustomObject]@{ TotalMappings = $rows.Count CreatedMappings = 0 UpdatedMappings = 0 ProvidersUpdated = 0 Mappings = @() Errors = @() } $existingByName = @{} foreach ($existing in (Get-AuthentikSeededObject -Type ScopeMappings -Connection $connection)) { $existingByName[[string]$existing.name] = $existing } $providerBySlug = @{} if (-not $SkipProvider) { foreach ($application in (Get-AuthentikSeededObject -Type Applications -Connection $connection)) { if ($application.provider) { $providerBySlug[[string]$application.slug] = [string]$application.provider } } } $mappings = [System.Collections.Generic.List[object]]::new() foreach ($row in $rows) { $name = '{0}{1}' -f $marker.Prefix, $row.Name.Replace('-', ' ') if (-not $PSCmdlet.ShouldProcess($name, 'Create Authentik scope mapping')) { continue } try { $body = @{ name = $name scope_name = $row.ScopeName description = $row.Description expression = $row.Expression.Replace('`n', "`n") } $mapping = $null if ($existingByName.ContainsKey($name)) { $mapping = Invoke-AuthentikRequest -Method PATCH -Path "/propertymappings/provider/scope/$($existingByName[$name].pk)/" -Body $body -Connection $connection $result.UpdatedMappings++ Write-Verbose "Updated scope mapping $name" } else { $mapping = Invoke-AuthentikRequest -Method POST -Path '/propertymappings/provider/scope/' -Body $body -Connection $connection $result.CreatedMappings++ Write-Verbose "Created scope mapping $name" } $attached = @() if (-not $SkipProvider) { foreach ($applicationKey in @($row.Applications -split ';' | Where-Object { $_ })) { $slug = '{0}-{1}' -f $marker.SlugPrefix, $applicationKey if (-not $providerBySlug.ContainsKey($slug)) { $message = "Scope mapping '$name' names application '$slug', which does not exist or has no provider. Skipped." $result.Errors += $message Write-Warning $message continue } # Only an OAuth2 provider has scope mappings. Reading it first keeps the # standard openid, email and profile scopes it was created with. $providerPk = $providerBySlug[$slug] $provider = $null try { $provider = Invoke-AuthentikRequest -Method GET -Path "/providers/oauth2/$providerPk/" -Connection $connection } catch { $message = "Scope mapping '$name' names application '$slug', whose provider is not OAuth2. Skipped." $result.Errors += $message Write-Warning $message continue } $current = @($provider.property_mappings | ForEach-Object { [string]$_ }) if ($current -notcontains [string]$mapping.pk) { $null = Invoke-AuthentikRequest -Method PATCH -Path "/providers/oauth2/$providerPk/" ` -Body @{ property_mappings = @($current + [string]$mapping.pk) } -Connection $connection $result.ProvidersUpdated++ } $attached += $slug } } $mappings.Add([PSCustomObject]@{ Id = [string]$mapping.pk Key = $row.Name Name = $name ScopeName = $row.ScopeName Applications = $attached }) } catch { $message = "Failed to create scope mapping '$name': $($_.Exception.Message)" $result.Errors += $message Write-Error $message } } $result.Mappings = $mappings.ToArray() Write-Verbose ("Scope mappings: $($result.CreatedMappings) created, $($result.UpdatedMappings) updated, " + "$($result.ProvidersUpdated) providers updated, $($result.Errors.Count) problems") if ($PassThru) { return $result } } |