Private/Invoke-RBACRestRequest.ps1
|
function Invoke-RBACRestRequest { <# .SYNOPSIS Issues an authenticated REST request for the data-plane providers. .DESCRIPTION Internal. Fabric and Purview have no PowerShell RBAC cmdlets comparable to Az.Resources, so their providers call REST directly. This helper acquires a bearer token for the target resource from the probe context and performs the call, returning a normalized result that distinguishes success, authorization failure (403/401), and other errors - without throwing on auth failures, which the providers interpret as "caller lacks the role". .PARAMETER Context PSAutoRBAC.Context providing GetAccessToken. .PARAMETER ResourceUrl The token audience / resource URL (e.g. 'https://api.fabric.microsoft.com'). .PARAMETER Uri The full request URI. .PARAMETER Method HTTP method (default GET). .PARAMETER Body Optional request body object (serialized to JSON). .OUTPUTS PSCustomObject: Success [bool], StatusCode [int], IsAuthorizationError [bool], Content [object], Message [string]. #> [CmdletBinding()] [OutputType([psobject])] param( [Parameter(Mandatory)] [psobject]$Context, [Parameter(Mandatory)] [string]$ResourceUrl, [Parameter(Mandatory)] [string]$Uri, [Parameter()] [ValidateSet('GET', 'POST', 'PUT', 'PATCH', 'DELETE')] [string]$Method = 'GET', [Parameter()] [object]$Body ) Write-PSFMessage -Level Verbose -Message "REST $Method $Uri" -Tag 'PSAutoRBAC', 'Rest' try { $token = & $Context.GetAccessToken $ResourceUrl } catch { Write-PSFMessage -Level Warning -Message "Token acquisition for '$ResourceUrl' failed: $($_.Exception.Message)" -Tag 'PSAutoRBAC', 'Rest' return [pscustomobject]@{ PSTypeName = 'PSAutoRBAC.RestResult'; Success = $false; StatusCode = 0 IsAuthorizationError = $false; Content = $null; Message = "Token acquisition failed: $($_.Exception.Message)" } } $params = @{ Uri = $Uri Method = $Method Headers = @{ Authorization = "Bearer $token"; Accept = 'application/json' } ErrorAction = 'Stop' } if ($PSBoundParameters.ContainsKey('Body') -and $null -ne $Body) { $params['Body'] = ($Body | ConvertTo-Json -Depth 20) $params['ContentType'] = 'application/json' } try { $response = Invoke-RestMethod @params Write-PSFMessage -Level Debug -Message "REST $Method $Uri succeeded." -Tag 'PSAutoRBAC', 'Rest' return [pscustomobject]@{ PSTypeName = 'PSAutoRBAC.RestResult'; Success = $true; StatusCode = 200 IsAuthorizationError = $false; Content = $response; Message = '' } } catch { $status = 0 $resp = $null if ($_.Exception.PSObject.Properties.Name -contains 'Response') { $resp = $_.Exception.Response } if ($resp -and ($resp.PSObject.Properties.Name -contains 'StatusCode')) { try { $status = [int]$resp.StatusCode } catch { $status = 0 } } $isAuth = ($status -in 401, 403) -or ($_.Exception.Message -match 'Unauthorized|Forbidden|InsufficientPrivileges|PrincipalDoesNotHaveRequiredPermissions') $level = if ($isAuth) { 'Verbose' } else { 'Warning' } Write-PSFMessage -Level $level -Message "REST $Method $Uri failed (status $status, authError=$isAuth): $($_.Exception.Message)" -Tag 'PSAutoRBAC', 'Rest' return [pscustomobject]@{ PSTypeName = 'PSAutoRBAC.RestResult'; Success = $false; StatusCode = $status IsAuthorizationError = [bool]$isAuth; Content = $null; Message = $_.Exception.Message } } } |