Skip to content

Commit

Permalink
➕ ADD Find-PASSafe
Browse files Browse the repository at this point in the history
Adding contribution from [steveredden](https://github.com/steveredden).
- `Find-PASSafe`
  - Added version check - set to require 10.1 minimum (:question:)
  - Added Pester Tests for code coverage :100:
  - Updated Readme & Changelog
  - Added to exported functions
  • Loading branch information
pspete committed Jun 14, 2019
1 parent aceaac7 commit dc57013
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 35 deletions.
14 changes: 9 additions & 5 deletions CHANGELOG.md
Expand Up @@ -34,11 +34,15 @@ _2 years since first commit Anniversary Edition_

### Other Updates

- `New-PASSession`
- Added `OTP` Parameter
- Allows One Time Passcode to be provided, which is then sent with the password value.
- Tested with Duo RADIUS.
- Removed `$SecureMode` & `$AdditionalInfo` parameters.
- New Functions
- `Find-PASSafe` (Thanks (again) [steveredden](https://github.com/steveredden)!)
- List or search safes by name
- Updated Functions
- `New-PASSession`
- Added `OTP` Parameter
- Allows One Time Passcode to be provided, which is then sent with the password value.
- Tested with Duo RADIUS.
- Removed `$SecureMode` & `$AdditionalInfo` parameters.

## 2.6.17 (May 16th 2019)

Expand Down
8 changes: 5 additions & 3 deletions README.md
Expand Up @@ -164,9 +164,10 @@ requires version 9.8+).
[`Get-PASPSMRecordingProperty`][Get-PASPSMRecordingProperty] |**10.6** |Get property details from</br>a PSM Recording.
[`Export-PASPSMRecording`][Export-PASPSMRecording] |**10.6** |Save PSM Session Recording</br>to a file.
[`Request-PASAdHocAccess`][Request-PASAdHocAccess] |**10.6** |Enable request of temporary</br>administrative access to a</br>server.
[`Get-PASDirectoryMapping`][Get-PASDirectoryMapping] |**10.7** |Get details of configured</br>directory mappings.
[`Set-PASDirectoryMapping`][Set-PASDirectoryMapping] |**10.7** |Update a configured</br>directory mapping.
[`Remove-PASDirectory`][Remove-PASDirectory] |**10.7** |Delete a directory configuration.
[`Get-PASDirectoryMapping`][Get-PASDirectoryMapping] |**10.7** |Get details of configured</br>directory mappings.
[`Set-PASDirectoryMapping`][Set-PASDirectoryMapping] |**10.7** |Update a configured</br>directory mapping.
[`Remove-PASDirectory`][Remove-PASDirectory] |**10.7** |Delete a directory configuration.
[`Find-PASSafe`][Find-PASSafe] |**10.1** |List or Search Safes by name.

[New-PASSession]:/psPAS/Functions/Authentication/New-PASSession.ps1
[Close-PASSession]:/psPAS/Functions/Authentication/Close-PASSession.ps1
Expand Down Expand Up @@ -266,6 +267,7 @@ requires version 9.8+).
[Get-PASDirectoryMapping]:/psPAS/Functions/LDAPDirectories/Get-PASDirectoryMapping.ps1
[Set-PASDirectoryMapping]:/psPAS/Functions/LDAPDirectories/Set-PASDirectoryMapping.ps1
[Remove-PASDirectory]:/psPAS/Functions/LDAPDirectories/Remove-PASDirectory.ps1
[Find-PASSafe]:/psPAS/Functions/Safes/Find-PASSafe.ps1

## Installation

Expand Down
164 changes: 164 additions & 0 deletions Tests/Find-PASSafe.Tests.ps1
@@ -0,0 +1,164 @@
#Get Current Directory
$Here = Split-Path -Parent $MyInvocation.MyCommand.Path

#Get Function Name
$FunctionName = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -Replace ".Tests.ps1"

#Assume ModuleName from Repository Root folder
$ModuleName = Split-Path (Split-Path $Here -Parent) -Leaf

#Resolve Path to Module Directory
$ModulePath = Resolve-Path "$Here\..\$ModuleName"

#Define Path to Module Manifest
$ManifestPath = Join-Path "$ModulePath" "$ModuleName.psd1"

if ( -not (Get-Module -Name $ModuleName -All)) {

Import-Module -Name "$ManifestPath" -ArgumentList $true -Force -ErrorAction Stop

}

BeforeAll {

$Script:RequestBody = $null


}

AfterAll {

$Script:RequestBody = $null

}

Describe $FunctionName {

InModuleScope $ModuleName {

Context "Input" {

$Script:BaseURI = "https://SomeURL/SomeApp"
$Script:ExternalVersion = "0.0"
$Script:WebSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession

BeforeEach {

Mock Invoke-PASRestMethod -MockWith {
[PSCustomObject]@{"Prop1" = "Val1"; "Prop2" = "Val2" }
}

Find-PASSafe

}

It "sends request" {

Assert-MockCalled Invoke-PASRestMethod -Times 1 -Exactly -Scope It

}

It "sends request to expected endpoint" {

Assert-MockCalled Invoke-PASRestMethod -ParameterFilter {

$URI -eq "$($Script:BaseURI)/api/Safes?limit=25"

} -Times 1 -Exactly -Scope It

}

It "sends request with expected query" {

Assert-MockCalled Invoke-PASRestMethod -ParameterFilter {

Find-PASSafe -search SomeQuery
$URI -eq "$($Script:BaseURI)/api/Safes?limit=25&search=SomeQuery"

} -Times 1 -Exactly -Scope It

}

It "uses expected method" {

Assert-MockCalled Invoke-PASRestMethod -ParameterFilter { $Method -match 'GET' } -Times 1 -Exactly -Scope It

}

It "sends request with no body" {

Assert-MockCalled Invoke-PASRestMethod -ParameterFilter { $Body -eq $null } -Times 1 -Exactly -Scope It

}

It "throws error if version requirement not met" {
$Script:ExternalVersion = "1.0"
{ Find-PASSafe } | Should Throw
$Script:ExternalVersion = "0.0"
}

It "sends expected number of requests" {

Mock Invoke-PASRestMethod -MockWith {
[PSCustomObject]@{
"Total" = 100
"Safes" = [PSCustomObject]@{"Prop1" = "Val1"; "Prop2" = "Val2" }
}
}

Find-PASSafe

Assert-MockCalled Invoke-PASRestMethod -Times 5 -Exactly -Scope It

}



}

Context "Response Output" {

BeforeEach {

Mock Invoke-PASRestMethod -MockWith {
[PSCustomObject]@{
"Safes" = [PSCustomObject]@{"Prop1" = "Val1"; "Prop2" = "Val2" }
}
}

$response = Find-PASSafe

}

it "provides output" {

$response | Should not BeNullOrEmpty

}

It "has output with expected number of properties" {

($response | Get-Member -MemberType NoteProperty).length | Should Be 2

}

It "returns expected number of results" {

Mock Invoke-PASRestMethod -MockWith {
[PSCustomObject]@{
"Total" = 100
"Safes" = [PSCustomObject]@{"Prop1" = "Val1"; "Prop2" = "Val2" }
}
}

$response = Find-PASSafe

$response.count | Should be 4

}

}

}

}
63 changes: 37 additions & 26 deletions psPAS/Functions/Safes/Find-PASSafe.ps1
@@ -1,36 +1,42 @@
function Find-PASSafe {
<#
.SYNOPSIS
Returns safe list from the vault.
<#
.SYNOPSIS
Returns safe list from the vault.
.DESCRIPTION
Returns abbreviated details for all safes
.DESCRIPTION
Returns abbreviated details for all safes
.PARAMETER search
List of keywords, separated with a space.
.PARAMETER search
List of keywords, separated with a space.
.PARAMETER TimeoutSec
See Invoke-WebRequest
Specify a timeout value in seconds
.PARAMETER TimeoutSec
See Invoke-WebRequest
Specify a timeout value in seconds
.EXAMPLE
Find-PASSafe
Find-PASSafe -search "xyz abc"
.EXAMPLE
Find-PASSafe
.INPUTS
Returns details of all safes which the user has access to.
.OUTPUTS
.EXAMPLE
Find-PASSafe -search "xyz abc"
.NOTES
This API is largly undocumented, but appears to be available since V10
The documentation mentions no body parameters, but search/offset/limit/sort(NYI)/filter(NYI) seem to work
It returns results faster than the v9 API (invoked with Get-PASSafe) but has a vastly different return object
Recommended Use: Use this to search for safes many quickly, then use Get-PASSafe to get full details about individual accounts
Returns details of all matching safes which the user has access to.
.LINK
https://cyberarkdocu.azurewebsites.net/Product-Doc/OnlineHelp/PAS/Latest/en/Content/SDK/Safes%20Web%20Services%20-%20List%20Safes.htm
.INPUTS
#>
.OUTPUTS
.NOTES
This API is largely undocumented, but appears to be available since V10
The documentation mentions no body parameters, but search/offset/limit/sort(NYI)/filter(NYI) seem to work
It returns results faster than the v9 API (invoked with Get-PASSafe) but has a vastly different return object
Recommended Use: Use this to search for safes many quickly, then use Get-PASSafe to get full details about individual accounts
.LINK
https://cyberarkdocu.azurewebsites.net/Product-Doc/OnlineHelp/PAS/Latest/en/Content/SDK/Safes%20Web%20Services%20-%20List%20Safes.htm
#>
[CmdletBinding()]
param(
[parameter(
Expand All @@ -47,10 +53,14 @@ https://cyberarkdocu.azurewebsites.net/Product-Doc/OnlineHelp/PAS/Latest/en/Cont

)

BEGIN {}#begin
BEGIN {
$MinimumVersion = [System.Version]"10.1"
}#begin

PROCESS {

Assert-VersionRequirement -ExternalVersion $Script:ExternalVersion -RequiredVersion $MinimumVersion

#Create base URL for request
$URI = "$Script:BaseURI/api/Safes"
$SearchQuery = $null
Expand All @@ -68,14 +78,15 @@ https://cyberarkdocu.azurewebsites.net/Product-Doc/OnlineHelp/PAS/Latest/en/Cont
$Safes += $InitialResponse.Safes

For ( $Offset = $Limit ; $Offset -lt $Total ; $Offset += $Limit ) {
Write-Verbose "Getting next result set: ?limit=$Limit&OffSet=$Offset$searchQuery"

$Safes += (Invoke-PASRestMethod -Uri "$URI`?limit=$Limit&OffSet=$Offset$searchQuery" -Method GET -WebSession $Script:WebSession -TimeoutSec $TimeoutSec).Safes

}

$Safes

}#process

END {}#end
END { }#end

}
3 changes: 2 additions & 1 deletion psPAS/psPAS.psd1
Expand Up @@ -175,7 +175,8 @@
'Request-PASAdHocAccess',
'Get-PASDirectoryMapping',
'Remove-PASDirectory',
'Set-PASDirectoryMapping'
'Set-PASDirectoryMapping',
'Find-PASSafe'
)

AliasesToExport = @(
Expand Down

0 comments on commit dc57013

Please sign in to comment.