PowerShell / SecretManagement

PowerShell module to consistent usage of secrets through different extension vaults
MIT License
335 stars 47 forks source link

Argument completers lack functionality #91

Closed camusicjunkie closed 3 years ago

camusicjunkie commented 3 years ago

Currently, the two argument completers here lack functionality. https://github.com/PowerShell/SecretManagement/blob/30991fd56ef43074c3ff76f303fbf35c9e46be7d/src/code/SecretManagement.cs#L79 https://github.com/PowerShell/SecretManagement/blob/30991fd56ef43074c3ff76f303fbf35c9e46be7d/src/code/SecretManagement.cs#L778 Both argument completers do not account for spaces in the name or vault parameter. For example, if I have these vaults and secrets set up

Name        Type VaultName
----        ---- ---------
Test Name String SecretStore
Test      String Cred Man

the following command does not wrap quotes around each value when you tab through the values.

Get-Secret -Name Test Name shows instead of Get-Secret -Name 'Test Name'

Also, the -Name parameter does not take in to account the current value for the -Vault parameter. I've added quotes around the name and vault parameter values below to show the expected behavior from above.

Get-Secret -Vault 'Cred Man' -Name 'Test Name' shows first when I tab through the name parameter instead of Get-Secret -Vault 'Cred Man' -Name Test

The expected behavior would be that when 'Cred Man' is selected as the vault, the only option I get when I tab through the name parameter is Test.

camusicjunkie commented 3 years ago

I'm not familiar enough with C# to tell but looking at #99, it looks my second scenario isn't accounted for. I don't know what this would look like in C# but below is something I put together in Powershell where $fakeBoundParameters is used as a filter. This allows for only secret names to show from a vault if the vault parameter is used first.

$commands = 'Get-Secret', 'Get-SecretInfo', 'Remove-Secret', 'Set-Secret'

Register-ArgumentCompleter -CommandName $commands -ParameterName Vault -ScriptBlock {
    param (
        $commandName, $parameterName, $wordsToComplete, $commandAst, $fakeBoundParameters
    )

    $filter = $fakeBoundParameters.Name

    (Get-SecretInfo | Where-Object VaultName -like "$wordsToComplete*" |
        Where-Object Name -like "$filter*").VaultName | Select-Object -Unique |
        ForEach-Object {
            $completionText = if ($_ -match '\s') { "'$_'" } else { $_ }

            New-Object System.Management.Automation.CompletionResult (
                $completionText, $_, 'ParameterValue', $_
            )
        }
}

Register-ArgumentCompleter -CommandName $commands -ParameterName Name -ScriptBlock {
    param (
        $commandName, $parameterName, $wordsToComplete, $commandAst, $fakeBoundParameters
    )

    $filter = $fakeBoundParameters.Vault

    (Get-SecretInfo | Where-Object Name -like "$wordsToComplete*" |
        Where-Object VaultName -like "$filter*").Name |
        ForEach-Object {
            $completionText = if ($_ -match '\s') { "'$_'" } else { $_ }

            New-Object System.Management.Automation.CompletionResult (
                $completionText, $_, 'ParameterValue', $_
            )
        }
}
PaulHigin commented 3 years ago

Fixed in RC2.