|
| 1 | +#!/usr/bin/env groovy |
| 2 | + |
| 3 | +/** |
| 4 | + * groovy script to show all users that can access a given repository in a GitHub Enterprise instance |
| 5 | + * |
| 6 | + * Run 'groovy PrintRepoAccess.groovy' to see the list of command line options |
| 7 | + * |
| 8 | + * Example on how to list access rights for repos foo/bar and bar/foo on GitHub Enterprise instance https://foobar.com: |
| 9 | + * |
| 10 | + * groovy PrintRepoAccess.groovy -u https://foobar.com -t <access token> foo/bar bar/foo |
| 11 | + * |
| 12 | + * Example on how to list access rights for repos stored in <org-name>/<repo-name.git> in directory local: |
| 13 | + * groovy PrintRepoAccess.groovy -u https://foobar.com -t <access token> -l local |
| 14 | + * |
| 15 | + * Example that combines the two examples above but uses environmental variables instead of explicit parameters: |
| 16 | + * |
| 17 | + * export GITHUB_TOKEN="<personal access token>" |
| 18 | + * export GITHUB_URL="https://foobar.com" |
| 19 | + * groovy PrintRepoAccess.groovy -l local foo/bar bar/foo |
| 20 | + * |
| 21 | + * Apart from Groovy (and Java), you do not need to install any libraries on your system as the script will download them when you first start it |
| 22 | + * The first run may take some time as required dependencies have to get downloaded, then it should be quite fast |
| 23 | + * |
| 24 | + * If you do not have groovy yet, run 'brew install groovy' on a Mac, for Windows and Linux follow the instructions here: |
| 25 | + * http://groovy-lang.org/install.html |
| 26 | + * |
| 27 | + */ |
| 28 | + |
| 29 | +@Grab(group='org.kohsuke', module='github-api', version='1.75') |
| 30 | +import org.kohsuke.github.GitHub |
| 31 | + |
| 32 | +// parsing command line args |
| 33 | +cli = new CliBuilder(usage: 'groovy PrintRepoAccess.groovy [options] [repos]\nPrint out users that can access the repos specified, ALL if public repo') |
| 34 | +cli.t(longOpt: 'token', 'personal access token of a GitHub Enterprise site admin with repo scope (or use GITHUB_TOKEN env variable)', required: false , args: 1 ) |
| 35 | +cli.u(longOpt: 'url', 'GitHub Enterprise URL (or use GITHUB_URL env variable), e.g. https://myghe.com', required: false , args: 1 ) |
| 36 | +cli.l(longOpt: 'localDirectory', 'Directory with org/repo directory structure (show access for all contained repos)', required: false, args: 1) |
| 37 | +cli.h(longOpt: 'help', 'Print this usage info', required: false , args: 0 ) |
| 38 | + |
| 39 | +OptionAccessor opt = cli.parse(args) |
| 40 | + |
| 41 | +token = opt.t?opt.t:System.getenv("GITHUB_TOKEN") |
| 42 | +url = opt.u?opt.u:System.getenv("GITHUB_URL") |
| 43 | + |
| 44 | +// bail out if help parameter was supplied or not sufficient input to proceed |
| 45 | +if (opt.h || !token || !url ) { |
| 46 | + cli.usage() |
| 47 | + return |
| 48 | +} |
| 49 | + |
| 50 | +// chop potential trailing slash from GitHub Enterprise URL |
| 51 | +url = url.replaceAll('/\$', "") |
| 52 | + |
| 53 | +// connect to GitHub Enterprise |
| 54 | +client=GitHub.connectToEnterprise("${url}/api/v3", token) |
| 55 | + |
| 56 | +// printing CSV header |
| 57 | +println "REPOSITORY,USER_WITH_ACCESS" |
| 58 | + |
| 59 | +// iterate over all supplied repos |
| 60 | +printAccessRightsForCommandLineRepos(opt) |
| 61 | + |
| 62 | +if (opt.l) { |
| 63 | + localRepoStore = new File(opt.l) |
| 64 | + if (!localRepoStore.isDirectory()) { |
| 65 | + printErr "${localRepoStore.canonicalPath} is not a directory" |
| 66 | + return |
| 67 | + } |
| 68 | + printAccessRightsForStoredRepos(localRepoStore) |
| 69 | +} |
| 70 | + |
| 71 | +// END OF MAIN |
| 72 | + |
| 73 | +def printAccessRightsForRepo(org, repo) { |
| 74 | + if (repo.endsWith(".git")) { |
| 75 | + repo=repo.take(repo.length()-4) |
| 76 | + } |
| 77 | + |
| 78 | + try { |
| 79 | + ghRepo=client.getRepository("${org}/${repo}") |
| 80 | + isPublic=!ghRepo.isPrivate() |
| 81 | + if (isPublic) { |
| 82 | + println "${org}/${repo},ALL" |
| 83 | + } else { |
| 84 | + ghRepo.getCollaboratorNames().each { |
| 85 | + println "${org}/${repo},${it}" |
| 86 | + } |
| 87 | + } |
| 88 | + } catch (Exception e) { |
| 89 | + printErr "Could not access repo ${org}/${repo}, skipping ..." |
| 90 | + printErr "Reason: ${e.message}" |
| 91 | + return |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +def printAccessRightsForCommandLineRepos(opt) { |
| 96 | + opt.arguments().each { |
| 97 | + parsed=it.tokenize("/") |
| 98 | + if (parsed.size!=2 || parsed[1] == 0) { |
| 99 | + printErr "Could not parse new repo ${it}, please use org/repo format, skipping ..." |
| 100 | + return |
| 101 | + } |
| 102 | + printAccessRightsForRepo(parsed[0], parsed[1]) |
| 103 | + } |
| 104 | +} |
| 105 | + |
| 106 | +def printAccessRightsForStoredRepos(localRepoStore) { |
| 107 | + localRepoStore.eachDir { org -> |
| 108 | + org.eachDir { repo -> |
| 109 | + printAccessRightsForRepo(org.name,repo.name) |
| 110 | + } |
| 111 | + } |
| 112 | +} |
| 113 | + |
| 114 | +def printErr (msg) { |
| 115 | + System.err.println "ERROR: ${msg}" |
| 116 | +} |
0 commit comments