diff --git a/src/classes/folder-permissions/TssFolderPermission.class.ps1 b/src/classes/folder-permissions/TssFolderPermission.class.ps1 index 369a865e..36b655e2 100644 --- a/src/classes/folder-permissions/TssFolderPermission.class.ps1 +++ b/src/classes/folder-permissions/TssFolderPermission.class.ps1 @@ -1,5 +1,7 @@ class TssFolderPermission { [int]$FolderAccessRoleId + [string]$FolderAccessRoleName [int]$GroupId [int]$SecretAccessRoleId + [string]$SecretAccessRoleName } \ No newline at end of file diff --git a/src/en-us/about_tssfolderpermission.help.txt b/src/en-us/about_tssfolderpermission.help.txt index 877ffc64..a7831e1a 100644 --- a/src/en-us/about_tssfolderpermission.help.txt +++ b/src/en-us/about_tssfolderpermission.help.txt @@ -17,13 +17,21 @@ PROPERTIES FolderAccessRoleId Folder Access Role Id + FolderAccessRoleName + Permission on the folder + GroupId Group Id SecretAccessRoleId Secret Access Role Id + SecretAccessRoleName + Permission on the secrets in the folder + METHODS RELATED LINKS: - Get-TssFolderPermission \ No newline at end of file + Get-TssFolderPermission + Get-TssFolderPermissionStub + New-TssFolderPermission \ No newline at end of file diff --git a/src/functions/folder-permissions/New-FolderPermission.ps1 b/src/functions/folder-permissions/New-FolderPermission.ps1 new file mode 100644 index 00000000..a5b8c313 --- /dev/null +++ b/src/functions/folder-permissions/New-FolderPermission.ps1 @@ -0,0 +1,94 @@ +function New-FolderPermission { + <# + .SYNOPSIS + Create a new folder permission + + .DESCRIPTION + Create a new folder permission + + .LINK + https://thycotic-ps.github.io/thycotic.secretserver/commands/New-TssFolderPermission + + .NOTES + Requires TssSession object returned by New-TssSession + #> + [CmdletBinding(SupportsShouldProcess)] + [OutputType('TssFolderPermission')] + param ( + # TssSession object created by New-TssSession for auth + [Parameter(Mandatory,ValueFromPipeline,Position = 0)] + [TssSession] + $TssSession, + + # Folder ID + [Parameter(Mandatory,ValueFromPipeline)] + [int] + $FolderId, + + # Group Id + [Parameter(ValueFromPipeline)] + [int] + $GroupId, + + # User ID + [Parameter(ValueFromPipeline)] + [int] + $UserId, + + # Folder Access Role Name + [Parameter(Mandatory,ValueFromPipeline)] + [ValidateSet('View','Edit','Add Secret','Owner')] + [string] + $FolderAccessRoleName, + + # Secret Access Role Name + [Parameter(Mandatory,ValueFromPipeline)] + [ValidateSet('View','Edit','List','Owner','None')] + [string] + $SecretAccessRoleName + ) + begin { + $tssNewParams = $PSBoundParameters + $invokeParams = . $GetInvokeTssParams $TssSession + } + process { + Write-Verbose "Provided command parameters: $(. $GetInvocation $PSCmdlet.MyInvocation)" + if ($tssNewParams.ContainsKey('TssSession') -and $TssSession.IsValidSession()) { + if ($tssNewParams.ContainsKey('UserId') -or $tssNewParams.ContainsKey('GroupId')) { + $restResponse = $null + $uri = $TssSession.ApiUrl, 'folder-permissions' -join '/' + $invokeParams.Uri = $uri + $invokeParams.Method = 'POST' + + $newBody = [ordered]@{} + switch ($tssNewParams.Keys) { + 'FolderId' { $newBody.Add('folderId',$FolderId) } + 'GroupId' { $newBody.Add('groupId',$GroupId) } + 'FolderAccessRoleName' { $newBody.Add('folderAccessRoleName',$FolderAccessRoleName) } + 'UserId' { $newBody.Add('userId',$UserId) } + 'SecretAccessRoleName' { $newBody.Add('secretAccessRoleName',$SecretAccessRoleName) } + } + + $invokeParams.Body = $newBody | ConvertTo-Json + + Write-Verbose "$($invokeParams.Method) $uri with:`n $newBody" + if (-not $PSCmdlet.ShouldProcess("FolderID: $FolderId", "$($invokeParams.Method) $uri with $($invokeParams.Body)")) { return } + try { + $restResponse = Invoke-TssRestApi @invokeParams + } catch { + Write-Warning "Issue creating Folder Permission on Folder [$FolderId]" + $err = $_ + . $ErrorHandling $err + } + + if ($restResponse) { + . $TssFolderPermissionObject $restResponse + } + } else { + Write-Error "Please provide one of the following parameters: -GroupId or -UserId" + } + } else { + Write-Warning "No valid session found" + } + } +} \ No newline at end of file diff --git a/src/parts/TssFolderPermissionObject.ps1 b/src/parts/TssFolderPermissionObject.ps1 index 537fa9b9..0b92c891 100644 --- a/src/parts/TssFolderPermissionObject.ps1 +++ b/src/parts/TssFolderPermissionObject.ps1 @@ -8,24 +8,45 @@ param( begin { $Properties = $Object[0].PSObject.Properties.Name + + <# Hashtables for Folder Access Role Name #> + $folderAccessRoles = @{ + 6 = 'Add Secret' + 7 = 'Edit' + 10 = 'Owner' + 12 = 'View' + } + <# Hashtables for Secret Access Role Name #> + $secretAccessRoles = @{ + 8 = 'Edit' + 9 = 'List' + 11 = 'Owner' + 13 = 'View' + } } process { $outObject = @() foreach ($f in $Object) { $currentObject = [TssFolderPermission]::new() - foreach ($sProp in $Properties) { - # until bug is fixed in endpoint - if ($sProp -in 'Id','folderId','folderAccessRoleName','SecretAccessRoleName','groupName','userId','userName','knownAs') { - continue - } - if ($sProp -in $currentObject.PSObject.Properties.Name) { - $currentObject.$sProp = $f.$sProp - } else { - Write-Warning "Property $sProp does not exist in the TssFolderPermission class.bug report at https://github.com/thycotic-ps/thycotic.secretserver/issues/new/choose" - } + foreach ($sProp in $Properties) { + # until bug is fixed in endpoint + if ($sProp -in 'Id','folderId','folderAccessRoleName','SecretAccessRoleName','groupName','userId','userName','knownAs') { + continue + } + if ($sProp -in $currentObject.PSObject.Properties.Name) { + $currentObject.$sProp = $f.$sProp + } else { + Write-Warning "Property $sProp does not exist in the TssFolderPermission class.bug report at https://github.com/thycotic-ps/thycotic.secretserver/issues/new/choose" } - $outObject += $currentObject } - return $outObject - } \ No newline at end of file + # Set FolderAccessRoleName + $currentObject.FolderAccessRoleName = $folderAccessRoles[[int]$f.FolderAccessRoleId] + + # Set SecretAccessRoleName + $currentObject.SecretAccessRoleName = $secretAccessRoles[[int]$f.SecretAccessRoleId] + + $outObject += $currentObject + } + return $outObject +} \ No newline at end of file diff --git a/tests/folder-permissions/New-TssFolderPermission.Tests.ps1 b/tests/folder-permissions/New-TssFolderPermission.Tests.ps1 new file mode 100644 index 00000000..d227b2a4 --- /dev/null +++ b/tests/folder-permissions/New-TssFolderPermission.Tests.ps1 @@ -0,0 +1,64 @@ +BeforeDiscovery { + $commandName = Split-Path ($PSCommandPath.Replace('.Tests.ps1','')) -Leaf + . ([IO.Path]::Combine([string]$PSScriptRoot, '..', 'constants.ps1')) +} +Describe "$commandName verify parameters" { + BeforeDiscovery { + [object[]]$knownParameters = 'TssSession', + 'FolderId', 'GroupId', 'UserId', 'FolderAccessRoleName', 'SecretAccessRoleName' + [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 TssFolderPermission" -TestCases $commandDetails { + $_.OutputType.Name | Should -Be 'TssFolderPermission' + } + } +} +Describe "$commandName functions" { + BeforeAll { + . ([IO.Path]::Combine([string]$PSScriptRoot,'..','..', 'src', 'classes', 'TssSession.class.ps1')) + . ([IO.Path]::Combine([string]$PSScriptRoot,'..','..', 'src', 'classes', 'TssDelete.class.ps1')) + Mock -CommandName Invoke-TssRestApi -MockWith { + return @{ + FolderAccessRoleId = 7 + FolderAccessRoleName = 'Edit' + GroupId = 0 + SecretAccessRoleId = $null + SecretAccessRoleName = '' + } + } + Mock New-TssSession -MockWith { + return [TssSession]@{ + ApiVersion = 'api/v1' + Take = 2147483647 + SecretServer = 'http://vault3/' + ApiUrl = 'http://vault3/api/v1' + AccessToken = 'AgJf5YLFWtzw2UcBrM1s1KB2BGZ5Ufc4qLZeRE3-sYkrTRt5zp_19C-Z8FQbgtID9xz9hHmm0BfL9DzEsDI1gVjG7Kltpq-K3SOa3WbYLIgIb9FGwW2vV6JYvcW4uEBqPBvcY9l4fHKIKJ5pyLp' + RefreshToken = '9oacYFZZ0YqgBNg0L7VNIF6-Z9ITE51QpljgpuZRVkse4xnv5 rten1Y_3_L2MQX7cflVy7iDbRIuj-ohkVnVfXbYdRQqQmrCTB 3j7VcSKlkLXF2FnUP4LnObcgucrBEUdgS1UN0bySXZ8RJh_ez' + TokenType = 'bearer' + ExpiresIn = 1199 + } + } + + $session = New-TssSession -SecretServer 'http://vault3' -AccessToken (Get-Random) + $object = New-TssFolderPermission -TssSession $session -FolderId 999 -UserId 497 -FolderAccessRoleName Edit -SecretAccessRoleName None + } + Context "Checking" -ForEach { object = $object } { + It "Should not be empty" { + $object | Should -Not -BeNullOrEmpty + } + It "Should have property <_>" -TestCases 'FolderAccessRoleName', 'GroupId', 'SecretAccessRoleName' { + $object[0].PSObject.Properties.Name | Should -Contain $_ + } + } +} \ No newline at end of file