Azure DevOps ServiceConnection Roles Rest API - azure-devops

How can I modify Azure DevOps ServiceConnection Roles using the REST API?
This is the corresponding UI
I want to add a team within the 'User' role.
I have been looking at
https://learn.microsoft.com/en-us/rest/api/azure/devops/security/security%20namespaces?view=azure-devops-rest-5.1
https://learn.microsoft.com/en-us/rest/api/azure/devops/security/access%20control%20lists?view=azure-devops-rest-5.1
is this the right direction?

You can use below api to update security for service connection.
Put https://dev.azure.com/<Org>/_apis/securityroles/scopes/distributedtask.serviceendpointrole/roleassignments/resources/<resourcesId>?api-version=5.1-preview.1"
The API is not documented. But you can find it when you F12 your browser.
You can get the resourceId from the request url in F12 page.
And also from the URL of the Service Connection UI page url and also
Below is example in powershell scripts:
$url="https://dev.azure.com/<org>/_apis/securityroles/scopes/distributedtask.serviceendpointrole/roleassignments/resources/......c5_d69e94f6-9c07-4341-bd6f-8b28e05d4b08?api-version=5.1-preview.1"
$connectionToken ="Personal Access token"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
$body ='[{"roleName":"User","userId":"....a313-31d7848bcdcc"}]'
Invoke-RestMethod -Uri $url -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method put -ContentType "application/json" -Body $body
Above script with assign the user to User role permission for the service connection.
You can get the user id from the request body in F12 page. But you may still need to use below rest api to get the user id
GET https://vssps.dev.azure.com/{organization}/_apis/graph/users/{userDescriptor}?api-version=5.1-preview.1
You can get the userDescriptor from the URL in UI page of the Permission page for each user.

watch out for the url... this contains the ProjectId_ServiceEndpointId
$url="https://dev.azure.com/$OrganizationName/_apis/securityroles/scopes/distributedtask.serviceendpointrole/roleassignments/resources/$($ProjectId)_$($ServiceEndpointId)?api-version=5.1-preview.1"
ProjectId from
https://dev.azure.com/$OrganizatioName/_apis/projects?api-version=5.1
UserId from [property: originId]
https://vssps.dev.azure.com/$OrganizatioName/_apis/graph/groups?api-version=5.1-preview.1
ServiceEndpointId from
https://dev.azure.com/$OrganizatioName/$ProjectId/_apis/serviceendpoint/endpoints?api-version=5.1-preview.2

Related

I want to use a System.AccessToken to a rest api call to deploy one release

In Azure Pipeline Releases, I have one task "Azure PowerShell".
This script will do a deployment of another release. In my code, I use a System.AutenticantionToken: "$AzureDevOpsToken = $env:SYSTEM_ACCESSTOKEN" and my headers for a call rest API is:
$basicAuthValue = "Bearer $AzureDevOpsToken"
$headers = #{
Authorization = $basicAuthValue
}
When I ran this code :
$deploymentBody = #{
status = "inProgress"
} | ConvertTo-Json
$urlDeployment = "https://vsrm.dev.azure.com/$Organization/$ProjectName/_apis/Release/releases/$ReleaseId/environments/$EnvironmentId`?api-version=5.1-preview.6"
$deployment = Invoke-WebRequest -Uri $urlDeployment -Method Patch -ContentType "application/json" -Headers $header -UseBasicParsing -Body $deploymentBody
I received an error:
2022-06-01T14:53:15.4901741Z {"$id":"1","customProperties":{"Descriptor":null,"IdentityDisplayName":null,"Token":null,"RequestedPermissions":0,"NamespaceId":"00000000-0000-0000-0000-000000000000"},"innerException":null,"message":"VS402904: Access denied: User e3b793c5-a512-44b7-a704-878e8adb62e9 does not have manage deployments permission. Contact your release manager.","typeName":"Microsoft.VisualStudio.Services.Security.AccessCheckException, Microsoft.VisualStudio.Services.WebApi","typeKey":"AccessCheckException","errorCode":0,"eventId":3000}
This happened when I use a System.AccessToken.
But when I use a Personal Access Token it goes well. But I don't want to use it because I need to put the password in plain sight in the pipeline. So I want to use a System.AccessToken.
In my pipeline, on the agent pool, I have this check: "Allow scripts to access the OAuth token"
Can you help me?
You do not have to use the password plaintext for the personal access token. You can set a variable lets call it PAT on your pipeline with the value as a secret and then inject this variable on your powershell script.
$connectionToken="$(PAT)"
$base64AuthInfo= [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($connectionToken)"))
Then you have to use as a header
-Headers #{authorization = "Basic $base64AuthInfo"}
VS402904: Access denied: User e3b793c5-a512-44b7-a704-878e8adb62e9 does not have manage deployments permission.
Based on the error message, it means that the service account has no access to manage the deployment.
The variable: $(system.accesstoken) will create a token based on the permissions of the service account: {Project Name} Build Service ({Org Name}).
Refer to this doc: Scoped build identities
To solve this issue, you need to navigate to Piplines -> Release -> Security and grant the Manage Deployments permission to the service account: {Project Name} Build Service ({Org Name}).
For example:

Create folder in user mailbox with Graph API

want to use the Graph API to create a folder in a user's mailbox that exists in Exchange Online.
As a result of the investigation, if I use "https://graph.microsoft.com/v1.0/users/testuser01#domain.com/mailFolders", I feel that it is possible, but an error is displayed and I cannot create it.
Currently, "Exchange> Mail.ReadWrite, MailboxSettings.ReadWrite" is assigned to the execution user (admin).
However, it says "Access is denied. Check credentials and try again." Is the permission wrong?
Or is the specified URL incorrect?
Sorry to trouble you, but thank you for your response.
【Append】
$body = #{
grant_type="client_credentials"
resource=$resource
client_id=$ClientID
client_secret=$ClientSecret
}
`#Get Token
$oauth = Invoke-RestMethod -Method Post -Uri $loginURL/$TenantName/oauth2/token -Body $body
API Permissions
You are using the client credential flow to get the token to call Microsoft Graph - Create MailFolder, so you need to add the Application permission Mail.ReadWrite of Micrsoft Graph to your AD App.
1.Add the Application permission Mail.ReadWrite like below.
2.Click the Grant admin consent for xxx button, and make sure the $resource in your request is https://graph.microsoft.com.
Update:
Here is a powershell sample to call Create MailFolder API to create MailFolder.
$uri = "https://graph.microsoft.com/v1.0/users/joyw#xxxxx.onmicrosoft.com/mailFolders"
$headers = #{
'Content-Type' = 'application/json'
'Authorization' = 'Bearer <access-token-here>'
}
$body = ConvertTo-Json #{
"displayName" = "testfolder1"
}
Invoke-RestMethod -Method Post -Uri $uri -Headers $headers -Body $body
Check the result in the Graph Explorer with List mailFolders:

Permissions required for these TFS (on premise) REST urls?

I am trying to automate some jobs that require information about agent pools and agents and while the job script works just fine for regular users of my TFS collection it fails miserably for a service account.
My job script tries to access urls
http://<instance>/<collection>/_apis/distributedtask/pools
http://<instance>/<collection>/_apis/distributedtask/pools/<pool>/agents
Initially my service account got a response like
TF400813: The user '<service account>' is not authorized to access this resource
The service account was previously not member of any TFS related AD group but after creating a new group and adding it to 'Project Collection Valid Users' the call does not fail but the response does not include any pool information still.
If I modify the service account interactive logins the GUI for agents in the agent pool shows no information but the hint
no agents are registered or you do not have permission to view the agents
suggests that permission is missing.
I have tried to add the service account to various groups in TFS like Project Collection Administrators, Project Collection Build Administrators, etc. all to no avail.
So in short, what permissions does a service account need to retrieve information from the urls mentioned in the start?
I can reproduce this issue, it does not work even change the regular users as the service account.
So, as a workaround for now you can call the REST API using the regular users or PAT in your script.
Below PowerShell script works for me:
$user = "Domain\username"
$token = "password"
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
$uri = "http://SERVER:8080/tfs/_apis/distributedtask/pools/1/agents/5"
$result = Invoke-RestMethod -Uri $uri -Method Get -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
Write-Host "result = $($result | ConvertTo-Json -Depth 100)"

How to use Release Definition REST API for VSTS?

I have been successfully able to use Release Definition API on our TFS 2015 Update 3 on prem instance using API Version "3.0-preview.1". But ever since I started testing this on VSTS, I am continuously getting a 404 error stating
Page not found And a long block of HTML.
I am using PowerShell to call the API. And I am creating the API request as mentioned in the documentation using Personal Access Token and Alternate credential method.
https://fabfiber.vsrm.visualstudio.com/DefaultCollection/ff213d65-d61d-447c-b39d-d16f21b18364/_apis/release/definitions?api-version=3.0-preview.1
Can someone let me know if I am missing something.
Try this code:
$vstsAccount = "[your vsts name]"
$user = "test"
$accessToken="[personal access token]"
$teamProject="[team project name]"
Function QueryWorkItem{
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$accessToken)))
$uri="https://$vstsAccount.vsrm.visualstudio.com/defaultcollection/$teamProject/_apis/release/definitions?api-version=3.0-preview.1"
$result = Invoke-RestMethod -Uri $uri -Method Get -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
}
You may refer the blog :-
https://blogs.msdn.microsoft.com/chandananjani/2016/04/15/using-releasemanagement-rest-apis/
https://blogs.msdn.microsoft.com/chandananjani/2016/04/27/using-releasehttpclient-for-interacting-with-releasemanagement-service/
as well to know as how to use the release management REST API's.

How do I use a server apiKey with Chrome Store API?

I generated an server key for Chrome Store API in the Developer Dashboard. I would like to publish a .zip file containing my extension programmatically. The instructions in https://developer.chrome.com/webstore/using_webstore_api show OAuth, Bearer token authentication. How can I use the server key instead?
Things I tried: header "X-ApiKey" = "$apiKey", adding ?key=$apiKey, etc.
In all cases
{"error":{"errors":[{"domain":"global","reason":"required","message":"Login
Required","locationType":"header","location":"Authorization"}],"code":401,"message":"Login
Required"}}
For this example I have been using Powershell Invoke-RestMethod
$headers = #{
"X-ApiKey" = $apiKey
"X-Goog-Api-Version" = "2"
}
$endpoint = "https://www.googleapis.com/upload/chromewebstore/v1.1/items/$appId/?key=$apiKey"
Write-Host $endpoint
$response = Invoke-RestMethod $endpoint -Method Put -InFile $filePath -Headers $headers
More docs, and no clues - https://developer.chrome.com/webstore/api_index
You can't. API keys are only used to access public data. To use the Chrome Store API, you must authenticate as the user who you wish to publish the app as and, thus, you must supply an OAuth token. Check out the OAuth 2.0 Playground for an example of how to get an OAuth token.