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);
            }
        }
Example #3
0
        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);
                }
            }
        }