Private/Get-iPilotOAuthToken.ps1

Function Get-iPilotOAuthToken {
    <#
        .Synopsis
        Returns iPilot OAuth token.

        .Description
        Helper function for iPilot module to retrieve OAuth access token.

        .Parameter iPilotAuthUri
        URL of iPilot API

        .Parameter APIVersion
        Version of iPilot API

        .Parameter APIKey
        iPilot API Key

        .Parameter Instance
        iPilot Synthesis Instance
        Note: Instance is mandatory in iPilot module v1.1.0

        .Parameter Credential
        Credentials for iPilot API

        .Example
        # Get the OAuth Token for a given set of credentials
        Get-iPilotOAuthToken -Credential (Get-Credential)
    #>

    Param (
        [System.String] [Parameter(Mandatory = $false)]
            $ApiUrl = $global:IP_ApiUrl,   
        [System.String] [Parameter(Mandatory = $false)]
            $ApiVersion = "v1",
        [System.String] [Parameter(Mandatory = $true)] 
            $ApiKey,    
        [System.String] [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()]
            $Instance = $(throw "Instance is mandatory in iPilot module v1.1.0, please provide your iPilot Instance Name."),  
        [System.Management.Automation.PSCredential] [Parameter(Mandatory = $true)] 
            $Credential,
        [Switch]
            $RefreshToken
    )

    # Force refresh OAuth Token
    if ($RefreshToken.IsPresent) {
        $iPilotOAuthToken = $null
    }

    # Verbose Switch
    if($Verbose.IsPresent) {
        $PreviousVerbosePreference = $VerbosePreference
        $VerbosePreference = "continue"
    }

    #region Get OAuth Token
    $now = Get-Date
    if ($iPilotOAuthToken.OAuthTokenExpirationDateTime -ge ($now.ToUniversalTime()) -and $iPilotOAuthToken.Username -eq $Credential.UserName) {
        Write-Verbose "iPilot OAuth Token has not expired"
        return $iPilotOAuthToken
    } else {
        Write-Verbose "iPilot OAuth Token has expired or is not valid for $($Credential.UserName)"

        # Build request
        $iPilotAuthUri = "$ApiUrl/$ApiVersion/oauth2/authorize"
        Write-Verbose "iPilotAuthUri:$iPilotAuthUri"

        $Username = $Credential.UserName
        $Password = $Credential.GetNetworkCredential().Password

        $GetiPilotAuthInvokeParams = @{
            Uri = $iPilotAuthUri
            Method = "Post"
            ContentType = "application/x-www-form-urlencoded"
            Headers = @{
                "x-api-key"      = $ApiKey
            }
            Body = @{
                "username" = $Username
                "password" = $Password
            }
        }

        # If Instance is specified, add to OAuth body
        if ($global:IP_Instance) {
            $GetiPilotAuthInvokeParams.Body += @{
                "instance" = $global:IP_Instance
            }
            Write-Verbose "Adding instance ($($global:IP_Instance)) to GetiPilotAuthInvokeParams"
        }

        Write-Verbose "GetiPilotAuthInvokeParams:`n$($GetiPilotAuthInvokeParams | Out-String)"
        Write-Debug "GetiPilotAuthInvokeParams (JSON):`n$($GetiPilotAuthInvokeParams | ConvertTo-Json | Out-String)"

        # Make REST call to get OAuth Token
        Try {
            $global:IP_iPilotOAuthToken = Invoke-RestMethod @GetiPilotAuthInvokeParams -ErrorAction Stop
            $global:IP_iPilotOAuthToken = Invoke-WebRequest @GetiPilotAuthInvokeParams -SessionVariable iPilotWebSession | Select-Object -ExpandProperty Content | ConvertFrom-Json
            $global:IP_iPilotWebSession = $iPilotWebSession
            $global:IP_iPilotCookie = $iPilotWebSession.Cookies.GetCookies($iPilotAuthUri) | Where-Object {$_.Name -eq "PHPSESSID"}
            Write-Verbose "$global:IP_iPilotOAuthToken"
            $iPilotOAuthToken = $global:IP_iPilotOAuthToken
            if ($iPilotOAuthToken -eq "You are not authorize to perform this action.") {
                throw $iPilotOAuthToken
            }
            Write-Debug "iPilotCooke`n:$iPilotCookie"
        } Catch {
            Write-Error "Failed to authenticate $($Credential.UserName). Error: $($_)."
            break
        }

        # Verify OAuth Token has expiration date
        if (!($iPilotOAuthToken.expires_at)) {
            throw "Failed to get OAuth Token from $iPilotAuthUri using $($Credential.UserName). OAuth Token has no expiration date.`niPilotOAuthToken:`n$($iPilotOAuthToken | Out-String)"
        }

        # Format Expiration Date & Time
        $iPilotOAuthTokenExpirationDateTime = (Get-Date 1970/1/1).AddSeconds($iPilotOAuthToken.expires_at)

        # Append formatted expiration date
        $iPilotOAuthToken | Add-Member -MemberType NoteProperty -Name OAuthTokenExpirationDateTime -Value $iPilotOAuthTokenExpirationDateTime
        
        # Append username
        $iPilotOAuthToken | Add-Member -MemberType NoteProperty -Name Username -Value $Credential.UserName

        # Verbose Switch
        if($Verbose.IsPresent) {
            $VerbosePreference = $PreviousVerbosePreference
        }

        # Return token
        return $iPilotOAuthToken
    }
}