示例#1
0
        private static async Task RunAsync(string orgName, string outputFileName, string cacheLocation)
        {
            var isForExcel = outputFileName == null;

            var client = await GitHubClientFactory.CreateAsync();

            var cachedOrg = await CachedOrg.LoadAsync(client, orgName, Console.Out, cacheLocation, forceUpdate : false);

            var csvDocument = new CsvDocument("repo", "repo-state", "repo-last-pushed", "principal-kind", "principal", "permission", "via-team");

            using (var writer = csvDocument.Append())
            {
                foreach (var repo in cachedOrg.Repos)
                {
                    var publicPrivate = repo.IsPrivate ? "private" : "public";
                    var lastPush      = repo.LastPush.ToLocalTime().DateTime.ToString();

                    foreach (var teamAccess in repo.Teams)
                    {
                        var permissions = teamAccess.Permission.ToString().ToLower();
                        var teamName    = teamAccess.Team.Name;
                        var teamUrl     = teamAccess.Team.Url;

                        writer.WriteHyperlink(repo.Url, repo.Name, isForExcel);
                        writer.Write(publicPrivate);
                        writer.Write(lastPush);
                        writer.Write("team");
                        writer.WriteHyperlink(teamUrl, teamName, isForExcel);
                        writer.Write(permissions);
                        writer.Write(teamName);
                        writer.WriteLine();
                    }

                    foreach (var userAccess in repo.Users)
                    {
                        var via         = userAccess.Describe().ToString();
                        var userUrl     = CachedOrg.GetUserUrl(userAccess.UserLogin);
                        var permissions = userAccess.Permission.ToString().ToLower();

                        writer.WriteHyperlink(repo.Url, repo.Name, isForExcel);
                        writer.Write(publicPrivate);
                        writer.Write(lastPush);
                        writer.Write("user");
                        writer.WriteHyperlink(userUrl, userAccess.UserLogin, isForExcel);
                        writer.Write(permissions);
                        writer.Write(via);
                        writer.WriteLine();
                    }
                }
            }

            if (outputFileName == null)
            {
                csvDocument.ViewInExcel();
            }
            else
            {
                csvDocument.Save(outputFileName);
            }
        }
示例#2
0
        private static IReadOnlyCollection <CachedUser> ComputeAssignees(CachedOrg org, CachedRepo repo, CachedTeam team, CachedUser user, IReadOnlyCollection <CachedUser> assignees)
        {
            if (assignees != null && assignees.Count > 0)
            {
                return(assignees);
            }

            if (repo != null)
            {
                return(repo.GetAdministrators().ToArray());
            }

            if (team != null)
            {
                return(team.GetMaintainers().ToArray());
            }

            if (user != null)
            {
                return new[] { user }
            }
            ;

            return(org.GetOwners().ToArray());
        }
示例#3
0
 public PolicyViolation(PolicyDescriptor descriptor,
                        string title,
                        string body,
                        CachedOrg org,
                        CachedRepo repo = null,
                        CachedTeam team = null,
                        CachedUser user = null,
                        IReadOnlyCollection <CachedUser> assignees = null)
 {
     Descriptor  = descriptor;
     Fingerprint = ComputeFingerprint(descriptor.DiagnosticId, repo, user, team);
     Title       = title;
     Body        = UnindentAndTrim(body);
     Org         = org;
     Repo        = repo;
     Team        = team;
     User        = user;
     Assignees   = ComputeAssignees(org, repo, team, user, assignees);
 }
示例#4
0
        private static async Task RunAsync(string orgName, string outputFileName, string cacheLocation, string githubToken, string ospoToken, string policyRepo)
        {
            var isForExcel   = outputFileName == null;
            var gitHubClient = await GitHubClientFactory.CreateAsync(githubToken);

            var ospoClient = await OspoClientFactory.CreateAsync(ospoToken);

            var cachedOrg = await CachedOrg.LoadAsync(gitHubClient, orgName, Console.Out, cacheLocation, forceUpdate : false);

            var userLinks = await MicrosoftUserLinks.LoadAsync(ospoClient);

            var context    = new PolicyAnalysisContext(cachedOrg, userLinks);
            var violations = PolicyRunner.Run(context);

            SaveVioloations(orgName, outputFileName, isForExcel, violations);

            if (!string.IsNullOrEmpty(policyRepo))
            {
                await FilePolicyViolationsAsync(gitHubClient, orgName, policyRepo, violations);
            }
        }
示例#5
0
        private static Func <CachedUser, bool> CreateUserFilter(CachedOrg cachedOrg, List <string> logins)
        {
            if (!logins.Any())
            {
                return(_ => true);
            }

            var userByLogin   = cachedOrg.Users.ToDictionary(u => u.Login, StringComparer.OrdinalIgnoreCase);
            var includedUsers = new HashSet <CachedUser>();

            foreach (var login in logins)
            {
                if (!userByLogin.TryGetValue(login, out var user))
                {
                    Console.Error.WriteLine($"warning: User '{login}' doesn't exist");
                }
                else
                {
                    includedUsers.Add(user);
                }
            }

            return(includedUsers.Contains);
        }
示例#6
0
        private static Func <CachedTeam, bool> CreateTeamFilter(CachedOrg cachedOrg, List <string> names)
        {
            if (!names.Any())
            {
                return(_ => true);
            }

            var teamByName    = cachedOrg.Teams.ToDictionary(t => t.Name, StringComparer.OrdinalIgnoreCase);
            var includedTeams = new HashSet <CachedTeam>();

            foreach (var name in names)
            {
                if (!teamByName.TryGetValue(name, out var team))
                {
                    Console.Error.WriteLine($"warning: Team '{name}' doesn't exist");
                }
                else
                {
                    includedTeams.Add(team);
                }
            }

            return(includedTeams.Contains);
        }
示例#7
0
        private static Func <CachedRepo, bool> CreateRepoFilter(CachedOrg cachedOrg, List <string> names)
        {
            if (!names.Any())
            {
                return(_ => true);
            }

            var repoByName    = cachedOrg.Repos.ToDictionary(r => r.Name, StringComparer.OrdinalIgnoreCase);
            var includedRepos = new HashSet <CachedRepo>();

            foreach (var name in names)
            {
                if (!repoByName.TryGetValue(name, out var repo))
                {
                    Console.Error.WriteLine($"warning: Repo '{name}' doesn't exist");
                }
                else
                {
                    includedRepos.Add(repo);
                }
            }

            return(includedRepos.Contains);
        }
 public PolicyAnalysisContext(CachedOrg org, MicrosoftUserLinks userLinks)
 {
     Org       = org;
     UserLinks = userLinks;
 }
示例#9
0
        private static async Task RunAsync(string orgName,
                                           List <string> repoNames,
                                           List <string> teamNames,
                                           List <string> userNames,
                                           string outputFileName,
                                           string cacheLocation)
        {
            Console.WriteLine("Loading org data...");
            var cachedOrg = await CachedOrg.LoadFromCacheAsync(orgName, cacheLocation);

            if (cachedOrg == null)
            {
                Console.Error.WriteLine("The org wasn't loaded yet or the cache isn't valid anymore.");
                return;
            }

            var repoFilter = CreateRepoFilter(cachedOrg, repoNames);
            var teamFilter = CreateTeamFilter(cachedOrg, teamNames);
            var userFilter = CreateUserFilter(cachedOrg, userNames);

            Console.WriteLine("Loading Microsoft links...");
            var ospoClient = await OspoClientFactory.CreateAsync();

            var links = await ospoClient.GetAllAsync();

            Console.WriteLine("Computing result...");

            var emailByUser   = new Dictionary <CachedUser, string>();
            var nameByUser    = new Dictionary <CachedUser, string>();
            var microsoftLink = links.ToDictionary(l => l.GitHubInfo.Login);

            foreach (var user in cachedOrg.Users)
            {
                emailByUser[user] = user.Email;
                nameByUser[user]  = user.Name;

                if (microsoftLink.TryGetValue(user.Login, out var link))
                {
                    if (!string.IsNullOrEmpty(link.MicrosoftInfo.EmailAddress))
                    {
                        emailByUser[user] = link.MicrosoftInfo.EmailAddress;
                    }

                    if (!string.IsNullOrEmpty(link.MicrosoftInfo.PreferredName))
                    {
                        nameByUser[user] = link.MicrosoftInfo.PreferredName;
                    }
                }
            }

            var isForExcel  = outputFileName == null;
            var csvDocument = new CsvDocument("team", "repo", "user", "user-name", "user-email", "is-microsoft", "change", "repo-admins");

            using (var writer = csvDocument.Append())
            {
                foreach (var userAccess in cachedOrg.Collaborators)
                {
                    var repo = userAccess.Repo;
                    var user = userAccess.User;

                    if (!repoFilter(repo) || !userFilter(user))
                    {
                        continue;
                    }

                    foreach (var team in cachedOrg.Teams)
                    {
                        if (!teamFilter(team))
                        {
                            continue;
                        }

                        var whatIfRemoved = userAccess.WhatIfRemovedFromTeam(team);
                        var change        = whatIfRemoved.ToString();

                        if (whatIfRemoved.IsUnchanged)
                        {
                            continue;
                        }

                        var isMicrosoft = microsoftLink.ContainsKey(user.Login) ? "Yes" : "No";
                        var repoAdmins  = repo.GetAdministrators()
                                          .Select(u => (Email: emailByUser[u], Name: nameByUser[u]))
                                          .Where(t => !string.IsNullOrEmpty(t.Email))
                                          .Select(t => $"{t.Name}<{t.Email}>");
                        var repoAdminList = string.Join("; ", repoAdmins);

                        writer.WriteHyperlink(team.Url, team.Name, isForExcel);
                        writer.WriteHyperlink(repo.Url, repo.Name, isForExcel);
                        writer.WriteHyperlink(user.Url, user.Login, isForExcel);
                        writer.Write(nameByUser[user]);
                        writer.Write(emailByUser[user]);
                        writer.Write(isMicrosoft);
                        writer.Write(change);
                        writer.Write(repoAdminList);
                        writer.WriteLine();
                    }
                }
            }

            if (outputFileName != null)
            {
                csvDocument.Save(outputFileName);
            }
            else
            {
                csvDocument.ViewInExcel();
            }
        }
示例#10
0
 public static IEnumerable <CachedUser> GetOwners(this CachedOrg org)
 {
     return(org.Users.Where(u => u.IsOwner && !u.IsBot()));
 }
示例#11
0
 public static CachedTeam GetBotsTeam(this CachedOrg org)
 {
     return(org.Teams.SingleOrDefault(t => string.Equals(t.Name, "bots", StringComparison.OrdinalIgnoreCase)));
 }