I'm using the JiraPS module and I have already raised a bug for this issue, however I'm trying to work around it. I am using Jira Cloud and have found some gaps between how Jira Server and Jira Cloud operate (namely on things like using username for server but userid for cloud). When I try to call the JiraPS function Add-JiraGroupMember
it errors out throwing a 401 (the same $credential is being passed for adding user, which doesn't fail).
However I took that function and did some tweaking to it to try to make it work:
function Add-JiraGroupMemberCloud {
[CmdletBinding( SupportsShouldProcess )]
param(
[Parameter( Mandatory, ValueFromPipeline )]
[Alias('GroupName')]
[ValidateNotNullOrEmpty()]
[Object[]]
$Group,
[Parameter( Mandatory )]
[ValidateNotNullOrEmpty()]
[Object[]]
$User,
[Parameter()]
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential,
[Switch]
$PassThru
)
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Function started"
$server = Get-JiraConfigServer -ErrorAction Stop
$resourceURi = "$server/rest/api/2/group/user?groupId={0}"
foreach ($_group in $Group) {
Write-Verbose "[$($MyInvocation.MyCommand.Name)] Processing [$_group]"
Write-Debug "[$($MyInvocation.MyCommand.Name)] Processing `$_group [$_group]"
$groupObj = Get-JiraGroup -GroupName $_group -Credential $Credential -ErrorAction Stop
$groupMembers = (Get-JiraGroupMember -Group $_group -Credential $Credential -ErrorAction Stop).AccountId
if ($groupMembers -notcontains $user.AccountId) {
Write-Debug -Message "[$($MyInvocation.MyCommand.Name)] User [$($user.EmailAddress)] is not already in group [$_group]. Adding user."
$parameter = @{
URI = $resourceURi -f ($groupObj.RestURL -split ("groupID="))[1]
Method = "POST"
headers = @{'Accept'='application/json'; 'Content-Type'='application/json'}
Body = ConvertTo-Json -InputObject @{ 'accountId' = $user.AccountId }
Credential = $Credential
}
# echo "curl --request POST \`n --url $($parameter.URI) \`n --user ""$($credential.GetNetworkCredential().Username):$($credential.GetNetworkCredential().password)"" \`n --header 'Accept: application/json' \`n --header 'Content-Type: application/json' \`n --data '$($parameter.Body)'"
Write-Debug -Message "[$($MyInvocation.MyCommand.Name)] Invoking JiraMethod with `$parameter"
if ($PSCmdlet.ShouldProcess($GroupName, "Adding user '$($user.AccountId)'.")) {
Try{
$result = Invoke-RestMethod @parameter
}
Catch{
return $_
}
}
}
else {
Write-Warning -Message "User [$($user.EmailAddress)] is already a member of group [$_group]"
}
}
if ($PassThru) {
Write-Output (ConvertTo-JiraGroup -InputObject $result)
}
}
When it hits the invoke-restmethod
it does bomb out and return an error:
Invoke-RestMethod : The remote server returned an error: (401) Unauthorized.
so I added a step in there that basically builds out the call using cURL (based on the structure example in the Jira REST API docs). When I put a breakpoint in at the invoke-restmethod
, and I run the echo to get the cURL command and run it in ubuntu, it works without any issues. I cannot seem to figure out what the issue with the invoke-restmethod call is, or why it would work in cURL, but I assuming I'm doing something stupid that I'm hoping someone here can see better than I can.
CodePudding user response:
By default, Invoke-RestMethod
does not perform authentication. Solutions based on your PowerShell version:
PowerShell >= v6.0
You can use the -Authentication
parameter to define an authentication method:
-Authentication
Specifies the explicit authentication type to use for the request. The default is None. The Authentication parameter can't be used with the UseDefaultCredentials parameter.
Available Authentication Options:
None
: This is the default option when Authentication is not supplied. No explicit authentication will be used.Basic
: Requires Credential. The credentials will be used to send an RFC 7617 Basic AuthenticationAuthorization: Basic
header in the format ofbase64(user:password)
.Bearer
: Requires the Token parameter. Sends an RFC 6750Authorization: Bearer
header with the supplied token.OAuth
: Requires the Token parameter. Sends an RFC 6750Authorization: Bearer
header with the supplied token.Supplying Authentication overrides any
Authorization
headers supplied to Headers or included in WebSession.This feature was added in PowerShell 6.0.0.
PowerShell <= v5.1
You have to do perform your authentication manually through the headers. Example for Basic Authentication
:
$base64Creds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($Credential.UserName):$($Credential.GetNetworkCredential().Password)"))
# And then add the following key-value-pair to your headers hash table:
headers = @{Authorization="Basic $base64Creds";...