Public/Add-DunePermission.ps1

<#
.SYNOPSIS
Grant a permission on a Dune config item.

.DESCRIPTION
Grants one or more users a role on a config item by sending a POST request to the authorization service. The target can be supplied as a `DuneConfigItem` derived object (pipeline input supported) or via `ConfigItemId`/`ConfigItemType`. The role can be supplied as a `DuneRole` object or by name. Returns the created `DunePermission` objects.

.PARAMETER ConfigItem
A `DuneConfigItem` derived object (`DuneTenant`, `DuneCollection`, `DuneDeployment`, `DuneResourceGroup` or `DuneResource`) to grant the permission on (pipeline input supported).

.PARAMETER ConfigItemId
The GUID of the config item to grant the permission on. Use together with `ConfigItemType` as an alternative to passing a typed object.

.PARAMETER ConfigItemType
The type of the config item referenced by `ConfigItemId` (`Tenant`, `Collection`, `Deployment`, `ResourceGroup`, `Resource`).

.PARAMETER User
One or more `DuneUser` objects that are granted the role.

.PARAMETER RoleName
The name of the role to grant, e.g. `Owner` or `Operator` (matched case-sensitively). A role name is only unique together with its `AppliesTo`, so the API pairs the name with the target's config item type to resolve the matching role.

.PARAMETER Role
A `DuneRole` object to grant, as an alternative to `-RoleName`. Fetch the right variant with `Get-DuneRole <name> -AppliesTo <type>`; its `AppliesTo` must match the config item type.

.EXAMPLE
PS> Get-DuneDeployment -Name "webapp" | Add-DunePermission -User $User -RoleName Owner
Grants the user the Owner role on the deployment `webapp`.

.EXAMPLE
PS> $Users = Get-DuneUser | Where-Object Email -like "*@example.com"
PS> Add-DunePermission -ConfigItemId $CollectionId -ConfigItemType Collection -User $Users -RoleName Operator
Grants multiple users the Operator role on a collection by id.

.EXAMPLE
PS> $Role = Get-DuneRole Operator -AppliesTo Deployment
PS> Get-DuneDeployment -Name "webapp" | Add-DunePermission -User $User -Role $Role
Grants the role using a `DuneRole` object instead of its name.
#>

function Add-DunePermission {
    [CmdletBinding(DefaultParameterSetName = 'ConfigItem')]
    param(
        [Parameter(ParameterSetName = 'ConfigItem', ValueFromPipeline)]
        [DuneConfigItem]$ConfigItem,

        [Parameter(ParameterSetName = 'Id', Mandatory)]
        [guid]$ConfigItemId,

        [Parameter(ParameterSetName = 'Id', Mandatory)]
        [ValidateSet('Tenant','Collection','Deployment','ResourceGroup','Resource')]
        [string]$ConfigItemType,

        [Parameter(Mandatory)]
        [DuneUser[]]$User,

        [Parameter()]
        [string]$RoleName,

        [Parameter()]
        [DuneRole]$Role
    )

    begin {
        Write-Debug "$($MyInvocation.MyCommand)|begin"
        if (-not $RoleName -and -not $Role) { throw 'Provide -RoleName or -Role.' }
    }

    process {
        Write-Debug "$($MyInvocation.MyCommand)|process|$($PSCmdlet.ParameterSetName)"

        if ($PSCmdlet.ParameterSetName -eq 'ConfigItem') {
            $ConfigItemId = $ConfigItem.Id
            $ConfigItemType = switch ($ConfigItem) {
                { $_ -is [DuneTenant] } { 'Tenant'; break }
                { $_ -is [DuneCollection] } { 'Collection'; break }
                { $_ -is [DuneDeployment] } { 'Deployment'; break }
                { $_ -is [DuneResourceGroup] } { 'ResourceGroup'; break }
                { $_ -is [DuneResource] } { 'Resource'; break }
                Default { throw "Permissions cannot be granted on objects of type '$($ConfigItem.GetType().Name)'." }
            }
        }

        $Body = @{
            ConfigItemId   = $ConfigItemId
            ConfigItemType = $ConfigItemType
            UserAuthIds    = @($User | ForEach-Object { $_.Id })
        }
        if ($Role) { $Body.RoleId = $Role.Id } else { $Body.RoleName = $RoleName }

        $Return = Invoke-DuneApiRequest -Uri 'authorization/permissions' -Method POST -Body $Body -ErrorAction Stop
        $ReturnObject = if ($Return.Content) {
            ($Return.Content | ConvertFrom-Json).Items | ForEach-Object { ConvertTo-DuneClassObject -Class DunePermission -InputObject $_ }
        }
        return $ReturnObject
    }

    end {}
}