Tests/SecretManagementVault.Tests.ps1
#requires -modules @{ModuleName="Pester"; ModuleVersion="5.1.0"} Describe 'SecretManagement.Keepass' { BeforeAll { Remove-Module SecretManagement.Keepass,SecretManagement.KeePass.Extension -ErrorAction SilentlyContinue #Fetch helper function . $PSScriptRoot/../SecretManagement.KeePass.Extension/Private/Unlock-SecureString.ps1 #Would use TestDrive but the PoshKeePass Module doesn't understand it for purposes of new-keepassdatabase $SCRIPT:VaultName = 'SecretManagement.Tests' $SCRIPT:VaultExtensionName = 'SecretManagement.KeePass' $SCRIPT:VaultPath = Join-Path $TestDrive.FullName 'KeepassTestVault.kdbx' $SCRIPT:VaultKey = [PSCredential]::new('vaultkey',(ConvertTo-SecureString -AsPlainText -Force 'ThisIsATestVaultYouShouldNotUseIt')) #BUG: For some reason there's an issue with using the nested module exported commands in Pester, this is workaround Import-Module "$PSScriptRoot/../SecretManagement.KeePass.psd1" -Force & (Get-Module SecretManagement.Keepass) { Import-Module "$PSScriptRoot/../PoshKeePass/PoShKeePass.psd1" #Create three variations of databases: Master Key only, keyfile, and both $VaultKeyFilePath = Join-Path $TestDrive.FullName 'KeepassTestKeyFileVault.key' $VaultKeyDBPath = $VaultPath -replace 'Vault','KeyVault' $VaultKeyPWDBPath = $VaultPath -replace 'Vault','KeyPWVault' [KeePassLib.Keys.KcpKeyFile]::Create($VaultKeyFilePath, $null) New-KeePassDatabase -DatabasePath $VaultPath -MasterKey $VaultKey New-KeePassDatabase -DatabasePath $VaultKeyDBPath -KeyPath $VaultKeyFilePath New-KeePassDatabase -DatabasePath $VaultKeyPWDBPath -KeyPath $VaultKeyFilePath -MasterKey $VaultKey Remove-Module PoshKeePass } $SCRIPT:RegisterSecretVaultParams = @{ Name = $VaultName ModuleName = (Get-Module $VaultExtensionName).Path PassThru = $true VaultParameters = @{ Path = $VaultPath } } try { $SCRIPT:TestVault = Register-SecretVault @RegisterSecretVaultParams } catch [InvalidOperationException] { if ($PSItem -match 'Provided Name for vault is already being used') { Unregister-SecretVault -Name $RegisterSecretVaultParams.Name $SCRIPT:TestVault = Register-SecretVault @RegisterSecretVaultParams } else { $PSCmdlet.ThrowTerminatingError($PSItem) } } Mock -Verifiable Get-Credential {return $VaultKey} } AfterAll { $SCRIPT:TestVault | Unregister-SecretVault Get-Item $VaultPath -ErrorAction SilentlyContinue | Remove-Item } BeforeEach { $secretName = "tests/$((New-Guid).Guid)" } Context 'Unlock' { It 'Vault prompts for Master Key' { Test-SecretVault -Name $TestVault.Name | Out-Null Should -InvokeVerifiable } } Context 'SecretManagement' { BeforeAll { #Unlock the vault Test-SecretVault -Name $TestVault.Name } It 'Get-SecretVault' { Get-SecretVault -Name $TestVault.Name | Should -Not -BeNullOrEmpty } It 'Test-SecretVault' { Test-SecretVault -Name $TestVault.Name | Should -Be $true } It 'Get/Set/Remove String' { $secretText = 'This is my string secret' Set-Secret -Name $secretName -Vault $VaultName -Secret $secretText $secretInfo = Get-SecretInfo -Name $secretName -Vault $VaultName $secretInfo.Name | Should -BeExactly $secretName $secretInfo.VaultName | Should -BeExactly $VaultName $secret = Get-Secret -Name $secretName -Vault $VaultName $secret | Should -Be 'System.Security.SecureString' Unlock-SecureString $secret | Should -BeExactly $secretText Remove-Secret -Name $secretName -Vault $VaultName { Get-Secret -Name $secretName -Vault $VaultName -ErrorAction Stop } | Should -Throw -ErrorId 'GetSecretNotFound,Microsoft.PowerShell.SecretManagement.GetSecretCommand' } It 'Get/Set/Remove SecureString' { $secretText = 'This is my securestring secret' Set-Secret -Name $secretName -Vault $VaultName -Secret ($secretText | ConvertTo-SecureString -AsPlainText -Force) $secretInfo = Get-SecretInfo -Name $secretName -Vault $VaultName $secretInfo.Name | Should -BeExactly $secretName $secretInfo.VaultName | Should -BeExactly $VaultName $secret = Get-Secret -Name $secretName -AsPlainText -Vault $VaultName $secret | Should -BeExactly $secretText Remove-Secret -Name $secretName -Vault $VaultName { Get-Secret -Name $secretName -Vault $VaultName -ErrorAction Stop } | Should -Throw -ErrorId 'GetSecretNotFound,Microsoft.PowerShell.SecretManagement.GetSecretCommand' } It 'Get/Set/Remove PSCredential' { $secretPassword = 'PesterPassword' $secret = [PSCredential]::new('PesterUser',($secretPassword | ConvertTo-SecureString -AsPlainText -Force)) Set-Secret -Name $secretName -Vault $VaultName -Secret $secret $secretInfo = Get-SecretInfo -Name $secretName -Vault $VaultName $secretInfo.Name | Should -BeLike $secretName $secretInfo.VaultName | Should -BeExactly $VaultName $storedSecret = Get-Secret -Name $secretName -Vault $VaultName $storedSecret | Should -BeOfType [PSCredential] $storedSecret.GetNetworkCredential().Password | Should -BeExactly $secretPassword $storedSecret.Username | Should -BeExactly $secret.UserName Remove-Secret -Name $secretName -Vault $VaultName { Get-Secret -Name $secretName -Vault $VaultName -ErrorAction Stop } | Should -Throw -ErrorId 'GetSecretNotFound,Microsoft.PowerShell.SecretManagement.GetSecretCommand' } It 'Register-SecretVault -AllowClobber' { $RegisterSecretVaultParams.VaultParameters.Pester = $true $RegisterSecretVaultParams.AllowClobber = $true $newVault = Register-SecretVault @RegisterSecretVaultParams $newVault.VaultParameters.Pester | Should -BeTrue } } } |