Private/Get-ConnectorConfiguration.ps1

<#
.SYNOPSIS
Helper functions for building SuccessFactors ConnectorConfiguration objects.

.DESCRIPTION
This file contains helper functions intended for local testing and troubleshooting.
It simplifies creation of ConnectorConfiguration objects for both Assertion and
ClientCredentials authentication flows.

These functions are convenience helpers and are not part of the core connector's
normal runtime path.

.NOTES
Helper utilities only. Treat as private tooling.
#>


<#
.SYNOPSIS
Converts a SecureString to plain text.

.DESCRIPTION
Used by helper configuration creation for scenarios where client secret must be
stored as plain text in a temporary in-memory configuration object.

.PARAMETER SecureString
SecureString value to convert.

.OUTPUTS
System.String

.NOTES
Internal helper function for New-SFConnectorConfiguration.
#>

function ConvertTo-PlainText {
    param(
        [Parameter(Mandatory = $true)]
        [Security.SecureString]$SecureString
    )

    $bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString)
    try {
        return [Runtime.InteropServices.Marshal]::PtrToStringBSTR($bstr)
    }
    finally {
        [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
    }
}

<#
.SYNOPSIS
Reads private key content from a PEM file.

.DESCRIPTION
Reads PEM content as raw text or, when -BodyOnly is used, strips PEM header/footer
lines and returns only the base64 body as a single line.

.PARAMETER PemPath
Path to the private key PEM file.

.PARAMETER BodyOnly
Return only body content between BEGIN/END markers.

.OUTPUTS
System.String

.NOTES
Internal helper function for New-SFConnectorConfiguration.
#>

function Get-PrivateKeyContent {
    param(
        [Parameter(Mandatory = $true)]
        [string]$PemPath,

        [Parameter(Mandatory = $false)]
        [switch]$BodyOnly
    )

    $pemRaw = (Get-Content -Raw -Path $PemPath).Replace("`r", "").Trim()

    if (-not $BodyOnly) {
        return $pemRaw
    }

    # Return only payload between BEGIN/END lines as one single line
    $body = (Get-Content -Path $PemPath | Where-Object { $_ -notmatch "-----BEGIN|-----END" }) -join ""
    return $body.Trim()
}

<#
.SYNOPSIS
Creates a SuccessFactors ConnectorConfiguration helper object.

.DESCRIPTION
Builds a hashtable in the structure expected by Connect-SF. Supports both Assertion
and ClientCredentials authentication flows through parameter sets.

This function is intended as a helper utility to speed up local testing and
configuration setup.

.PARAMETER BaseUrl
SuccessFactors tenant base URL.

.PARAMETER ClientId
OAuth client id.

.PARAMETER CompanyId
SuccessFactors company id.

.PARAMETER UserId
SuccessFactors user id for Assertion flow.

.PARAMETER PrivateKeyPath
Path to private key PEM file for Assertion flow.

.PARAMETER PrivateKeyBodyOnly
For Assertion flow, strips PEM header/footer and returns body only.

.PARAMETER ClientSecret
Client secret for ClientCredentials flow.

.OUTPUTS
System.Collections.Hashtable

.EXAMPLE
$config = New-SFConnectorConfiguration -BaseUrl 'https://api55preview.sapsf.eu' -ClientId '...' -CompanyId '...' -UserId 'api_42IU' -PrivateKeyPath '~/sf-private.pem' -PrivateKeyBodyOnly

.EXAMPLE
$secret = Read-Host 'Client secret' -AsSecureString
$config = New-SFConnectorConfiguration -BaseUrl 'https://api55preview.sapsf.eu' -ClientId '...' -CompanyId '...' -ClientSecret $secret

.NOTES
Helper utility function. The returned object is intended for Connect-SF and test scripts.
#>

function New-SFConnectorConfiguration {
    [CmdletBinding(DefaultParameterSetName = "Assertion")]
    param(
        [Parameter(Mandatory = $true)]
        [string]$BaseUrl,

        [Parameter(Mandatory = $true)]
        [string]$ClientId,

        [Parameter(Mandatory = $true)]
        [string]$CompanyId,

        [Parameter(Mandatory = $true, ParameterSetName = "Assertion")]
        [string]$UserId,

        [Parameter(Mandatory = $true, ParameterSetName = "Assertion")]
        [string]$PrivateKeyPath,

        [Parameter(Mandatory = $false, ParameterSetName = "Assertion")]
        [switch]$PrivateKeyBodyOnly,

        [Parameter(Mandatory = $true, ParameterSetName = "ClientCredentials")]
        [Security.SecureString]$ClientSecret
    )

    $baseUrlNormalized = $BaseUrl.TrimEnd("/")

    $config = @{
        configuration = @{
            baseurl   = $baseUrlNormalized
            clientid  = $ClientId
            companyid = $CompanyId
        }
        secrets = @{}
    }

    if ($PSCmdlet.ParameterSetName -eq "Assertion") {
        $config.configuration.authflow = "Assertion"
        $config.configuration.userid = $UserId
        $config.secrets.privatekey = Get-PrivateKeyContent -PemPath $PrivateKeyPath -BodyOnly:$PrivateKeyBodyOnly
    }
    else {
        $config.configuration.authflow = "ClientCredentials"
        $config.secrets.clientsecret = ConvertTo-PlainText -SecureString $ClientSecret
    }

    return $config
}