ldap-teamsync/app.py

113 строки
3.2 KiB
Python
Исходник Обычный вид История

2020-06-17 17:43:47 +03:00
from pprint import pprint
from flask import Flask
from githubapp import GitHubApp, LDAPClient
2020-06-18 23:48:01 +03:00
import os
2020-06-17 17:43:47 +03:00
app = Flask(__name__)
github_app = GitHubApp(app)
2020-06-18 23:48:01 +03:00
ldap = LDAPClient()
2020-06-17 17:43:47 +03:00
@github_app.on('team.created')
def sync_team():
2020-06-19 00:58:56 +03:00
pprint(github_app.payload)
2020-06-17 17:43:47 +03:00
payload = github_app.payload
2020-06-19 17:34:51 +03:00
owner = github_app.payload['organization']['login']
org = github_app.installation_client.organization(owner)
team = org.team(payload['team']['id'])
2020-06-17 17:43:47 +03:00
slug = payload['team']['slug']
parent = payload['team']['parent']
ldap_members = ldap_lookup(group=slug)
2020-06-17 23:31:54 +03:00
team_members = github_lookup(
team_id=payload['team']['id'],
attribute='username'
)
2020-06-19 00:58:56 +03:00
2020-06-17 23:31:54 +03:00
compare = compare_members(
ldap_group=ldap_members,
github_team=team_members,
attribute='username'
)
pprint(compare)
2020-06-19 20:43:52 +03:00
execute_sync(
2020-06-19 17:34:51 +03:00
org=org,
team=team,
state=compare
)
2020-06-19 00:58:56 +03:00
2020-06-17 17:43:47 +03:00
def ldap_lookup(group=None):
"""
Look up members of a group in LDAP
2020-06-17 18:20:02 +03:00
:param group: The name of the group to query in LDAP
:type group: str
:return: ldap_members
:rtype: list
2020-06-17 17:43:47 +03:00
"""
group_members = ldap.get_group_members(group)
2020-06-17 23:31:54 +03:00
ldap_members = [member for member in group_members]
2020-06-17 17:43:47 +03:00
return ldap_members
2020-06-19 00:58:56 +03:00
def github_team(team_id):
owner = github_app.payload['organization']['login']
org = github_app.installation_client.organization(owner)
return org.team(team_id)
2020-06-17 17:43:47 +03:00
2020-06-17 23:31:54 +03:00
def github_lookup(team_id=None, attribute='username'):
2020-06-17 17:43:47 +03:00
"""
Look up members of a give team in GitHub
:param team_id:
2020-06-17 23:31:54 +03:00
:param attribute:
2020-06-17 18:20:02 +03:00
:type team_id: int
2020-06-17 23:31:54 +03:00
:type attribute: str
2020-06-17 18:20:02 +03:00
:return: team_members
:rtype: list
2020-06-17 17:43:47 +03:00
"""
2020-06-17 23:31:54 +03:00
team_members = []
2020-06-19 00:58:56 +03:00
team = github_team(team_id)
2020-06-17 23:31:54 +03:00
if attribute == 'email':
for m in team.members():
user = github_app.installation_client.user(m.login)
team_members.append({'username': str(user.login).casefold(),
'email': str(user.email).casefold()})
else:
for member in team.members():
team_members.append({'username': str(member).casefold(),
'email': ''})
2020-06-17 17:43:47 +03:00
return team_members
2020-06-17 23:31:54 +03:00
def compare_members(ldap_group, github_team, attribute='username'):
2020-06-17 18:20:02 +03:00
"""
Compare users in GitHub and LDAP to see which users need to be added or removed
:param ldap_group:
:param github_team:
2020-06-17 23:31:54 +03:00
:param attribute:
2020-06-17 18:20:02 +03:00
:return: sync_state
:rtype: dict
"""
2020-06-17 23:31:54 +03:00
ldap_list = [x[attribute] for x in ldap_group]
github_list = [x[attribute] for x in github_team]
add_users = list(set(ldap_list) - set(github_list))
remove_users = list(set(github_list) - set(ldap_list))
2020-06-17 18:20:02 +03:00
sync_state = {
'ldap': ldap_group,
'github': github_team,
'action': {
'add': add_users,
'remove': remove_users
}
}
return sync_state
2020-06-17 17:43:47 +03:00
2020-06-19 20:43:52 +03:00
def execute_sync(org, team ,state):
2020-06-19 17:34:51 +03:00
for user in state['action']['add']:
# Validate that user is in org
if org.is_member(user):
team.add_or_update_membership(user)
else:
pprint(f'Skipping {user} as they are not part of the org')
for user in state['action']['remove']:
pprint(f'Removing {user}')
team.revoke_membership(user)