Skip to content

Commit

Permalink
init: add sources
Browse files Browse the repository at this point in the history
  • Loading branch information
SaicharanKandukuri committed Sep 29, 2023
0 parents commit bad1d52
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
GITHUB_ACCESS_TOKEN=your_github_access_token
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__pycache**
.env

49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# GitHub Multi user invite

A simple script to invite multiple users to a GitHub organization.

## Usage

Clone this repository & install dependencies:

```bash
git clone https://github.com/GDSCParulUniversity/Github-multi-user-invite.git
cd github-multi-user-invite
pip install -r requirements.txt
```

Create a personal access token with the `admin:org` scope from [GitHub](https://github.com/settings/tokens) and create a `.env` file with the following content:

```bash
GITHUB_ACCESS_TOKEN=your_token_here
```

> **Note**
> You should be have owner/admin access to the organization.
Create a file ( e.g. `users.txt` ) with the list of users to invite, one per line.

example:

```txt
saicharankandukuri
vinci-d
torvalds
```

> **Warning**
> Cross check the usernames before adding them to the list for safety.
Run the script:

```bash
python3 main.py --org your_org_name --users_file users.txt
```

## Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

## License

This project is licensed under the MIT License.
Empty file added github.py
Empty file.
74 changes: 74 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# pylint: disable=missing-module-docstring
import os
import sys
import argparse
from dotenv import load_dotenv
from rich.progress import track
from rich import print as cprint
from utils import github

gh: github


def multi_invite(org: str, a_users: list):
"""
Invite multiple users to a GitHub organization.
Args:
org (str): The name of the GitHub organization.
users (list): A list of usernames to invite.
Returns:
None
"""
# check if user exists
cprint(f"[magenta] Inviting {len(a_users)} user/s ..")
for user in track(a_users, description="Inviting users"):
uid = gh.get_user_id(user)

if uid is None:
cprint(f"[red]: user {user} does not exists")
continue

cprint(f"[green]: sending invite to {user}.")
inv = gh.invite_user_org(org, uid)

if inv.status_code == 201:
cprint(f"[green]: invite sent to {user}.")
else:
print(f"[red]: coudn't invite {user}")
print(f"[gray]: LOG: {inv.json()}")


if __name__ == "__main__":
# Load environment variables
if os.path.exists(".env"):
load_dotenv(".env")

# Parse arguments
parser = argparse.ArgumentParser(
prog="GitHub Organization Inviter",
epilog="v0.0.1"
)
parser.add_argument("--users_file", dest="users_file",
help="invite multiple users", required=True)
parser.add_argument(
"--org", dest="org", help="The organization to invite the user to.", required=True)
args = parser.parse_args()

auth = os.environ["GITHUB_ACCESS_TOKEN"]
gh = github(auth)

if not args.org:
cprint("[red]: requires org name")
sys.exit(1)

users = []
if args.users_file:
usr_file = args.users_file
if os.path.exists(usr_file):
with open(usr_file, 'r', encoding="utf-8") as f:
users = f.readlines()
users = [u.strip() for u in users]

multi_invite(args.org, a_users=users)
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
argparse
requests
Empty file added users.txt
Empty file.
88 changes: 88 additions & 0 deletions utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import json, requests
class github:
def __init__(self, auth, org=None):
self.auth = auth
self.org = org

def gh_request(self, path: str, method="GET", data: dict = {}) -> requests.Response:
"""Make a request to the GitHub API.
"""
data = json.dumps(data) if data != {} else None

res = requests.request(
method=method, url=f"https://api.github.com{path}",
headers={
"Accept": "application/vnd.github+json",
"Authorization": f"Bearer {self.auth}",
"X-GitHub-Api-Version": "2022-11-28"
},
data=data
)

return res

def invite_user_org(
self,
org: str, user: int,
teams: list = [], role: str = "direct_member"
) -> requests.Response:
"""
Invite a user to an organization with the specified role and teams.
Args:
org (str): The name of the organization to invite the user to.
user (int): The ID of the user to invite.
teams (list, optional): A list of team IDs to add the user to. Defaults to [].
role (str, optional): The role to assign to the user. Defaults to "direct_member".
Returns:
requests.Response: The response object from the GitHub API.
"""
res = self.gh_request(
f"/orgs/{org}/invitations",
method="POST",
data={
"invitee_id": user,
"role": role,
"team_ids": teams
}
)

return res

def get_user_id(self, user: str) -> int | None:
"""
Get the user ID of a given GitHub username.
Args:
user (str): The GitHub username.
Returns:
int | None: The user ID if the user exists, otherwise None.
"""

res = self.gh_request(f"/users/{user}")
if res.status_code == 200:
return res.json()['id']
else:
return None

def list_teams(self, org: str):
"""
Lists all the teams in the specified organization.
Args:
- org (str): The name of the organization.
Returns:
- None
"""
res = self.gh_request(f"/orgs/{org}/teams")

if res.status_code == 200:
for team in len(res):
print(f"{team.name} | id: {team.id}")
else:
print("Something unexpected happened")


0 comments on commit bad1d52

Please sign in to comment.