diff --git a/.github/workflows/versioning.yml b/.github/workflows/versioning.yml index bb8ca39..d1c801b 100644 --- a/.github/workflows/versioning.yml +++ b/.github/workflows/versioning.yml @@ -37,6 +37,8 @@ jobs: uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: Bumping release to ${{ steps.buildUpdate.outputs.v }} + branch: release + push_options: '--force' Minor: if: startsWith(github.head_ref, 'minor/') && github.event.pull_request.merged == true outputs: @@ -62,6 +64,7 @@ jobs: with: commit_message: Bumping release to ${{ steps.buildUpdate.outputs.v }} branch: release + push_options: '--force' Major: if: startsWith(github.head_ref, 'major/') && github.event.pull_request.merged == true outputs: @@ -86,4 +89,5 @@ jobs: uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: Bumping release to ${{ steps.buildUpdate.outputs.v }} - branch: release \ No newline at end of file + branch: release + push_options: '--force' \ No newline at end of file diff --git a/docs/function-documentation/Invoke-VerkadaFormCall.md b/docs/function-documentation/Invoke-VerkadaFormCall.md index 050604b..798e019 100644 --- a/docs/function-documentation/Invoke-VerkadaFormCall.md +++ b/docs/function-documentation/Invoke-VerkadaFormCall.md @@ -12,9 +12,17 @@ Used to build an Invoke-RestMethod call for Verkada's private API enpoints that ## SYNTAX +### Default (Default) ``` -Invoke-VerkadaFormCall [-url] [-org_id] [-form_params] [-method ] - -x_verkada_token -x_verkada_auth [-ProgressAction ] [] +Invoke-VerkadaFormCall [-url] [-org_id] [-form_params] [-query_params ] + [-method ] [-x_verkada_auth_api ] [-ProgressAction ] [] +``` + +### UnPwd +``` +Invoke-VerkadaFormCall [-url] [-org_id] [-form_params] [-query_params ] + [-method ] -x_verkada_token -x_verkada_auth [-ProgressAction ] + [] ``` ## DESCRIPTION @@ -76,6 +84,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -query_params +Object containing the query parameters need that will be put into the query string of the uri + +```yaml +Type: Object +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -method HTTP method required @@ -96,7 +119,7 @@ The Verkada(CSRF) token of the user running the command ```yaml Type: String -Parameter Sets: (All) +Parameter Sets: UnPwd Aliases: Required: True @@ -111,7 +134,7 @@ The Verkada Auth(session auth) token of the user running the command ```yaml Type: String -Parameter Sets: (All) +Parameter Sets: UnPwd Aliases: Required: True @@ -121,6 +144,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -x_verkada_auth_api +The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway + +```yaml +Type: String +Parameter Sets: Default +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -ProgressAction {{ Fill ProgressAction Description }} diff --git a/docs/function-documentation/Set-VerkadaAccessUserProfilePicture.md b/docs/function-documentation/Set-VerkadaAccessUserProfilePicture.md index 6398b3c..51d1865 100644 --- a/docs/function-documentation/Set-VerkadaAccessUserProfilePicture.md +++ b/docs/function-documentation/Set-VerkadaAccessUserProfilePicture.md @@ -8,20 +8,20 @@ schema: 2.0.0 # Set-VerkadaAccessUserProfilePicture ## SYNOPSIS -Adds/replaces an Access user's profile picture in an organization. +Adds/replaces an Access user's profile picture in an organization using https://apidocs.verkada.com/reference/putprofilephotoviewv1 ## SYNTAX ``` -Set-VerkadaAccessUserProfilePicture [[-userId] ] [[-imagePath] ] [[-org_id] ] - [[-x_verkada_token] ] [[-x_verkada_auth] ] [[-usr] ] - [-ProgressAction ] [] +Set-VerkadaAccessUserProfilePicture [[-userId] ] [[-externalId] ] [[-imagePath] ] + [[-overwrite] ] [[-org_id] ] [[-x_verkada_auth_api] ] [[-region] ] + [-errorsToFile] [-ProgressAction ] [] ``` ## DESCRIPTION -This will set the Access user's, specified by the userId, profile picture. +This will set the Access user's, specified by the user_Id or external_ID, profile picture. This must be a png or jpeg/jpg format image. -The org_id and reqired tokens can be directly submitted as parameters, but is much easier to use Connect-Verkada to cache this information ahead of time and for subsequent commands. +The org_id and reqired token can be directly submitted as parameters, but is much easier to use Connect-Verkada to cache this information ahead of time and for subsequent commands. ## EXAMPLES @@ -33,8 +33,8 @@ This sets the Access user with userId 801c9551-b04c-4293-84ad-b0a6aa0588b3 to us ### EXAMPLE 2 ``` -Set-VerkadaAccessUserProfilePicture -userId '801c9551-b04c-4293-84ad-b0a6aa0588b3' -imagePath './myPicture.png' -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_token 'a366ef47-2c20-4d35-a90a-10fd2aee113a' -x_verkada_auth 'auth-token-uuid-dscsdc' -usr 'a099bfe6-34ff-4976-9d53-ac68342d2b60' -This sets the Access user with userId 801c9551-b04c-4293-84ad-b0a6aa0588b3 to use the picture specified at path ./myPicture.png. The org_id and tokens are submitted as parameters in the call. +Set-VerkadaAccessUserProfilePicture -externalId 'newUserUPN@contoso.com' -imagePath './myPicture.png' -overwrite $true -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_auth_api 'sd78ds-uuid-of-verkada-token' +This sets the Access user with externalId newUserUPN@contoso.com to use the picture specified at path ./myPicture.png and will overwrite the existing photo. The org_id and tokens are submitted as parameters in the call. ``` ## PARAMETERS @@ -54,6 +54,21 @@ Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` +### -externalId +unique identifier managed externally provided by the consumer + +```yaml +Type: String +Parameter Sets: (All) +Aliases: external_id + +Required: False +Position: 2 +Default value: None +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + ### -imagePath This is the path the image will be uploaded from @@ -63,12 +78,27 @@ Parameter Sets: (All) Aliases: Required: False -Position: 2 +Position: 3 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` +### -overwrite +The flag that states whether to overwrite the existing profile photo + +```yaml +Type: Boolean +Parameter Sets: (All) +Aliases: + +Required: False +Position: 4 +Default value: False +Accept pipeline input: True (ByPropertyName) +Accept wildcard characters: False +``` + ### -org_id The UUID of the organization the user belongs to @@ -78,14 +108,14 @@ Parameter Sets: (All) Aliases: Required: False -Position: 3 +Position: 5 Default value: $Global:verkadaConnection.org_id Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` -### -x_verkada_token -The Verkada(CSRF) token of the user running the command +### -x_verkada_auth_api +The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway ```yaml Type: String @@ -93,14 +123,14 @@ Parameter Sets: (All) Aliases: Required: False -Position: 4 -Default value: $Global:verkadaConnection.csrfToken +Position: 6 +Default value: $Global:verkadaConnection.x_verkada_auth_api Accept pipeline input: False Accept wildcard characters: False ``` -### -x_verkada_auth -The Verkada Auth(session auth) token of the user running the command +### -region +The region of the public API to be used ```yaml Type: String @@ -108,23 +138,23 @@ Parameter Sets: (All) Aliases: Required: False -Position: 5 -Default value: $Global:verkadaConnection.userToken +Position: 7 +Default value: Api Accept pipeline input: False Accept wildcard characters: False ``` -### -usr -The UUID of the user account making the request +### -errorsToFile +Switch to write errors to file ```yaml -Type: String +Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False -Position: 6 -Default value: $Global:verkadaConnection.usr +Position: Named +Default value: False Accept pipeline input: False Accept wildcard characters: False ``` diff --git a/verkadaModule/Private/Invoke-VerkadaFormCall.ps1 b/verkadaModule/Private/Invoke-VerkadaFormCall.ps1 index 5d8d9b7..6a240d0 100644 --- a/verkadaModule/Private/Invoke-VerkadaFormCall.ps1 +++ b/verkadaModule/Private/Invoke-VerkadaFormCall.ps1 @@ -7,7 +7,7 @@ function Invoke-VerkadaFormCall Private function to build Invoke-RestMethod calls for Verkada's private API enpoints that require a form #> - [CmdletBinding(PositionalBinding = $true)] + [CmdletBinding(PositionalBinding = $true, DefaultParameterSetName = 'Default')] Param( #The url for the enpoint to be used [Parameter(Mandatory = $true, Position = 0)] @@ -20,24 +20,47 @@ function Invoke-VerkadaFormCall #Object to pass form parameters to forms [Parameter(Mandatory = $true,Position = 2)] [Object]$form_params, + #Object containing the query parameters need that will be put into the query string of the uri + [Parameter()] + [Object]$query_params, #HTTP method required [Parameter()] [String]$method = 'POST', #The Verkada(CSRF) token of the user running the command - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $true, ParameterSetName = 'UnPwd')] [ValidateNotNullOrEmpty()] [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [string]$x_verkada_token, #The Verkada Auth(session auth) token of the user running the command - [Parameter(Mandatory = $true)] + [Parameter(Mandatory = $true, ParameterSetName = 'UnPwd')] [ValidateNotNullOrEmpty()] - [string]$x_verkada_auth + [string]$x_verkada_auth, + #The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway + [Parameter(ParameterSetName = 'Default')] + [String]$x_verkada_auth_api ) Process { - $headers=@{ - 'x-verkada-token' = $x_verkada_token - 'X-Verkada-Auth' = $x_verkada_auth + if ($PSCmdlet.ParameterSetName -eq 'UnPwd'){ + $headers=@{ + 'x-verkada-token' = $x_verkada_token + 'X-Verkada-Auth' = $x_verkada_auth + } + } else { + $headers=@{ + 'x-verkada-auth' = $x_verkada_auth_api + } + } + + if($query_params){ + $query = [System.Web.HttpUtility]::ParseQueryString([String]::Empty) + foreach ($qp in $query_params.GetEnumerator()) { + $query.add("$($qp.name)", "$($qp.value)") + } + $uri = [System.UriBuilder]"$url" + $uri.Query = $query.ToString() + $uri = $uri.Uri.OriginalString + $url = $uri } $uri = $url diff --git a/verkadaModule/Public/Set-VerkadaAccessUserProfilePicture.ps1 b/verkadaModule/Public/Set-VerkadaAccessUserProfilePicture.ps1 index 0acdc43..768369a 100644 --- a/verkadaModule/Public/Set-VerkadaAccessUserProfilePicture.ps1 +++ b/verkadaModule/Public/Set-VerkadaAccessUserProfilePicture.ps1 @@ -1,11 +1,11 @@ function Set-VerkadaAccessUserProfilePicture{ <# .SYNOPSIS - Adds/replaces an Access user's profile picture in an organization. + Adds/replaces an Access user's profile picture in an organization using https://apidocs.verkada.com/reference/putprofilephotoviewv1 .DESCRIPTION - This will set the Access user's, specified by the userId, profile picture. This must be a png or jpeg/jpg format image. - The org_id and reqired tokens can be directly submitted as parameters, but is much easier to use Connect-Verkada to cache this information ahead of time and for subsequent commands. + This will set the Access user's, specified by the user_Id or external_ID, profile picture. This must be a png or jpeg/jpg format image. + The org_id and reqired token can be directly submitted as parameters, but is much easier to use Connect-Verkada to cache this information ahead of time and for subsequent commands. .LINK https://github.com/bepsoccer/verkadaModule/blob/master/docs/function-documentation/Set-VerkadaAccessUserProfilePicture.md @@ -15,8 +15,8 @@ function Set-VerkadaAccessUserProfilePicture{ This sets the Access user with userId 801c9551-b04c-4293-84ad-b0a6aa0588b3 to use the picture specified at path ./myPicture.jpg. The org_id and tokens will be populated from the cached created by Connect-Verkada. .EXAMPLE - Set-VerkadaAccessUserProfilePicture -userId '801c9551-b04c-4293-84ad-b0a6aa0588b3' -imagePath './myPicture.png' -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_token 'a366ef47-2c20-4d35-a90a-10fd2aee113a' -x_verkada_auth 'auth-token-uuid-dscsdc' -usr 'a099bfe6-34ff-4976-9d53-ac68342d2b60' - This sets the Access user with userId 801c9551-b04c-4293-84ad-b0a6aa0588b3 to use the picture specified at path ./myPicture.png. The org_id and tokens are submitted as parameters in the call. + Set-VerkadaAccessUserProfilePicture -externalId 'newUserUPN@contoso.com' -imagePath './myPicture.png' -overwrite $true -org_id '7cd47706-f51b-4419-8675-3b9f0ce7c12d' -x_verkada_auth_api 'sd78ds-uuid-of-verkada-token' + This sets the Access user with externalId newUserUPN@contoso.com to use the picture specified at path ./myPicture.png and will overwrite the existing photo. The org_id and tokens are submitted as parameters in the call. #> [CmdletBinding(PositionalBinding = $true)] [Alias("Set-VrkdaAcUsrPrflPic","s-VrkdaAcUsrPrflPic")] @@ -27,72 +27,93 @@ function Set-VerkadaAccessUserProfilePicture{ [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [Alias('user_id')] [String]$userId, + #unique identifier managed externally provided by the consumer + [Parameter(ValueFromPipelineByPropertyName = $true)] + [Alias('external_id')] + [String]$externalId, #This is the path the image will be uploaded from [Parameter(ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [ValidatePattern('^.*\.(jpg|jpeg|png)$')] [string]$imagePath, + #The flag that states whether to overwrite the existing profile photo + [Parameter(ValueFromPipelineByPropertyName = $true)] + [bool]$overwrite=$false, #The UUID of the organization the user belongs to [Parameter(ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] [String]$org_id = $Global:verkadaConnection.org_id, - #The Verkada(CSRF) token of the user running the command + #The public API token obatined via the Login endpoint to be used for calls that hit the public API gateway [Parameter()] [ValidateNotNullOrEmpty()] - [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] - [string]$x_verkada_token = $Global:verkadaConnection.csrfToken, - #The Verkada Auth(session auth) token of the user running the command + [String]$x_verkada_auth_api = $Global:verkadaConnection.x_verkada_auth_api, + #The region of the public API to be used [Parameter()] - [ValidateNotNullOrEmpty()] - [string]$x_verkada_auth = $Global:verkadaConnection.userToken, - #The UUID of the user account making the request + [ValidateSet('api','api.eu','api.au')] + [String]$region='api', + #Switch to write errors to file [Parameter()] - [ValidateNotNullOrEmpty()] - [ValidatePattern('^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$')] - [string]$usr = $Global:verkadaConnection.usr + [switch]$errorsToFile ) begin { + $url = "https://$($region).verkada.com/access/v1/access_users/user/profile_photo" #parameter validation if ([string]::IsNullOrEmpty($org_id)) {throw "org_id is missing but is required!"} - if ([string]::IsNullOrEmpty($x_verkada_token)) {throw "x_verkada_token is missing but is required!"} - if ([string]::IsNullOrEmpty($x_verkada_auth)) {throw "x_verkada_auth is missing but is required!"} - if ([string]::IsNullOrEmpty($usr)) {throw "usr is missing but is required!"} - - $url = 'https://vcerberus.command.verkada.com/user/photos/upload' + if ([string]::IsNullOrEmpty($x_verkada_auth_api)) {throw "x_verkada_auth_api is missing but is required!"} + $myErrors = @() } #end begin process { - if (!(Test-Path -Path $imagePath -PathType Leaf)){ - Write-Error "$imagePath is not a valid file path" - return - } - if ([string]::IsNullOrEmpty($userId)){ - Write-Error "userId required" + if ([string]::IsNullOrEmpty($externalId) -and [string]::IsNullOrEmpty($userId)){ + Write-Error "Either externalId or userId required" return } $form = @{ - organizationId = $org_id - userId = $userId - file = Get-Item -Path $imagePath + file = Get-Item -Path $imagePath + } + + $query_params = @{ + 'overwrite' = $overwrite } + if (!([string]::IsNullOrEmpty($userId))){ + $query_params.user_id = $userId + } elseif (!([string]::IsNullOrEmpty($externalId))){ + $query_params.external_id = $externalId + } + try { - Invoke-VerkadaFormCall $url $org_id $form -x_verkada_token $x_verkada_token -x_verkada_auth $x_verkada_auth -Method 'POST' + Invoke-VerkadaFormCall $url $org_id $form -query_params $query_params -x_verkada_auth_api $x_verkada_auth_api -Method 'PUT' + return "Successfully uploaded $imagePath to $($query_params | ConvertTo-Json -Compress)" } catch [Microsoft.PowerShell.Commands.HttpResponseException] { $err = $_.ErrorDetails | ConvertFrom-Json $errorMes = $_ | Convertto-Json -WarningAction SilentlyContinue $err | Add-Member -NotePropertyName StatusCode -NotePropertyValue (($errorMes | ConvertFrom-Json -Depth 100 -WarningAction SilentlyContinue).Exception.Response.StatusCode) -Force - - Write-Host "$($err.StatusCode) - $($err.message)" -ForegroundColor Red - Return + $msg = "$($err.StatusCode) - $($err.message)" + $msg += ": $(($query_params + $form) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null + } + catch [VerkadaRestMethodException] { + $msg = $_.ToString() + $msg += ": $(($query_params + $body_params) | ConvertTo-Json -Compress)" + Write-Error $msg + $myErrors += $msg + $msg = $null } } #end process end { - + if ($errorsToFile.IsPresent){ + if (![string]::IsNullOrEmpty($myErrors)){ + Get-Date | Out-File ./errors.txt -Append + $myErrors | Out-File ./errors.txt -Append + } + } } #end end } #end function \ No newline at end of file diff --git a/verkadaModule/verkadaModule.psd1 b/verkadaModule/verkadaModule.psd1 index afabe16..2d83586 100644 --- a/verkadaModule/verkadaModule.psd1 +++ b/verkadaModule/verkadaModule.psd1 @@ -3,7 +3,7 @@ # # Generated by: Verkada SE Community # -# Generated on: 05/12/2025 +# Generated on: 05/13/2025 # @{ @@ -12,7 +12,7 @@ RootModule = 'verkadaModule.psm1' # Version number of this module. -ModuleVersion = '0.9.1' +ModuleVersion = '0.9.3' # Supported PSEditions CompatiblePSEditions = 'Desktop', 'Core'