Skip to content

Instantly share code, notes, and snippets.

@angelobelchior
Last active January 6, 2023 14:13
Show Gist options
  • Save angelobelchior/9182808d82d79ba15d86ecf8fe1f1a51 to your computer and use it in GitHub Desktop.
Save angelobelchior/9182808d82d79ba15d86ecf8fe1f1a51 to your computer and use it in GitHub Desktop.
Setar permissões para um usuário em um repo az dev
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
var pat = "abc123";
var organization = "my_org";
var projectName = "my_project";
var userEmail = "[email protected]";
var repositoryUrl = $"https://dev.azure.com/{organization}/{projectName}/_apis/git/repositories";
var repositoryId = await GetRepositoryId();
var usersUrl = $"https://vssps.dev.azure.com/{organization}/_apis/identities?searchFilter=General&filterValue={{0}}&api-version=7.0";
var userId = await GetUserId(userEmail);
var securityUrl = $"https://dev.azure.com/{organization}/_apis/securitynamespaces?api-version=7.0";
var securityNamespaceId = await GetSecurityNamespaceId();
var accessControlEntriesUrl = $"https://dev.azure.com/{organization}/_apis/AccessControlEntries/{securityNamespaceId}";
await SetPermissions(accessControlEntriesUrl, projectName, repositoryId, userId);
Console.ReadLine();
async Task SetPermissions(string url, string projectName, string repositoryId, string userId)
{
//Se passar as duas permissões no AccessControlEntry não funciona... ele aplica apenas a última do array :/
var request2048 = PermissionRequest.Create(projectName, repositoryId, userId, 2048 /*Edit Policies*/);
var permissionResponse2048 = await Post<PermissionRequest, PermissionResponse>(url, request2048);
Console.WriteLine(permissionResponse2048);
var request8192 = PermissionRequest.Create(projectName, repositoryId, userId, 8192 /*Manage Permissions*/);
var permissionResponse8192 = await Post<PermissionRequest, PermissionResponse>(url, request8192);
Console.WriteLine(request8192);
}
async Task<string> GetSecurityNamespaceId()
{
const string securityNamespaceName = "Git Repositories";
Console.WriteLine($"GET {securityUrl} - {securityNamespaceName}");
var result = await Get<ResultCollection<SecurityNamespace>>(securityUrl);
return result?.Value?.FirstOrDefault(x => x.Name.Equals(securityNamespaceName, StringComparison.CurrentCultureIgnoreCase))
?.NamespaceId ?? string.Empty;
}
async Task<string> GetRepositoryId()
{
Console.WriteLine($"GET {repositoryUrl}");
var result = await Get<ResultCollection<Respository>>(repositoryUrl);
return result?.Value?.FirstOrDefault()?.Id ?? string.Empty;
}
async Task<string> GetUserId(string userEmail)
{
var url = string.Format(usersUrl, userEmail);
Console.WriteLine($"GET {url}");
var result = await Get<ResultCollection<User>>(url);
return result?.Value?.FirstOrDefault()?.Descriptor ?? string.Empty;
}
async Task<T?> Get<T>(string url)
{
using var client = CreateHttpClient();
var response = await client.GetAsync(url);
var json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<T>(json);
return result;
}
async Task<TResponse?> Post<TRequest, TResponse>(string url, TRequest content)
{
using var client = CreateHttpClient();
var json = JsonSerializer.Serialize<TRequest>(content);
var httpContent = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, httpContent);
json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<TResponse>(json);
return result;
}
HttpClient CreateHttpClient()
{
var patBytes = Encoding.ASCII.GetBytes($":{pat}");
var base64 = Convert.ToBase64String(patBytes);
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", base64);
return client;
}
public record ResultCollection<T>(
[property: JsonPropertyName("value")] T[] Value,
[property: JsonPropertyName("count")] int Count);
public record Respository(
[property: JsonPropertyName("id")] string Id,
[property: JsonPropertyName("name")] string Name);
public record User(
[property: JsonPropertyName("id")] string Id,
[property: JsonPropertyName("descriptor")] string Descriptor,
[property: JsonPropertyName("subjectDescriptor")] string SubjectDescriptor,
[property: JsonPropertyName("providerDisplayName")] string ProviderDisplayName,
[property: JsonPropertyName("customDisplayName")] string CustomDisplayName
);
public record SecurityNamespace(
[property: JsonPropertyName("namespaceId")] string NamespaceId,
[property: JsonPropertyName("name")] string Name);
public record Project(
[property: JsonPropertyName("id")] string Id,
[property: JsonPropertyName("name")] string Name);
public record PermissionRequest(
[property: JsonPropertyName("token")] string Token,
[property: JsonPropertyName("merge")] bool Merge,
[property: JsonPropertyName("accessControlEntries")] IEnumerable<AccessControlEntry> AccessControlEntries)
{
public static PermissionRequest Create(string projectName, string repositoryId, string userId, int permission)
=> new($"repoV2/{projectName}/{repositoryId}/", true, new[] { AccessControlEntry.Create(userId, permission) });
}
public record AccessControlEntry(
[property: JsonPropertyName("descriptor")] string Descriptor,
[property: JsonPropertyName("allow")] int Allow,
[property: JsonPropertyName("deny")] int Deny,
[property: JsonPropertyName("extendedInfo")] ExtendedInfo EsxtendedInfo)
{
public static AccessControlEntry Create(string descriptor, int permission)
=> new(descriptor, permission, 0, new ExtendedInfo(permission, 0, permission, 0));
}
public record ExtendedInfo(
[property: JsonPropertyName("effectiveAllow")] int EffectiveAllow,
[property: JsonPropertyName("effectiveDeny")] int EffectiveDeny,
[property: JsonPropertyName("inheritedAllow")] int InheritedAllow,
[property: JsonPropertyName("inheritedDeny")] int InheritedDeny);
public record PermissionResponse(
[property: JsonPropertyName("descriptor")] string Descriptor,
[property: JsonPropertyName("allow")] int Allow,
[property: JsonPropertyName("deny")] int Deny);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment