-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit bad1d52
Showing
8 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
GITHUB_ACCESS_TOKEN=your_github_access_token |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
__pycache** | ||
.env | ||
|
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
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.
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
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) |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
argparse | ||
requests |
Empty file.
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
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") | ||
|
||
|