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
72 changes: 63 additions & 9 deletions CredentialRetriever/Functions/Get-CCPCredential.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@

Use at your own risk.

.PARAMETER UsePostMethod
Uses POST method instead of GET method for the request.
Authentication details will be sent in the request body instead of the URL.
Requires CyberArk Central Credential Provider version 14.2 or later.

.EXAMPLE
Get-CCPCredential -AppID PSScript -Safe PSAccounts -Object PSPlatform-AccountName -URL https://cyberark.yourcompany.com

Expand All @@ -89,6 +94,12 @@
Uses the PowerShell App ID to search for and retrieve the password for the svc-psProvision account in the PSAccounts safe
from the https://cyberark-dev.yourcompany.com/DevAIM CCP Web Service.

.EXAMPLE
Get-CCPCredential -AppID PowerShell -Safe PSAccounts -UserName svc-psProvision -WebServiceName DevAIM -UsePostMethod -URL https://cyberark-dev.yourcompany.com

Uses the PowerShell App ID to search for and retrieve the password for the svc-psProvision account in the PSAccounts safe
from the https://cyberark-dev.yourcompany.com/DevAIM CCP Web Service using POST method.

.EXAMPLE
$result = Get-CCPCredential -AppID PS -Safe PS -Object PSP-AccountName -URL https://cyberark.yourcompany.com

Expand Down Expand Up @@ -337,15 +348,30 @@
ValueFromPipelinebyPropertyName = $true,
ParameterSetName = 'Query'
)]
[switch]$SkipCertificateCheck
[switch]
$SkipCertificateCheck,

# Use POST method for request to CCP
[Parameter(
Mandatory = $false,
ValueFromPipelineByPropertyName = $false,
ParameterSetName = 'Default'
)]
[Parameter(
Mandatory = $false,
ValueFromPipelineByPropertyName = $false,
ParameterSetName = 'Query'
)]
[switch]
$UsePostMethod
)

Begin {

#Collection of parameters which are to be excluded from the request URL
[array]$CommonParameters += [System.Management.Automation.PSCmdlet]::CommonParameters
[array]$CommonParameters += [System.Management.Automation.PSCmdlet]::OptionalCommonParameters
[array]$CommonParameters += 'URL', 'WebServiceName', 'Credential', 'UseDefaultCredentials', 'CertificateThumbPrint', 'Certificate', 'SkipCertificateCheck'
[array]$CommonParameters += 'URL', 'WebServiceName', 'Credential', 'UseDefaultCredentials', 'CertificateThumbPrint', 'Certificate', 'SkipCertificateCheck', 'UsePostMethod'

#If Tls12 Security Protocol is available
if (([Net.SecurityProtocolType].GetEnumNames() -contains 'Tls12') -and
Expand All @@ -367,7 +393,17 @@

'Query' {

$QueryString = $Query
if ($UsePostMethod) {
# Build JSON body from query string for POST method (simplified)
$PostBody = @{}
foreach ($pair in $Query -split '&') {
$key,$value = $pair -split '=',2
if ($key) { $PostBody[$key] = [System.Uri]::UnescapeDataString($value) }
}
$PostBody = $PostBody | ConvertTo-Json
} else {
$QueryString = $Query
}

break

Expand All @@ -384,24 +420,42 @@

}

#Format URL query string
$QueryString = $QueryArgs -join '&'
if ($UsePostMethod) {
#For POST method, parameters go in body as JSON, URL has no query string
$PostBodyObject = @{}
$PSBoundParameters.keys | Where-Object { $CommonParameters -notcontains $_ } | ForEach-Object {
$PostBodyObject[$_] = $PSBoundParameters[$_]
}
$PostBody = $PostBodyObject | ConvertTo-Json
} else {
#For GET method, parameters go in URL query string
$QueryString = $QueryArgs -join '&'
}

}

}

#Create hashtable of request parameters
$URI = "$URL/$WebServiceName/api/Accounts"
if (-not $UsePostMethod -and $QueryString) {
$URI += "?$QueryString"
}

$Request = @{
'URI' = "$URL/$WebServiceName/api/Accounts?$QueryString"
'Method' = 'GET'
'URI' = $URI
'Method' = if ($UsePostMethod) { 'POST' } else { 'GET' }
'ContentType' = 'application/json'
'ErrorAction' = 'Stop'
'ErrorVariable' = 'RequestError'
'UseBasicParsing' = $true
}

#Add authentication parameters to request
# Add body for POST requests
if ($UsePostMethod) {
$Request['Body'] = $PostBody
}

# Add authentication parameters to request
Switch ($($PSBoundParameters.keys)) {
{ $PSItem -contains 'Credential' } { $Request['Credential'] = $Credential }
{ $PSItem -contains 'UseDefaultCredentials' } { $Request['UseDefaultCredentials'] = $true }
Expand Down
14 changes: 14 additions & 0 deletions tests/Get-CCPCredential.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,20 @@ InModuleScope $ModuleName {
($result.ToCredential()).GetNetworkCredential().Password | Should Be 'SomePassword'
}

It 'sends POST request when UsePostMethod is specified' {
$InputObj | Get-CCPCredential -UsePostMethod
Assert-MockCalled Invoke-RestMethod -ParameterFilter {
$Method -eq 'POST'
} -Times 1 -Exactly -Scope It
}

It 'converts Query parameter to JSON for POST request' {
Get-CCPCredential -Query 'AppID=PS&Object=PSP-AccountName&Safe=PS' -URL 'https://SomeURL' -UsePostMethod
Assert-MockCalled Invoke-RestMethod -ParameterFilter {
$Method -eq 'POST' -and $Body -like '*AppID*'
} -Times 1 -Exactly -Scope It
}

}

}