Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 153 additions & 5 deletions PSSailpoint/Configuration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ function Get-DefaultConfiguration {
$Configuration["Experimental"] = $false
}

if (!$Configuration.containsKey("ClientIdOverride")) {
$Configuration["ClientIdOverride"] = $null
}

if (!$Configuration.containsKey("ClientSecretOverride")) {
$Configuration["ClientSecretOverride"] = $null
}

Return $Configuration

}
Expand Down Expand Up @@ -130,6 +138,8 @@ function Set-DefaultConfiguration {
[string]$TokenUrl,
[string]$ClientId,
[string]$ClientSecret,
[string]$ClientIdOverride,
[string]$ClientSecretOverride,
[System.Nullable[Int32]]$MaximumRetryCount,
[System.Nullable[Int32]]$RetryIntervalSeconds,
[System.Nullable[Boolean]]$Experimental,
Expand Down Expand Up @@ -172,6 +182,14 @@ function Set-DefaultConfiguration {
$Script:Configuration['ClientSecret'] = $ClientSecret
}

If ($ClientIdOverride) {
$Script:Configuration['ClientIdOverride'] = $ClientIdOverride
}

If ($ClientSecretOverride) {
$Script:Configuration['ClientSecretOverride'] = $ClientSecretOverride
}

If ($RetryIntervalSeconds) {
$Script:Configuration['RetryIntervalSeconds'] = $RetryIntervalSeconds
}
Expand Down Expand Up @@ -200,14 +218,37 @@ function Set-DefaultConfiguration {
}

function Get-IDNAccessToken {
[CmdletBinding()]
Param(
[string]$ClientId,
[string]$ClientSecret
)

Write-Debug "Getting Access Token"

if ($null -eq $Script:Configuration["ClientId"] -or $null -eq $Script:Configuration["ClientSecret"] -or $null -eq $Script:Configuration["TokenUrl"]) {
# Priority: 1. Function parameters, 2. Override configuration, 3. Default configuration
$effectiveClientId = if ($ClientId) {
$ClientId
} elseif ($Script:Configuration["ClientIdOverride"]) {
$Script:Configuration["ClientIdOverride"]
} else {
$Script:Configuration["ClientId"]
}

$effectiveClientSecret = if ($ClientSecret) {
$ClientSecret
} elseif ($Script:Configuration["ClientSecretOverride"]) {
$Script:Configuration["ClientSecretOverride"]
} else {
$Script:Configuration["ClientSecret"]
}

if ($null -eq $effectiveClientId -or $null -eq $effectiveClientSecret -or $null -eq $Script:Configuration["TokenUrl"]) {
throw "ClientId, ClientSecret or TokenUrl Missing. Please provide values in the environment or in ~/.sailpoint/config.yaml"
} else {
Write-Debug $Script:Configuration["TokenUrl"]
Write-Debug $Script:Configuration["ClientId"]
Write-Debug $Script:Configuration["ClientSecret"]
Write-Debug $effectiveClientId
Write-Debug $effectiveClientSecret

$multipartContent = [System.Net.Http.MultipartFormDataContent]::new()

Expand All @@ -221,13 +262,13 @@ function Get-IDNAccessToken {
#set client id formdata value
$stringHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
$stringHeader.Name = "client_id"
$stringContent = [System.Net.Http.StringContent]::new([string]$Script:Configuration["ClientId"])
$stringContent = [System.Net.Http.StringContent]::new([string]$effectiveClientId)
$stringContent.Headers.ContentDisposition = $stringHeader
$multipartContent.Add($stringContent)
#set client secret formdata value
$stringHeader = [System.Net.Http.Headers.ContentDispositionHeaderValue]::new("form-data")
$stringHeader.Name = "client_secret"
$stringContent = [System.Net.Http.StringContent]::new([string]$Script:Configuration["ClientSecret"])
$stringContent = [System.Net.Http.StringContent]::new([string]$effectiveClientSecret)
$stringContent.Headers.ContentDisposition = $stringHeader
$multipartContent.Add($stringContent)

Expand Down Expand Up @@ -323,3 +364,110 @@ function Get-Config {

return $Configuration
}

<#
.SYNOPSIS

Set Client ID and Client Secret overrides for all API endpoints

.DESCRIPTION

This function sets client ID and secret overrides that will be used for all API calls instead of the default configured values.
These overrides take precedence over environment variables and config file settings.
To clear the overrides, call this function with empty strings or use Clear-ClientCredentialOverride.

.PARAMETER ClientId
The Client ID to use for authentication

.PARAMETER ClientSecret
The Client Secret to use for authentication

.EXAMPLE
Set-ClientCredentialOverride -ClientId "myClientId" -ClientSecret "myClientSecret"

.EXAMPLE
# Clear overrides
Set-ClientCredentialOverride -ClientId "" -ClientSecret ""

#>
function Set-ClientCredentialOverride {
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[string]$ClientId,
[Parameter(Mandatory = $true)]
[string]$ClientSecret
)

Process {
if([string]::IsNullOrEmpty($ClientId) -or [string]::IsNullOrEmpty($ClientSecret)) {
$Script:Configuration["ClientIdOverride"] = $null
$Script:Configuration["ClientSecretOverride"] = $null
Write-Verbose "Client credential overrides cleared"
} else {
$Script:Configuration["ClientIdOverride"] = $ClientId
$Script:Configuration["ClientSecretOverride"] = $ClientSecret
Write-Verbose "Client credential overrides set"
}
}
}

<#
.SYNOPSIS

Clear Client ID and Client Secret overrides

.DESCRIPTION

This function clears any client ID and secret overrides that were set using Set-ClientCredentialOverride.
After calling this function, the SDK will revert to using the default configured credentials.

.EXAMPLE
Clear-ClientCredentialOverride

#>
function Clear-ClientCredentialOverride {
[CmdletBinding()]
Param()

Process {
$Script:Configuration["ClientIdOverride"] = $null
$Script:Configuration["ClientSecretOverride"] = $null
Write-Verbose "Client credential overrides cleared"
}
}

<#
.SYNOPSIS

Get the current Client ID and Client Secret override status

.DESCRIPTION

This function returns whether client credential overrides are currently set and which client ID is being used.

.EXAMPLE
Get-ClientCredentialOverride

.OUTPUTS
PSCustomObject with IsOverrideSet and ClientId properties

#>
function Get-ClientCredentialOverride {
[CmdletBinding()]
Param()

Process {
$isOverrideSet = -not [string]::IsNullOrEmpty($Script:Configuration["ClientIdOverride"])
$clientId = if ($isOverrideSet) {
$Script:Configuration["ClientIdOverride"]
} else {
$null
}

return [PSCustomObject]@{
IsOverrideSet = $isOverrideSet
ClientId = $clientId
}
}
}
3 changes: 2 additions & 1 deletion PSSailpoint/PSSailpoint.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ RequiredModules = @(@{ModuleName = 'PSSailpoint.Beta'; RequiredVersion = '1.6.6'
FunctionsToExport = 'Get-FunctionsToExport', 'Get-DefaultConfiguration',
'Set-DefaultConfiguration', 'Get-IDNAccessToken', 'Get-EnvConfig',
'Get-LocalConfig', 'Get-Config', 'Invoke-Paginate',
'Invoke-PaginateSearch'
'Invoke-PaginateSearch', 'Set-ClientCredentialOverride',
'Get-ClientCredentialOverride', 'Clear-ClientCredentialOverride'

# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @()
Expand Down
107 changes: 107 additions & 0 deletions example/clientOverride.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Example: Client Credential Override Demonstration
# This example shows various ways to use client credential overrides in the PowerShell SDK

# Import the module (if not already imported)
# Import-Module PSSailpoint -Force

Write-Host "=== SailPoint PowerShell SDK - Client Credential Override Demo ===" -ForegroundColor Cyan

# Scenario 1: Temporary credential override for specific operations
Write-Host "`nScenario 1: Using override credentials for a specific task" -ForegroundColor Yellow

# Save current configuration state
$originalStatus = Get-ClientCredentialOverride
Write-Host "Original override status: $($originalStatus.IsOverrideSet)"

# Set override credentials (replace with actual credentials)
Set-ClientCredentialOverride -ClientId "temp-client-id" -ClientSecret "temp-client-secret"
Write-Host "Override credentials set"

try {
# Perform operations with override credentials
Write-Host "Fetching sources with override credentials..."
$sources = Get-Sources -Limit 5
Write-Host "Successfully retrieved $($sources.Count) sources"
} catch {
Write-Host "Error with override credentials: $_" -ForegroundColor Red
}

# Clear overrides
Clear-ClientCredentialOverride
Write-Host "Override credentials cleared"

# Scenario 2: Switching between multiple environments
Write-Host "`nScenario 2: Switching between environments" -ForegroundColor Yellow

# Production environment
Write-Host "Switching to production environment..."
Set-ClientCredentialOverride -ClientId "prod-client-id" -ClientSecret "prod-client-secret"
$status = Get-ClientCredentialOverride
Write-Host "Active Client ID: $($status.ClientId)"

# Perform production operations
# ... API calls here ...

# Development environment
Write-Host "`nSwitching to development environment..."
Set-ClientCredentialOverride -ClientId "dev-client-id" -ClientSecret "dev-client-secret"
$status = Get-ClientCredentialOverride
Write-Host "Active Client ID: $($status.ClientId)"

# Perform development operations
# ... API calls here ...

# Scenario 3: Using with pagination
Write-Host "`nScenario 3: Paginated search with override credentials" -ForegroundColor Yellow

$searchJson = @"
{
"indices": ["identities"],
"query": {
"query": "attributes.department:Engineering",
"fields": ["name", "email"]
},
"sort": ["name"]
}
"@

$search = ConvertFrom-JsonToSearch -Json $searchJson

try {
Write-Host "Performing paginated search with override credentials..."
$results = Invoke-PaginateSearch -Increment 50 -Limit 200 -Search $search
Write-Host "Retrieved $($results.Count) identities from Engineering department"
} catch {
Write-Host "Search error: $_" -ForegroundColor Red
}

# Scenario 4: Error handling and fallback
Write-Host "`nScenario 4: Error handling with credential override" -ForegroundColor Yellow

# Try with potentially invalid override credentials
Set-ClientCredentialOverride -ClientId "invalid-client" -ClientSecret "invalid-secret"

try {
$accounts = Get-Accounts -Limit 1
} catch {
Write-Host "Failed with override credentials: $_" -ForegroundColor Red

# Clear overrides and fall back to default
Write-Host "Falling back to default credentials..."
Clear-ClientCredentialOverride

try {
$accounts = Get-Accounts -Limit 1
Write-Host "Successfully retrieved accounts with default credentials" -ForegroundColor Green
} catch {
Write-Host "Also failed with default credentials: $_" -ForegroundColor Red
}
}

# Final cleanup
Clear-ClientCredentialOverride
Write-Host "`nDemo completed. All credential overrides have been cleared." -ForegroundColor Cyan

# Display final status
$finalStatus = Get-ClientCredentialOverride
Write-Host "Final override status: $($finalStatus.IsOverrideSet)"