Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start trying to remove graph api sdk dependency #1003

Open
wants to merge 76 commits into
base: dev
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
2fbaeb4
Switch caught exception usage
quails4Eva Apr 1, 2024
9626e86
Replace graph api sdk usage with http client usage
quails4Eva Apr 1, 2024
d3867f1
Update version of System.Text.Json used
quails4Eva May 15, 2024
22297cc
Replace Newtonsoft.Json with system.text.json
quails4Eva May 15, 2024
280db1d
Update Microsoft.Bcl.AsyncInterfaces
quails4Eva May 15, 2024
5c1b2ff
Re-use existing item group
quails4Eva May 15, 2024
c0098e4
Replace some graph api exception usage
quails4Eva May 15, 2024
6c45fdf
Add async version of MakeHttpRequest
quails4Eva May 15, 2024
c137c80
Replace a delete group usage
quails4Eva May 15, 2024
014dd41
Throw more specific exception when http error
quails4Eva May 15, 2024
68c6983
Replace delete call
quails4Eva May 15, 2024
c7f922f
CreateSubscription to use http client
quails4Eva May 27, 2024
d6a3e24
Update patch
quails4Eva May 27, 2024
5e8d822
Update delete
quails4Eva May 27, 2024
32e7b28
Update ListSubscriptions
quails4Eva May 27, 2024
f2cc5f7
Implement range selection
quails4Eva May 27, 2024
6c7acc9
Remove unused async -> sync
quails4Eva May 27, 2024
e30cd74
Add todo
quails4Eva May 27, 2024
d8d503c
Replace graph api usage
quails4Eva Jun 1, 2024
1484fbc
fix build issue
quails4Eva Jun 1, 2024
4cffde9
Fix build issue
quails4Eva Jun 1, 2024
8d979cf
.
quails4Eva Jun 1, 2024
a1b75ba
Remove some graph api usage
quails4Eva Jun 1, 2024
62fbf58
Remove graph api usage from Delete Group
quails4Eva Jun 1, 2024
4a1baaa
Remove unused code
quails4Eva Jun 1, 2024
cd6f09d
Maintain stack info
quails4Eva Jun 1, 2024
f9e6df3
Fix exception type
quails4Eva Jun 1, 2024
3a6104e
Update InviteGuestUser to not use graph nuget
quails4Eva Jun 1, 2024
f174b41
Remove unused task.run
quails4Eva Jun 1, 2024
e50af31
Tidy exception handling
quails4Eva Jun 8, 2024
a35d919
Replace graph api usage
quails4Eva Jun 8, 2024
54f6f4b
Rename group
quails4Eva Jul 20, 2024
321fc21
Update GetUnifiedGroup to not use grapn api sdk
quails4Eva Jul 20, 2024
2ea945c
Replace GetGroups graph api sdk usage
quails4Eva Jul 20, 2024
b03a32a
Replace Graph SDK in Create Group
quails4Eva Sep 29, 2024
476a0b8
Fix exception handling
quails4Eva Sep 29, 2024
5ce9af3
Don't use Graph SDK for RemoveGroupMembers
quails4Eva Sep 29, 2024
e2b4910
Remove unused code
quails4Eva Sep 29, 2024
e4aaf0a
Remove Graph SDK from RemoveGroupOwners
quails4Eva Sep 29, 2024
8b3e3ef
change naming
quails4Eva Sep 29, 2024
05403d5
Fix UpdateGroup setup
quails4Eva Sep 29, 2024
ad6ef23
Start updating UpdateMembers to use less Graph SDK
quails4Eva Sep 29, 2024
2435d06
Reduce Graph SDK use in UpdateOwners
quails4Eva Sep 29, 2024
a634d10
Remove direct use of Graph SDK from UpdateGroup
quails4Eva Sep 29, 2024
e95beaa
Replace direct Graph SDK usage in UpdateGroup
quails4Eva Sep 29, 2024
4b0fd00
Add helper method for reading paged data
quails4Eva Nov 17, 2024
769b909
Iterate paged owners and members without graph api sdk
quails4Eva Nov 17, 2024
62939e2
Remove unused ref to graph client and update exception type
quails4Eva Nov 17, 2024
12e30fe
Remaining GroupsUtility code to not use Graph SDK, allow custom deser…
quails4Eva Nov 17, 2024
301d6e7
Tidy async and tasks
quails4Eva Nov 17, 2024
ffc0d5e
Remove unused consts
quails4Eva Nov 17, 2024
cf619ed
Copy some methods from GroupsUtility to UnifiedGroupsUtility
quails4Eva Nov 17, 2024
25783a5
Copy some code from Group to UnifiedGroup utility
quails4Eva Nov 17, 2024
29bfccb
Get user ids without graph api sdk
quails4Eva Nov 23, 2024
2994cb9
Convert UpdateUnifiedGroup to not use Graph Api SDK
quails4Eva Nov 23, 2024
60293ae
Add missing content type
quails4Eva Nov 23, 2024
c2dcfcc
Use const for json content type
quails4Eva Nov 23, 2024
ac75bbd
Update Renew to not use Graph Api SDK
quails4Eva Nov 23, 2024
cac4566
Update CreateUnifiedGroup to not use Graph Api SDK
quails4Eva Nov 23, 2024
f373293
ListUnifiedGroups to not use Graph Api SDK
quails4Eva Nov 23, 2024
bb97d36
GetUnifiedGroups to not use Graph Api SDK
quails4Eva Nov 23, 2024
7ed9e96
GetUnifiedGroupMembers to not us MS Graph SDK
quails4Eva Dec 7, 2024
af15c73
Same for owners
quails4Eva Dec 7, 2024
6f99942
Remove unused code
quails4Eva Dec 7, 2024
ebbae7a
Update GetNestedUnifiedGroupMembers
quails4Eva Dec 7, 2024
6099479
Remove unused code
quails4Eva Dec 7, 2024
3cdc1a1
ListUsers to not use MS Graph Api SDK
quails4Eva Dec 7, 2024
6df9841
Fix start and end index
quails4Eva Dec 7, 2024
5355b6f
Replace use of MS Graph Api SDK
quails4Eva Dec 7, 2024
6a3d2e9
Remove PnPHttpProvider
quails4Eva Dec 7, 2024
b0ceb5c
Re-use json options
quails4Eva Dec 7, 2024
2372b67
Merge
quails4Eva Dec 7, 2024
a5d6613
Remove extra package added
quails4Eva Dec 7, 2024
81db6cc
Remove Microsoft.Graph package
quails4Eva Jan 11, 2025
47a75b0
Minor updates
quails4Eva Jan 11, 2025
281de1f
Remove Microsoft.Graph.Core
quails4Eva Jan 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Iterate paged owners and members without graph api sdk
quails4Eva committed Nov 17, 2024
commit 769b909838a6a923503d3a8ac122a41c05e2fa87
110 changes: 40 additions & 70 deletions src/lib/PnP.Framework/Graph/GroupsUtility.cs
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ public static GroupEntity CreateGroup(string displayName, string description, st
/// <param name="graphClient">GraphClient instance to use to communicate with the Microsoft Graph</param>
/// <param name="groupId">Id of the group which needs the owners added</param>
/// <param name="removeOtherMembers">If set to true, all existing members which are not specified through <paramref name="members"/> will be removed as a member from the group</param>
private static async Task UpdateMembers(string[] members, GraphServiceClient graphClient, string groupId, bool removeOtherMembers, string accessToken, int retryCount, int delay, AzureEnvironment azureEnvironment)
private static async Task UpdateMembers(string[] members, string groupId, bool removeOtherMembers, string accessToken, int retryCount, int delay, AzureEnvironment azureEnvironment)
{
var userRequestUrl = $"{GraphHttpClient.GetGraphEndPointUrl(azureEnvironment)}users";
var groupRequestUrl = $"{GraphHttpClient.GetGraphEndPointUrl(azureEnvironment)}groups/{groupId}";
@@ -174,38 +174,25 @@ private static async Task UpdateMembers(string[] members, GraphServiceClient gra
return;
}

// Remove any leftover member
var fullListOfMembers = await graphClient.Groups[groupId].Members.Request().Select("userPrincipalName, Id").GetAsync();
var pageExists = true;

while (pageExists)
// Remove any leftover members
var listMembersUrl = $"{groupRequestUrl}/members/microsoft.graph.user?$select=id,userPrincipalName";
var allMembersInGroup = GraphUtility.ReadPagedDataFromRequest<Model.User>(listMembersUrl, accessToken, retryCount, delay);
foreach (var member in allMembersInGroup)
{
foreach (var member in fullListOfMembers)
var currentMemberPrincipalName = member.UserPrincipalName;
if (!string.IsNullOrEmpty(currentMemberPrincipalName) &&
!members.Contains(currentMemberPrincipalName, StringComparer.InvariantCultureIgnoreCase))
{
var currentMemberPrincipalName = (member as Microsoft.Graph.User)?.UserPrincipalName;
if (!string.IsNullOrEmpty(currentMemberPrincipalName) &&
!members.Contains(currentMemberPrincipalName, StringComparer.InvariantCultureIgnoreCase))
try
{
try
{
// If it is not in the list of current members, just remove it
var memberUrl = $"{groupRequestUrl}/members/{member.Id}/ref";
HttpHelper.MakeDeleteRequest(memberUrl, accessToken, retryCount: retryCount, delay: delay);
}
catch (HttpResponseException ex) when (ex.StatusCode == 400)
{
// Skip any failing removal
}
// If it is not in the list of current members, just remove it
var memberUrl = $"{groupRequestUrl}/members/{member.Id}/ref";
HttpHelper.MakeDeleteRequest(memberUrl, accessToken, retryCount: retryCount, delay: delay);
}
catch (HttpResponseException ex) when (ex.StatusCode == 400)
{
// Skip any failing removal
}
}

if (fullListOfMembers.NextPageRequest != null)
{
fullListOfMembers = await fullListOfMembers.NextPageRequest.GetAsync();
}
else
{
pageExists = false;
}
}
}
@@ -217,7 +204,7 @@ private static async Task UpdateMembers(string[] members, GraphServiceClient gra
/// <param name="graphClient">GraphClient instance to use to communicate with the Microsoft Graph</param>
/// <param name="groupId">Id of the group which needs the owners added</param>
/// <param name="removeOtherOwners">If set to true, all existing owners which are not specified through <paramref name="owners"/> will be removed as an owner from the group</param>
private static async Task UpdateOwners(string[] owners, GraphServiceClient graphClient, string groupId, bool removeOtherOwners, string accessToken, int retryCount, int delay, AzureEnvironment azureEnvironment)
private static async Task UpdateOwners(string[] owners, string groupId, bool removeOtherOwners, string accessToken, int retryCount, int delay, AzureEnvironment azureEnvironment)
{
var userRequestUrl = $"{GraphHttpClient.GetGraphEndPointUrl(azureEnvironment)}users";
var groupRequestUrl = $"{GraphHttpClient.GetGraphEndPointUrl(azureEnvironment)}groups/{groupId}";
@@ -254,37 +241,24 @@ private static async Task UpdateOwners(string[] owners, GraphServiceClient graph
}

// Remove any leftover owner
var fullListOfOwners = await graphClient.Groups[groupId].Owners.Request().Select("userPrincipalName, Id").GetAsync();
var pageExists = true;

while (pageExists)
var listOwnersUrl = $"{groupRequestUrl}/members/microsoft.graph.user?$select=id,userPrincipalName";
var allOwnersInGroup = GraphUtility.ReadPagedDataFromRequest<Model.User>(listOwnersUrl, accessToken, retryCount, delay);
foreach (var owner in allOwnersInGroup)
{
foreach (var owner in fullListOfOwners)
var currentOwnerPrincipalName = owner.UserPrincipalName;
if (!string.IsNullOrEmpty(currentOwnerPrincipalName) &&
!owners.Contains(currentOwnerPrincipalName, StringComparer.InvariantCultureIgnoreCase))
{
var currentOwnerPrincipalName = (owner as Microsoft.Graph.User)?.UserPrincipalName;
if (!string.IsNullOrEmpty(currentOwnerPrincipalName) &&
!owners.Contains(currentOwnerPrincipalName, StringComparer.InvariantCultureIgnoreCase))
try
{
try
{
// If it is not in the list of current owners, just remove it
var memberUrl = $"{groupRequestUrl}/owners/{owner.Id}/ref";
HttpHelper.MakeDeleteRequest(memberUrl, accessToken, retryCount: retryCount, delay: delay);
}
catch (HttpResponseException ex) when (ex.StatusCode == 400)
{
// Skip any failing removal
}
// If it is not in the list of current owners, just remove it
var memberUrl = $"{groupRequestUrl}/owners/{owner.Id}/ref";
HttpHelper.MakeDeleteRequest(memberUrl, accessToken, retryCount: retryCount, delay: delay);
}
catch (HttpResponseException ex) when (ex.StatusCode == 400)
{
// Skip any failing removal
}
}

if (fullListOfOwners.NextPageRequest != null)
{
fullListOfOwners = await fullListOfOwners.NextPageRequest.GetAsync();
}
else
{
pageExists = false;
}
}
}
@@ -362,8 +336,6 @@ public static bool UpdateGroup(string groupId,
// Use a synchronous model to invoke the asynchronous process
result = Task.Run(async () =>
{
var graphClient = CreateGraphClient(accessToken, retryCount, delay, azureEnvironment);

var responseAsString = HttpHelper.MakeGetRequestForString(groupRequestUrl, accessToken, retryCount: retryCount, delay: delay);
var groupJson = JsonNode.Parse(responseAsString);
var groupToUpdate = groupJson.Deserialize<Model.Group>();
@@ -397,15 +369,15 @@ public static bool UpdateGroup(string groupId,
if (owners != null && owners.Length > 0)
{
// For each and every owner
await UpdateOwners(owners, graphClient, groupToUpdate.GroupId, true, accessToken, retryCount, delay, azureEnvironment);
await UpdateOwners(owners, groupToUpdate.GroupId, true, accessToken, retryCount, delay, azureEnvironment);
updateGroup = true;
}

// Check if we need to update members
if (members != null && members.Length > 0)
{
// For each and every owner
await UpdateMembers(members, graphClient, groupToUpdate.GroupId, true, accessToken, retryCount, delay, azureEnvironment);
await UpdateMembers(members, groupToUpdate.GroupId, true, accessToken, retryCount, delay, azureEnvironment);
updateGroup = true;
}

@@ -562,13 +534,13 @@ public static List<GroupEntity> GetGroups(string accessToken,
{
break;
}
if (currentIndex >= startIndex)
{
groups.Add(g.AsEntity());
}
currentIndex++;
if (currentIndex >= startIndex)
{
groups.Add(g.AsEntity());
}
currentIndex++;
}
}
catch (HttpResponseException ex)
{
Log.Error(Constants.LOGGING_SOURCE, CoreResources.GraphExtensions_ErrorOccured, ex.Message);
@@ -691,7 +663,7 @@ public static void AddGroupOwners(string groupId, string[] owners, string access
{
var graphClient = CreateGraphClient(accessToken, retryCount, delay, azureEnvironment);

await UpdateOwners(owners, graphClient, groupId, removeExistingOwners, accessToken, retryCount, delay, azureEnvironment);
await UpdateOwners(owners, groupId, removeExistingOwners, accessToken, retryCount, delay, azureEnvironment);

}).GetAwaiter().GetResult();
}
@@ -723,9 +695,7 @@ public static void AddGroupMembers(string groupId, string[] members, string acce
{
Task.Run(async () =>
{
var graphClient = CreateGraphClient(accessToken, retryCount, delay, azureEnvironment);

await UpdateMembers(members, graphClient, groupId, removeExistingMembers, accessToken, retryCount, delay, azureEnvironment);
await UpdateMembers(members, groupId, removeExistingMembers, accessToken, retryCount, delay, azureEnvironment);

}).GetAwaiter().GetResult();
}