Last active
January 14, 2021 14:50
-
-
Save lukpueh/42c23c35c7cc23ab194bda2db39779bf to your computer and use it in GitHub Desktop.
Query GitHub REST API to get org permission for people and teams.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
"""Query GitHub REST API to get org permission for people and teams | |
Usage: | |
./gh_org_info.py <GitHub user name> <AuthToken> <organization name> | |
Note: To create an authentication token see | |
https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token | |
Result: | |
{ | |
"people": { | |
"<user name>": { | |
"role": "<one of 'owner', 'member', 'outside collaborator'>", | |
"repos": { | |
"<repository name>": { | |
"permission": ["<(admin|push|maintain|triage|pull)>", ...] | |
}, ... | |
}, | |
}, ... | |
}, | |
"teams": { | |
"<team name>": { | |
"members": [ | |
<username>, ... | |
], | |
"repos": { | |
"<repository name>": { | |
"permission": ["<(admin|push|maintain|triage|pull)>", ...], | |
}, ... | |
} | |
}, ... | |
}, | |
"repos": ["<repository name>", ...] | |
} | |
""" | |
import sys | |
import json | |
import requests | |
def get_info(login, token, org): | |
"""Get GitHub organization info about people and teams permissions. """ | |
def _get(endpoint): | |
"""Query API and error if result is not a list. """ | |
url = f"https://api.github.com/{endpoint}" | |
result = requests.get(url, auth=(login, token)) | |
if result.status_code != requests.codes.ok: | |
raise Exception(f"request: {url}, response: {result.json()}") | |
return result.json() | |
# Init data structure to be returned | |
org_info = {"people": {}, "teams": {}, "repos": []} | |
# Temporary list of outside contributors to distinguish from members below | |
# https://docs.github.com/en/free-pro-team@latest/rest/reference/orgs#list-outside-collaborators-for-an-organization | |
_org_outside_collaborators = [r['login'] | |
for r in _get(f"orgs/{org}/outside_collaborators")] | |
# Get people info | |
# https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#list-organization-repositories | |
for repo in _get(f"orgs/{org}/repos"): | |
org_info["repos"].append(repo['name']) | |
# https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#list-repository-collaborators | |
for user in _get(f"repos/{org}/{repo['name']}/collaborators"): | |
user_name = user["login"] | |
repo_data = { | |
"permissions": [k for k, v in user["permissions"].items() if v] | |
} | |
# Add repo data to existing collaborator entry | |
if org_info["people"].get(user_name): | |
org_info["people"][user_name]["repos"][repo["name"]] = repo_data | |
# Create new collaborator entry with intial repo data | |
else: | |
# Query collaborator role info (only available for members) | |
if user_name not in _org_outside_collaborators: | |
# https://docs.github.com/en/free-pro-team@latest/rest/reference/orgs#get-organization-membership-for-a-user | |
member_details = _get(f"orgs/{org}/memberships/{user['login']}") | |
role = member_details["role"] | |
else: | |
role = "outside collaborator" | |
# Get full name for user | |
# https://docs.github.com/en/free-pro-team@latest/rest/reference/users#get-a-user | |
name = _get(f"users/{user_name}").get("name") | |
org_info["people"][user_name] = { | |
"name": name, | |
"repos": {repo["name"]: repo_data}, | |
"role": role | |
} | |
# Get teams info | |
# https://docs.github.com/en/free-pro-team@latest/rest/reference/teams#list-teams | |
for team in _get(f"orgs/{org}/teams"): | |
members = [] | |
# https://docs.github.com/en/free-pro-team@latest/rest/reference/teams#list-team-members | |
for member in _get(f"teams/{team['id']}/members"): | |
members.append(member["login"]) | |
# https://docs.github.com/en/free-pro-team@latest/rest/reference/teams#list-team-repositories | |
repos = {} | |
for repo in _get(f"teams/{team['id']}/repos"): | |
repos[repo["name"]] = { | |
"permissions": [k for k, v in repo["permissions"].items() if v] | |
} | |
org_info["teams"][team["name"]] = { | |
"description": team["description"], | |
"repos": repos, | |
"members": members, | |
} | |
return org_info | |
def main(): | |
if len(sys.argv) < 4: | |
print(f"usage: {sys.argv[0]} <GitHub user name> <GitHub AuthToken> <org>") | |
sys.exit(1) | |
login = sys.argv[1] | |
token = sys.argv[2] | |
org = sys.argv[3] | |
org_info = get_info(login, token, org) | |
print(json.dumps(org_info)) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment