def __grant_group_access(group_slug: str, access: str, repo: str): logging.info(f"Grant group {group_slug} to {access} on {repo}") bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() get_team_response = requests.get( teams_url().format(team=bitbucket_team_name), auth=BearerAuth(access_token)) if get_team_response.status_code != 200: logging.error(get_team_response) raise RuntimeError(f"Fail to obtain team {bitbucket_team_name}") bitbucket_team_uuid = get_team_response.json()['uuid'] response = requests.put( groups_privileges_url().format(team=bitbucket_team_name, team_id=bitbucket_team_uuid, repo=repo, group=group_slug), auth=BearerAuth(access_token), headers={'Content-Type': 'text/plain'}, data=access, ) print(response)
def groups_list_user(verbose: bool, group_name: str): from tabulate import tabulate from itertools import count bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() response = requests.get( f"{groups_url()}/{group_name}/members".format( team=bitbucket_team_name), auth=BearerAuth(access_token), ) if response.status_code != 200: raise HTTPError(response.text) if verbose: print(json.dumps(json.loads(response.text), indent=2)) return members = response.json() table = [[ member['display_name'], member['account_id'], member['uuid'], member['resource_uri'] ] for member in members] headers = ['display_name', 'account_id', 'uuid', 'resource_uri'] print( tabulate(table, headers=headers, showindex=range(1, len(table) + 1), tablefmt='github'))
def list_users(verbose: bool): from tabulate import tabulate bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() response = requests.get( f"{teams_url()}/members".format(team=bitbucket_team_name), auth=BearerAuth(access_token), ) if verbose: print(json.dumps(json.loads(response.text), indent=2)) return members = response.json() table = [[member['display_name'], member['account_id'], member['uuid']] for member in members['values']] headers = ['display_name', 'account_id', 'uuid'] print( tabulate(table, headers=headers, showindex=range(1, len(table) + 1), tablefmt='github'))
def groups_add(group_name: str): bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() # See # https://confluence.atlassian.com/bitbucket/groups-endpoint-296093143.html#groupsEndpoint-PUTnewmemberintoagroup response = requests.post( f"{groups_url()}".format(team=bitbucket_team_name), auth=BearerAuth(access_token), data=f"name={group_name}") print(response.text)
def delete_invitation(email: str): import json bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() response = requests.delete( f"{team_invitations_url()}".format(team=bitbucket_team_name), auth=BearerAuth(access_token), headers={'Content-Type': 'application/json'}, data=json.dumps({'email': email})) print(response)
def __revoke_user_access(user_id: str, repo: str): logging.info(f"Revoke user {user_id} to access on {repo}") bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() response = requests.delete( users_privileges_url().format(team=bitbucket_team_name, repo=repo, user_id=user_id), auth=BearerAuth(access_token), ) print(response)
def groups_del(group_name: str): bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() # See # https://confluence.atlassian.com/bitbucket/groups-endpoint-296093143.html#groupsEndpoint-DELETEamember response = requests.delete( f"{groups_url()}/{group_name}".format(team=bitbucket_team_name), auth=BearerAuth(access_token)) if response.status_code == 204: print('OK') return raise HTTPError(response.text)
def groups_list(verbose: bool): bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() response = requests.get( groups_url().format(team=bitbucket_team_name), auth=BearerAuth(access_token), ) if verbose: print(json.dumps(json.loads(response.text), indent=2)) return groups = response.json() [print(group['slug']) for group in groups]
def __grant_user_access(user_id: str, access: str, repo: str): logging.info(f"Grant user {user_id} to {access} on {repo}") bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() response = requests.put( users_privileges_url().format(team=bitbucket_team_name, repo=repo, user_id=user_id), auth=BearerAuth(access_token), headers={'Content-Type': 'text/plain'}, data=access, ) print(response)
def __revoke_group_access(group_slug: str, repo: str): logging.info(f"Revoke group {group_slug} to access on {repo}") bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() get_team_response = requests.get( teams_url().format(team=bitbucket_team_name), auth=BearerAuth(access_token)) if get_team_response.status_code != 200: logging.error(get_team_response) raise RuntimeError(f"Fail to obtain team {bitbucket_team_name}") bitbucket_team_uuid = get_team_response.json()['uuid'] response = requests.delete( groups_privileges_url().format(team=bitbucket_team_name, team_id=bitbucket_team_uuid, repo=repo, group=group_slug), auth=BearerAuth(access_token), ) print(response)
def get_user_accesses(user: str): bitbucket_team_name = os.getenv('BITBUCKET_TEAM') bitbucket_cloud_session = os.getenv('BITBUCKET_CLOUD_SESSION') access_token = get_access_token() get_team_response = requests.get( teams_url() .format(team=bitbucket_team_name), auth = BearerAuth(access_token) ) if get_team_response.status_code != 200: logging.error(get_team_response) raise RuntimeError(f"Fail to obtain team {bitbucket_team_name}") bitbucket_team_uuid = get_team_response.json()['uuid'] cookies = { 'optintowebauth' : '1', 'cloud.session.token': bitbucket_cloud_session } logging.debug(f"cookies: {cookies}") response = requests.get( user_accesses_url() .format( team_id=bitbucket_team_uuid, user_id=user ), cookies=cookies ) logging.debug(response.json()) access_summary = response.json() repos = [ repo['name'] for repo in access_summary['repos'] ] groups = [ group['slug'] for group in access_summary['groups']] headers = ['user', 'user_id', 'repos', 'groups'] table = [[access_summary['user']['display_name'], access_summary['user']['uuid'], '\n'.join(repos), '\n'.join(groups) ]] print(tabulate(table, headers=headers, showindex=range(1, len(table) + 1), tablefmt='pipe'))
def __group_add_user(group_name: str, username: str): bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() # See # https://confluence.atlassian.com/bitbucket/groups-endpoint-296093143.html#groupsEndpoint-PUTnewmemberintoagroup response = requests.put( f"{groups_url()}/{group_name}/members/{username}".format( team=bitbucket_team_name), auth=BearerAuth(access_token), # Required by the API headers={'Content-Type': 'application/json'}, # Required by the API data='{}') print(response)
def list_pending_users(): from tabulate import tabulate bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() response = requests.get( f"{team_invitations_url()}".format(team=bitbucket_team_name), auth=BearerAuth(access_token)) invitations = response.json() headers = ['email', 'invited_by', 'utc_sent_on'] table = [[i['email'], i['invited_by']['display_name'], i['utc_sent_on']] for i in invitations] print( tabulate(table, headers=headers, showindex=range(1, len(table) + 1), tablefmt='github'))
def add_user(email: str, group: str): import json # Since June 2019, BitBucket changed their policy which a new user # can only be invited via their email address. Once they accept the # invitation email address, their username will be added into the team # `developers`. bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() response = requests.put( f"{team_invitations_url()}".format(team=bitbucket_team_name), auth=BearerAuth(access_token), headers={'Content-Type': 'application/json'}, data=json.dumps({ 'email': email, 'group_slug': group })) print(response.text)
def list_in_project(project: str) -> None: bitbucket_team_name = os.getenv('BITBUCKET_TEAM') access_token = get_access_token() get_repos_in_project_response = requests.get( repos_url().format(team=bitbucket_team_name), auth=BearerAuth(access_token), params={ 'q': f"project.key=\"{project}\"", 'pagelen': 100 }) if get_repos_in_project_response.status_code != 200: logging.error(get_repos_in_project_response.text) raise RuntimeError( f"Fail to obtain repositories in project {project} in team {bitbucket_team_name}" ) repositories = get_repos_in_project_response.json()['values'] names = [repo['name'] for repo in repositories] for name in names: print(name)
def get_all_user_accesses(format: str): bitbucket_team_name = os.getenv('BITBUCKET_TEAM') bitbucket_cloud_session = os.getenv('BITBUCKET_CLOUD_SESSION') access_token = get_access_token() # TODO: Handle pagination get_all_users_response = requests.get( f"{teams_url()}/members" .format(team=bitbucket_team_name), auth = BearerAuth(access_token), ) if get_all_users_response.status_code != 200: raise RuntimeError(get_all_users_response.status_code) members = [(member['display_name'], member['account_id']) for member in get_all_users_response.json()['values']] get_team_response = requests.get( teams_url() .format(team=bitbucket_team_name), auth = BearerAuth(access_token) ) if get_team_response.status_code != 200: logging.error(get_team_response) raise RuntimeError(f"Fail to obtain team {bitbucket_team_name}") bitbucket_team_uuid = get_team_response.json()['uuid'] cookies = { 'optintowebauth' : '1', 'cloud.session.token': bitbucket_cloud_session } all_members_accesses = [] for display_name, user_uuid in members: logging.debug(f"Fetching {display_name}") users_accesses = __get_user_accesses( user_accesses_url() .format( team_id=bitbucket_team_uuid, user_id=user_uuid ), cookies=cookies ) all_members_accesses.append(users_accesses) # IMPORTANT # ---- # Workaround for Rate Limiting. # Too many requests sent in a short period of time will trigger BitBucket # to block the subsequent requests. time.sleep(2) FORMATTERS = { 'default': __tabulate_format, 'table': __tabulate_format, 'json': __json_format, 'pipe': __pipe_format } formatter = FORMATTERS.get(format, FORMATTERS.get('default')) formatter(all_members_accesses)