static async Task Main(string[] args) { Guid from = Guid.Parse(args[0]); Guid to = Guid.Parse(args[1]); string serviceBusNamespace = args[2]; Console.WriteLine($"Syncing members from group ID {from} to group ID {to}."); var publicClientApp = PublicClientApplicationBuilder.Create(ClientId) .WithRedirectUri("http://localhost") .WithAuthority(AzureCloudInstance.AzurePublic, Tenant) .Build(); var repo = new GraphGroupRepository(new InteractiveAuthenticationProvider(publicClientApp), new Logger()); var sbqueue = new MembershipServiceBusRepository(serviceBusNamespace, "membership"); var stopwatch = Stopwatch.StartNew(); await sbqueue.SendMembership(new GroupMembership { Sources = new[] { new AzureADGroup { ObjectId = from } }, Destination = new AzureADGroup { ObjectId = to }, SourceMembers = await repo.GetUsersInGroupTransitively(from) }); stopwatch.Stop(); Console.WriteLine($"Enqueued all users in group {from} in {stopwatch.Elapsed.TotalSeconds} seconds."); }
public static async Task CreateGraphRepository(TestContext _) { if (!RunTests) { Assert.Inconclusive("Tests not run because I assume this is in contiguous integration. Set RunTests to true if this is not the case."); } var publicClientApp = PublicClientApplicationBuilder.Create(ClientId) .WithRedirectUri("http://localhost") .WithAuthority(AzureCloudInstance.AzurePublic, Tenant) .Build(); var authProvider = new InteractiveAuthenticationProvider(publicClientApp); _graphServiceClient = new GraphServiceClient(authProvider); _groupRepo = new GraphGroupRepository(_graphServiceClient, new MockLogger()); await DeleteOldObjects("microsoft.graph.group"); await DeleteOldObjects("microsoft.graph.user"); // not the most efficient, but writing all the batching logic to add a bunch of users is a pain // we don't delete the users after, so this only has to be done once anyways. var users = await _graphServiceClient.Users.Request().Filter("startswith(MailNickname, 'testuser')").GetAsync(); HandleExistingUsers(users.CurrentPage); while (users.NextPageRequest != null) { users = await users.NextPageRequest.GetAsync(); HandleExistingUsers(users.CurrentPage); } try { for (int i = 0; i < _testUsers.Length; i++) { if (_testUsers[i] == null) { await AddNewUser(i); } } } catch (ServiceException ex) { Assert.Fail("Failed creating user. This happens sometimes. Please run the tests again and it'll pick up where it left off. Exception: {0}", ex); } }
static async Task Main(string[] args) { var publicClientApp = PublicClientApplicationBuilder.Create(ClientId) .WithRedirectUri("http://localhost") .WithAuthority(AzureCloudInstance.AzurePublic, Tenant) .Build(); var repo = new GraphGroupRepository(new InteractiveAuthenticationProvider(publicClientApp), new Logger()); bool compareGroups = args.Length == 2; var users = new List <HashSet <AzureADUser> >(); var cycles = new List <SecurityGroupCycle>(); foreach (var groupToTraverse in args.Select(x => Guid.Parse(x))) { Console.WriteLine("Checking group: " + groupToTraverse); if (await repo.GroupExists(groupToTraverse) == false) { Console.WriteLine($"{groupToTraverse} doesn't exist. Skipping."); continue; } var crawler = new SGCrawler(repo); var crawlerUsers = new ConcurrentDictionary <AzureADUser, byte>(); var crawlerGroups = new ConcurrentBag <AzureADGroup>(); var crawlerCycles = new ConcurrentBag <SecurityGroupCycle>(); crawler.FoundUserAction = (user) => { crawlerUsers.TryAdd(user, 0); }; crawler.FoundGroupAction = (group) => { crawlerGroups.Add(group); }; crawler.FoundGroupCycleAction = (cycle) => { crawlerCycles.Add(cycle); }; var stopwatch = Stopwatch.StartNew(); await crawler.CrawlGroup(new AzureADGroup { ObjectId = groupToTraverse }); stopwatch.Stop(); Console.WriteLine($"Found {crawlerUsers.Count} total ({crawlerUsers.Keys.Distinct().Count()} distinct) users in {crawlerGroups.Count} total ({crawlerGroups.Distinct().Count()} distinct) nested groups in {stopwatch.ElapsedMilliseconds} ms."); Console.WriteLine($"Found {crawlerCycles.Count} cycles."); if (crawlerCycles.Any()) { cycles.AddRange(crawlerCycles); foreach (var cycle in crawlerCycles) { Console.WriteLine(cycle); } } if (compareGroups) { users.Add(new HashSet <AzureADUser>(crawlerUsers.Keys)); } } if (compareGroups && users.Count == 2) { Console.WriteLine($"The following users are in {args[0]} but not {args[1]}:"); Console.WriteLine(string.Join(Environment.NewLine, users[0].Except(users[1]))); Console.WriteLine($"The following users are in {args[1]} but not {args[0]}:"); Console.WriteLine(string.Join(Environment.NewLine, users[1].Except(users[0]))); } if (cycles.Any()) { Console.WriteLine($"Found {cycles.Count} cycles across all groups checked."); foreach (var cycle in cycles) { Console.WriteLine(cycle); } } }