private async Task <bool> useIdentityPicker(HttpClient httpClient, string organization, string groupId, SubjectQueryResponse_Value groupSubjectQueryResponse, string memberId, string uniqueName) { if (groupSubjectQueryResponse == null) { Log.LogWarning("useIdentityPicker-> GroupSubjectQueryResponse is empty"); return(false); } Log.LogInformation("useIdentityPicker-> groupId: {0}", groupId); Log.LogInformation("useIdentityPicker-> memberId: {0}", memberId); Log.LogInformation("useIdentityPicker-> uniqueName: {0}", uniqueName); string parsedOrganization = MigrationTools.Helpers.UriHelpers.GetOrganization(organization); string url = $"https://dev.azure.com/{parsedOrganization}/_apis/IdentityPicker/Identities?api-version=5.0-preview.1"; var resultOptions = new Dictionary <string, int>(); resultOptions.Add("MinResults", 5); resultOptions.Add("MaxResults", 20); var body = new { query = uniqueName, identityTypes = new string[] { "user" }, operationScopes = new string[] { "ims", "source" }, options = resultOptions }; DefaultContractResolver contractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }; var jsonSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, ContractResolver = contractResolver, }; StringContent stringContent = new StringContent(JsonConvert.SerializeObject(body, jsonSettings), Encoding.UTF8, "application/json"); var result = await httpClient.PostAsync(url, stringContent); if (result.IsSuccessStatusCode) { string resultContent = await result.Content.ReadAsStringAsync(); var identities = JsonConvert.DeserializeObject <IdentityQueryResponse>(resultContent); //Log.LogInformation("useIdentityPicker-> resultContent: {0}", resultContent); if (identities.results != null && identities.results.Length != 0 && identities.results[0].identities != null && identities.results[0].identities.Length != 0) { string groupDescriptor = groupSubjectQueryResponse.descriptor; url = $"https://vssps.dev.azure.com/{parsedOrganization}/_apis/graph/users?groupDescriptors={groupDescriptor}&api-version=5.2-preview.1"; var addUserBody = new { origin = "aad", originId = identities.results[0].identities[0].originId, storageKey = "" }; stringContent = new StringContent(JsonConvert.SerializeObject(addUserBody, jsonSettings), Encoding.UTF8, "application/json"); result = await httpClient.PostAsync(url, stringContent); if (result.IsSuccessStatusCode) { return(true); } } } return(false); }
private async Task <bool> addTeamMember(HttpClient httpClient, string organization, string groupId, string memberId, string uniqueName, SubjectQueryResponse_Value groupDescriptor, bool useFallback = true) { string url = string.Format("https://vsaex.dev.azure.com/{0}/_apis/GroupEntitlements/{1}/members/{2}?api-version=6.1-preview.1" , MigrationTools.Helpers.UriHelpers.GetOrganization(organization), groupId, memberId); var content = new StringContent(string.Empty, Encoding.UTF8, "application/json"); var res = await httpClient.PutAsync(url, content); if (res.IsSuccessStatusCode == false) { if (useFallback == true) { if (await useIdentityPicker(httpClient, organization, groupId, groupDescriptor, memberId, uniqueName) == false) { Log.LogWarning("-> FAILED to add team member (with fallback): {0}", await res.Content.ReadAsStringAsync()); return(false); } } else { Log.LogWarning("-> FAILED to add team member: {0}", await res.Content.ReadAsStringAsync()); return(false); } } return(true); }