Private/Invoke-NSPFortinetSupportApi.ps1
|
function Invoke-NSPFortinetSupportApi { # One call to the support portal's JSON API (https://support.fortinet.com/app/...), with the # token Connect-NSPFortinetSupport stored. Returns the response's 'result'. The portal answers # every call with { status: { returnCode, message }, result }; returnCode 1 is success. # # The token lasts 30 minutes. When the session came from the browser, a token close to expiry # (or one the portal refuses) is renewed from the still-open browser window first. [CmdletBinding()] param( [Parameter(Mandatory)][string]$Path, [hashtable]$Body, [ValidateSet('Get', 'Post')][string]$Method = 'Post' ) $session = $script:NSPFortinetSupportSession if (-not $session) { throw 'Not connected to the Fortinet support portal. Run Connect-NSPFortinetSupport first.' } $renew = { if (-not $session.Port) { throw 'The Fortinet support portal token has expired (they last 30 minutes). Copy a fresh request and run Connect-NSPFortinetSupport -FromClipboard again.' } Write-Verbose 'Renewing the Fortinet support portal token from the browser.' $fresh = Get-NSPFortinetBrowserToken -Port $session.Port $session.Token = $fresh.Token $session.Expires = $fresh.Expires } if ($session.Expires -lt (Get-Date).AddMinutes(3)) { & $renew } for ($attempt = 1; $attempt -le 2; $attempt++) { $params = @{ Uri = "https://support.fortinet.com/app/$Path"; Method = $Method; UserAgent = $session.UserAgent; UseBasicParsing = $true; ErrorAction = 'Stop' Headers = @{ Authorization = $session.Token; Origin = 'https://support.fortinet.com'; Referer = 'https://support.fortinet.com/support/' } } if ($Method -eq 'Post') { $params.ContentType = 'application/json' $params.Body = if ($Body) { $Body | ConvertTo-Json -Compress } else { '{}' } } try { $response = Invoke-RestMethod @params break } catch { $status = $null if ($_.Exception.PSObject.Properties['Response'] -and $_.Exception.Response) { $status = [int]$_.Exception.Response.StatusCode } if ($status -ne 401 -or $attempt -eq 2) { if ($status -in 401, 403) { throw 'The Fortinet support portal refused the session. Run Connect-NSPFortinetSupport again.' } throw } & $renew } } if ($null -eq $response -or $response -is [string] -or -not $response.PSObject.Properties['status']) { throw 'The Fortinet support portal did not return API data, so the session has probably ended. Run Connect-NSPFortinetSupport again.' } if ($response.status.returnCode -ne 1) { throw "Fortinet support portal: $($response.status.message) (returnCode $($response.status.returnCode), $Path)." } $result = $response.result if ($result -and $result.PSObject.Properties['isValid'] -and -not $result.isValid) { throw "Fortinet support portal: $($result.message) ($Path)." } $result } |