Skip to content

Commit

Permalink
Start-TssSecretChangePassword - closes #71
Browse files Browse the repository at this point in the history
added Get_TssSecretPasswordStatus
  • Loading branch information
wsmelton committed Mar 3, 2021
1 parent a97a8c5 commit 3f4e6a9
Show file tree
Hide file tree
Showing 10 changed files with 311 additions and 4 deletions.
17 changes: 17 additions & 0 deletions src/classes/secrets/TssSecretPasswordStatus.class.ps1
@@ -0,0 +1,17 @@
class TssSecretPasswordStatus {
[string]
[ValidateSet('None','Pending','Success','Fail')]
$Status

[datetime]
$LastRpcDate

[string]
$RpcMessage

[int]
$FailedAttempts

[datetime]
$NextRpcDate
}
35 changes: 35 additions & 0 deletions src/en-us/about_tsssecretpasswordstatus.help.txt
@@ -0,0 +1,35 @@
TOPIC
This help topic describes the TssSecretPasswordStatus class in the Thycotic.SecretServer module

CLASS
TssSecretPasswordStatus

INHERITANCE
None

DESCRIPTION
The TssSecretPasswordStatus class represents and object returned by an internal endpoint to Secret Server

CONSTRUCTORS
new()

PROPERTIES
Status
Status of password change (None, Pending, Success, Fail)

LastRpcDate
DateTime of last password change event

RpcMessage
Message from last password change event

FailedAttempts
Failed attempts based on password changing configuration for the Secret

NextRpcDate
DateTime of next RPC attempt based on password changing configuration for the Secret

METHODS

RELATED LINKS:
Get-TssSecretPasswordStatus
66 changes: 66 additions & 0 deletions src/functions/secrets/Get-SecretPasswordStatus.ps1
@@ -0,0 +1,66 @@
function Get-SecretPasswordStatus {
<#
.SYNOPSIS
Get status of password change
.DESCRIPTION
Get status of password change
.EXAMPLE
PS> $session = New-TssSession -SecretServer https://alpha -Credential $ssCred
PS> Get-TssSecretPasswordStatus -TssSession $session -Id 26
Get password change status of Secret ID 26
.NOTES
Requires TssSession object returned by New-TssSession
#>
[CmdletBinding()]
[OutputType('TssSecretPasswordStatus')]
param (
# TssSession object created by New-TssSession for auth
[Parameter(Mandatory,
ValueFromPipeline,
Position = 0)]
[TssSession]
$TssSession,

# Short description for parameter
[Parameter(Mandatory,ValueFromPipelineByPropertyName)]
[Alias("SecretId")]
[int[]]
$Id
)
begin {
$tssParams = $PSBoundParameters
$invokeParams = . $GetInvokeTssParams $TssSession
}

process {
Write-Verbose "Provided command parameters: $(. $GetInvocation $PSCmdlet.MyInvocation)"
if ($tssParams.ContainsKey('TssSession') -and $TssSession.IsValidSession()) {
. $CheckVersion $TssSession '10.9.000000' $PSCmdlet.MyInvocation
foreach ($secret in $Id) {
$restResponse = $null
$uri = $TssSession.ApiUrl.Replace('api/v1','internals'), 'secret-detail', $secret, 'password-status' -join '/'
$invokeParams.Uri = $uri
$invokeParams.Method = 'GET'

Write-Verbose "Performing the operation $($invokeParams.Method) $uri"
try {
$restResponse = Invoke-TssRestApi @invokeParams
} catch {
Write-Warning "Issue getting password status on Secret [$secret]"
$err = $_
. $ErrorHandling $err
}

if ($restResponse) {
. $TssSecretPasswordStatusObject $restResponse
}
}
} else {
Write-Warning "No valid session found"
}
}
}
101 changes: 101 additions & 0 deletions src/functions/secrets/Start-SecretChangePassword.ps1
@@ -0,0 +1,101 @@
function Start-SecretChangePassword {
<#
.SYNOPSIS
Start a current password change
.DESCRIPTION
Start a current password change
.EXAMPLE
$session = New-TssSession -SecretServer https://alpha -Credential $ssCred
Start-TssSecretChangePassword -TssSession $session -Id 46
Start a current password change operation on secret 46
.LINK
https://thycotic-ps.github.io/thycotic.secretserver/commands/Start-TssSecretChangePassword
.NOTES
Requires TssSession object returned by New-TssSession
#>
[CmdletBinding(SupportsShouldProcess)]
param (
# TssSession object created by New-TssSession for auth
[Parameter(Mandatory,
ValueFromPipeline,
Position = 0)]
[TssSession]$TssSession,

# Secret Id
[Parameter(Mandatory,ValueFromPipelineByPropertyName)]
[Alias("SecretId")]
[int[]]
$Id,

[Parameter(Mandatory)]
[ValidateSet('Manual','Random')]
[string]
$Type,

[securestring]
$NextPassword
)
begin {
$tssParams = $PSBoundParameters
$invokeParams = . $GetInvokeTssParams $TssSession
}

process {
. $InternalEndpointUsed $PSCmdlet.MyInvocation
Write-Verbose "Provided command parameters: $(. $GetInvocation $PSCmdlet.MyInvocation)"
if ($tssParams.ContainsKey('TssSession') -and $TssSession.IsValidSession()) {
. $CheckVersion $TssSession '10.9.000000' $PSCmdlet.MyInvocation
foreach ($secret in $Id) {
$restResponse = $null
$uri = $TssSession.ApiUrl.Replace('api/v1','internals'), 'secret-detail', $secret, 'change-password-now' -join '/'
$invokeParams.Uri = $uri
$invokeParams.Method = 'POST'

$rpcBody = @{ data = @{ } }
switch ($Type) {
'Manual' {
if ($tssParams.ContainsKey('NextPassword')) {
$rpcBody.data.Add('NextPassword',[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($NextPassword)))
$rpcBody.data.Add('PasswordType',1)
} else {
Write-Error "-NextPassword parameter must be provided when using PasswordType of [Manual]"
return
}
}
'Random' {
if ($tssParams.ContainsKey('NextPassword')) {
Write-Error "-NextPassword parameter cannot be used with PasswordType of [Random]"
return
} else {
$rpcBody.data.Add('NextPassword',$null)
$rpcBody.data.Add('PasswordType',0)
}
}
}
$invokeParams.Body = $rpcBody | ConvertTo-Json

if (-not $PSCmdlet.ShouldProcess("Secret ID: $secret","$($invokeParamsOther.Method) $uri with:`t$($invokeParamsOther.Body)`n")) { return }
Write-Verbose "$($invokeParamsOther.Method) $uri with:`t$($invokeParamsOther.Body)`n"
try {
$restResponse = Invoke-TssRestApi @invokeParams
} catch {
$err = $_
. $ErrorHandling $err
}

if ($restResponse.success -eq $false) {
Write-Warning "Password Change not successful on Secret [$secret]"
} else {
Write-Verbose "Password Change successfully started on Secret [$secret]"
}
}
} else {
Write-Warning "No valid session found"
}
}
}
@@ -1,4 +1,4 @@
function Stop-SecretPasswordChange {
function Stop-SecretChangePassword {
<#
.SYNOPSIS
Stop a current password change
Expand All @@ -8,12 +8,12 @@ function Stop-SecretPasswordChange {
.EXAMPLE
$session = New-TssSession -SecretServer https://alpha -Credential $ssCred
Stop-TssSecretPasswordChange -TssSession $session -Id 46
Stop-TssSecretChangePassword -TssSession $session -Id 46
Stop a current password change operation on secret 46
.LINK
https://thycotic-ps.github.io/thycotic.secretserver/commands/Stop-TssSecretPasswordChange
https://thycotic-ps.github.io/thycotic.secretserver/commands/Stop-TssSecretChangePassword
.NOTES
Requires TssSession object returned by New-TssSession
Expand Down
14 changes: 14 additions & 0 deletions src/parts/InternalEndpointUsed.ps1
@@ -0,0 +1,14 @@
<#
.Synopsis
To centralize the code around verbose/warning output when an internal endpoint is utilized
#>
[cmdletbinding()]
param (
[Parameter(Mandatory,Position = 2)]
[System.Management.Automation.InvocationInfo]
$Invocation
)
process {
$source = $Invocation.MyCommand
Write-Verbose "[Important]: $source utilizes an internal endpoint that is not formally supported by Thycotic"
}
29 changes: 29 additions & 0 deletions src/parts/TssSecretPasswordStatusObject.ps1
@@ -0,0 +1,29 @@
<#
.Synopsis
Creates a TssSecretPasswordStatus object
#>
param(
[pscustomobject]$Object
)

begin {
$Properties = $Object[0].PSObject.Properties.Name
}

process {
$outObject = @()
foreach ($p in $Object) {
$currentObject = [TssSecretPasswordStatus]::new()
foreach ($pProp in $Properties) {
if ($pProp -in $currentObject.PSObject.Properties.Name) {
if ($p.$pProp) {
$currentObject.$pProp = $p.$pProp
}
} else {
Write-Warning "Property $pProp does not exist in the TssSecretPasswordStatus class. Please create a bug report at https://github.com/thycotic-ps/thycotic.secretserver/issues/new/choose"
}
}
$outObject += $currentObject
}
return $outObject
}
25 changes: 25 additions & 0 deletions tests/secrets/Get-TssSecretPasswordStatus.Tests.ps1
@@ -0,0 +1,25 @@
BeforeDiscovery {
$commandName = Split-Path ($PSCommandPath.Replace('.Tests.ps1','')) -Leaf
. ([IO.Path]::Combine([string]$PSScriptRoot, '..', 'constants.ps1'))
}
Describe "$commandName verify parameters" {
BeforeDiscovery {
[object[]]$knownParameters = 'TssSession', 'Id'
[object[]]$currentParams = ([Management.Automation.CommandMetaData]$ExecutionContext.SessionState.InvokeCommand.GetCommand($commandName,'Function')).Parameters.Keys
[object[]]$commandDetails = [System.Management.Automation.CommandInfo]$ExecutionContext.SessionState.InvokeCommand.GetCommand($commandName,'Function')
$unknownParameters = Compare-Object -ReferenceObject $knownParameters -DifferenceObject $currentParams -PassThru
}
Context "Verify parameters" -Foreach @{currentParams = $currentParams} {
It "$commandName should contain <_> parameter" -TestCases $knownParameters {
$_ -in $currentParams | Should -Be $true
}
It "$commandName should not contain parameter: <_>" -TestCases $unknownParameters {
$_ | Should -BeNullOrEmpty
}
}
Context "Command specific details" {
It "$commandName should set OutputType to TssSecretPasswordStatus" -TestCases $commandDetails {
$_.OutputType.Name | Should -Be 'TssSecretPasswordStatus'
}
}
}
20 changes: 20 additions & 0 deletions tests/secrets/Start-TssSecretChangePassword.Tests.ps1
@@ -0,0 +1,20 @@
BeforeDiscovery {
$commandName = Split-Path ($PSCommandPath.Replace('.Tests.ps1','')) -Leaf
. ([IO.Path]::Combine([string]$PSScriptRoot, '..', 'constants.ps1'))
}
Describe "$commandName verify parameters" {
BeforeDiscovery {
[object[]]$knownParameters = 'TssSession', 'Id', 'Type', 'NextPassword'
[object[]]$currentParams = ([Management.Automation.CommandMetaData]$ExecutionContext.SessionState.InvokeCommand.GetCommand($commandName,'Function')).Parameters.Keys
[object[]]$commandDetails = [System.Management.Automation.CommandInfo]$ExecutionContext.SessionState.InvokeCommand.GetCommand($commandName,'Function')
$unknownParameters = Compare-Object -ReferenceObject $knownParameters -DifferenceObject $currentParams -PassThru
}
Context "Verify parameters" -Foreach @{currentParams = $currentParams} {
It "$commandName should contain <_> parameter" -TestCases $knownParameters {
$_ -in $currentParams | Should -Be $true
}
It "$commandName should not contain parameter: <_>" -TestCases $unknownParameters {
$_ | Should -BeNullOrEmpty
}
}
}
Expand Up @@ -41,7 +41,7 @@ Describe "$commandName works" -Skip {
TssSession = $session
Id = $getSecrets[0].id
}
$secret = Get-TssSecret @params | Stop-TssSecretPasswordChange -TssSession $session
$secret = Get-TssSecret @params | Stop-TssSecretChangePassword -TssSession $session
$props = 'SecretId','Status','Notes'

if (-not $tssTestUsingWindowsAuth) {
Expand Down

0 comments on commit 3f4e6a9

Please sign in to comment.