Public/Connect-Inforcer.ps1
|
<# .SYNOPSIS Establishes a secure connection to the Inforcer REST API. .DESCRIPTION Creates an authenticated session using an API key. You can specify -Region (uk, eu, us, anz) or -BaseUrl for custom endpoints. The API key is stored as a SecureString. Before returning Connected, a minimal API call validates the key; if it fails (e.g. wrong key for the endpoint), the connection is not established and an error is returned. .PARAMETER ApiKey The Inforcer API key. Can be SecureString or String (converted to SecureString). .PARAMETER Region Region for production API. Valid: uk, eu, us, anz. Default: uk. Ignored when -BaseUrl is set. .PARAMETER BaseUrl Optional custom base URL. When set, -Region is ignored. .EXAMPLE Connect-Inforcer -ApiKey "your-api-key" -Region uk .EXAMPLE $key = Read-Host -AsSecureString -Prompt "API Key"; Connect-Inforcer -ApiKey $key -Region uk .EXAMPLE Connect-Inforcer -ApiKey $key -BaseUrl "https://api.example.com/api" Connects using a custom base URL (use your actual API base URL in place of the example). .OUTPUTS PSObject with Status, Region, BaseUrl, ConnectedAt. .LINK Disconnect-Inforcer .LINK Get-InforcerTenant #> function Connect-Inforcer { [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Justification = 'Intentional convenience: users may pass a plain-text API key which is converted to SecureString for storage.')] [CmdletBinding(SupportsShouldProcess = $true)] [OutputType([PSObject])] param( [Parameter(Mandatory = $true, Position = 0)] [Alias('Key')] [object]$ApiKey, [Parameter(Mandatory = $false, Position = 1)] [ValidateSet('anz', 'eu', 'uk', 'us', IgnoreCase = $true)] [string]$Region = 'uk', [Parameter(Mandatory = $false)] [string]$BaseUrl ) $rawApiKey = $ApiKey while ($rawApiKey -is [PSObject] -and $rawApiKey.BaseObject) { $rawApiKey = $rawApiKey.BaseObject } $secureApiKey = $null if ($rawApiKey -is [System.Security.SecureString]) { $secureApiKey = $rawApiKey } elseif ($rawApiKey -is [string]) { $secureApiKey = ConvertTo-SecureString -String $rawApiKey -AsPlainText -Force } else { Write-Error -Message "ApiKey must be a String or SecureString. Received: $($rawApiKey.GetType().Name)" ` -ErrorId 'InvalidApiKeyType' -Category InvalidArgument return } $plain = ConvertFrom-InforcerSecureString -SecureString $secureApiKey if ([string]::IsNullOrWhiteSpace($plain)) { Write-Error -Message 'API key cannot be empty.' -ErrorId 'EmptyApiKey' -Category InvalidArgument return } try { $baseUrlValue = Get-InforcerBaseUrl -Region $Region -BaseUrl $BaseUrl } catch { Write-Error -Message $_.Exception.Message -ErrorId 'InvalidRegion' -Category InvalidArgument return } if (!$PSCmdlet.ShouldProcess('Inforcer session', 'Connect')) { return } # Validate the API key with a minimal request before reporting Connected $validateUri = $baseUrlValue.TrimEnd('/') + '/beta/baselines' $validateHeaders = @{ 'Inf-Api-Key' = $plain 'Accept' = 'application/json' } try { $null = Invoke-RestMethod -Uri $validateUri -Method GET -Headers $validateHeaders -UseBasicParsing } catch [System.Net.WebException] { $statusCode = 0 if ($_.Exception.Response) { $statusCode = [int]$_.Exception.Response.StatusCode } $msg = $_.Exception.Message if ($statusCode -eq 401) { $msg = 'Connection failed: the API key is invalid for this endpoint.' } else { $msg = "Connection validation failed (HTTP $statusCode): $msg" } Write-Error -Message $msg -ErrorId 'ConnectionValidationFailed' -Category AuthenticationError return } catch { Write-Error -Message "Connection validation failed: $($_.Exception.Message)" -ErrorId 'ConnectionValidationFailed' -Category AuthenticationError return } $script:InforcerSession = @{ ApiKey = $secureApiKey BaseUrl = $baseUrlValue Region = $Region ConnectedAt = Get-Date } Write-Verbose "Successfully connected to Inforcer API at $baseUrlValue" $out = [PSCustomObject]@{ Status = 'Connected' Region = $Region BaseUrl = $baseUrlValue ConnectedAt = $script:InforcerSession.ConnectedAt } $out } |