CCRestMethod.ps1


#
# Citrix API Rest Call (Support Export/Prepare/GetJob)
#


function DecodeBearerTokenPart([string]$part) {
    $reformattedPart = $part.Replace('-', '+').Replace('_', '/')
    if ($reformattedPart.Length % 4) {
        $paddedPart = $reformattedPart + ("=" * (4 - ($reformattedPart.Length % 4)))
    } else {
        $paddedPart = $reformattedPart
    }
    return [System.Text.Encoding]::ASCII.GetString([system.convert]::FromBase64String($paddedPart)) | ConvertFrom-Json
}

function DecodeBearerToken()
{
    if ($GLOBAL:XDAuthToken) {
        $token = ($GLOBAL:XDAuthToken -split '=')[1]
        $tokenParts = $token.Split(".")

        $tokenheader = DecodeBearerTokenPart $tokenParts[0]
        $tokenPayload = DecodeBearerTokenPart $tokenParts[1]

        $tokenPayload.customers = $tokenPayload.customers | ConvertFrom-Json

        return $tokenheader, $tokenPayload
    }

    return $null, $null
}

Function BuildUrl([string]$deployment, [string]$serviceRoute, [hashtable]$query) {
    if ($deployment) {
        if ($deployment.StartsWith('http://') -or $deployment.StartsWith('https://')) {
            $baseUrl = $deployment
        } else {
            $baseUrl = "https://$deployment/"
        }
    } else {
        $tokenheader, $tokenPayload = DecodeBearerToken
        if ($null -eq $tokenPayload) {
            throw "Not authenticated to Citrix Cloud."
        }
        $btGeo = $tokenPayload.customers[0].Geo
        $geo = $btGeo.ToLower().Replace('-', '')
        $baseUrl = "https://api.$geo.layering.cloud.com/"
        LogIt "geo $btGeo api url $baseUrl" $False
    }

    $queryParams = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
    $query.Keys | ForEach-Object {
        $queryParams.Add($_, $query[$_])
    }

    $url = [System.UriBuilder]$baseUrl
    $url.Path = $serviceRoute
    $url.Query = $queryParams.ToString()
    return $url.Uri
}

Function GetAuthHeaders([string]$customerId, [string]$secureClientId, [string]$secureSecret, [bool]$authenticated = $true, [string]$eeOverride = $null) {
    $headers = @{`
        'Citrix-CustomerId' = $customerId
        'Accept'            = 'application/json'
        'Content-Type'      = 'application/json;charset=utf-8'
    }
    if ($eeOverride) {
        $headers['Citrix-ExecutionEngine-Override'] = $eeOverride
    }
    if ($authenticated) {
        if ([string]::IsNullOrEmpty($GLOBAL:XDAuthToken)) {
            try {
                $null = AuthToCitrixCloud $CustomerId $SecureClientId $SecureSecret
            }
            catch {
                throw "Failed to get bearer token: $_"
            }
        }
        $headers['Authorization'] = $GLOBAL:XDAuthToken
    }
    return $headers
}

Function Invoke-CCRestMethod(
    [string]$method,
    [string]$deployment,
    [string]$serviceRoute,
    [string]$customerId,
    [string]$secureClientId,
    [string]$secureSecret,
    [hashtable]$query = @{},
    [psobject]$json = $null,
    [bool]$authenticated = $true
    ) {
    $url = BuildUrl $deployment $serviceRoute $query
    $headers = GetAuthHeaders -customerId $customerId -secureClientId $secureClientId -secureSecret $secureSecret -authenticated $authenticated
    $moduleInfo = Get-InstalledModule "Citrix.Workloads.Portability"
    $parameters = @{
        Headers = $headers
        Method = $method
        UserAgent = "Citrix.Workloads.Portability/$($moduleInfo.Version) Powershell/$($PSVersionTable.PSVersion)"
        Verbose = $Global:LogVerbose
    }
    if ($json) {
        $parameters['Body'] = $json
    }
    try {
        LogIt "REST $url $(Convert-HashToString $parameters)" $false
        return Invoke-RestMethod $url @parameters
    }
    catch {
        throw "$method REST method failed: $_"
    }
}