Files
seafile-sso/seafile-ldap.py

132 lines
5.4 KiB
Python

#!/usr/bin/env python
from ldap3 import Connection, Server, ANONYMOUS, SIMPLE, SYNC, ASYNC, core
from getpass import getpass
import configparser
import logging
import argparse
import os
import requests
import urllib3
def request(resource, seafile, method='GET', data=None):
if data is None:
data = ''
else:
data = json.dumps(data)
url = '{0}/api/v2.1/{1}'.format(seafile['url'], resource)
logger.debug('Request URL: {}'.format(url))
logger.debug('Request Data: {}'.format(data))
r = requests.request(
method,
url,
data=data,
headers={'Accept': 'application/json; indent=4', 'Authorization': 'Token {0}'.format(seafile['token'])},
)
logger.debug('Request Status Code: {}'.format(r.status_code))
if r.ok:
try:
logger.debug('Request Returned JSON: {}'.format(r.json()))
return {'ok': r.ok, 'status_code': r.status_code, 'response': r.json()}
except:
logger.debug('Request Returned Text: {}'.format(r.text))
return {'ok': r.ok, 'status_code': r.status_code, 'response': r.text}
raise ValueError(r)
def checkIfUserHasEmail(user):
ldap.search(config['LDAP SERVER']['groupBaseDN'], '(&(mail=*)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(memberof={0}))'.format(config['LDAP SERVER']['seafileGroupDN']), attributes=['*'])
parser = argparse.ArgumentParser(description='Sync LDAP with Seafile')
#group = parser.add_mutually_exclusive_group()
#group.add_argument('-e', '--encrypt', action='store_true', help='encrypt')
#group.add_argument('-d', '--decrypt', action='store_true', help='decrypt')
#parser.add_argument('-t', '--text', type=str, help='text to encrypt/decrypt')
#group2 = parser.add_mutually_exclusive_group()
#group2.add_argument('-t', '--text', type=str, help='text to encrypt/decrypt')
#group2.add_argument('-f', '--file', type=str, help='file to encrypt/decrypt, will create a .pynacl file when encrypting, and requires .pynacl file to decrypt')
parser.add_argument('-v', '--verbose', action='store_true', help='increase log level to debug')
args = parser.parse_args()
logger = logging.getLogger(__name__)
logFormatter = logging.Formatter('%(asctime)s - [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
logger.setLevel(logging.INFO)
if args.verbose:
logger.setLevel(logging.DEBUG)
else:
logger.setLevel(logging.INFO)
#fileHandler = logging.FileHandler("/tmp/seafile-ldap.log")
#fileHandler.setFormatter(logFormatter)
#logger.addHandler(fileHandler)
consoleHandler = logging.StreamHandler()
consoleHandler.setFormatter(logFormatter)
logger.addHandler(consoleHandler)
# get directory of script
cwd = os.path.dirname(os.path.realpath(__file__))
configPath = os.path.join(cwd, 'config.ini')
# import the config file
logger.debug("Starting to read the ini config.")
logger.debug("Using file {0}.".format(configPath))
try:
config = configparser.ConfigParser()
config.read(cwd + '/config.ini')
except ValueError:
logger.critical("Unable to find/read config file. ")
serverDNS = config['LDAP SERVER']['server']
serverPort = config['LDAP SERVER'].getint('port')
serverSSL = config['LDAP SERVER'].getboolean('ssl')
logger.debug("Server: {0}, Server Port: {1}, Using SSL: {2}".format(serverDNS, serverPort, serverSSL))
bindAccount = config['Bind Account']['username']
bindPassword = config['Bind Account']['password']
logger.debug("Bind Account: {0}, Bind Password: <hidden>".format(bindAccount))
logger.debug("Finished reading the ini config.")
seafile = config['Seafile']
logger.debug("Seafile URL: {0}".format(seafile['url']))
logger.debug("Seafile Token: {0}".format(seafile['token']))
# setup the server
server = Server(serverDNS, port=serverPort, use_ssl=serverSSL)
logger.debug("Setup server connection uri: {0}".format(server))
try:
ldap = Connection(server, bindAccount, bindPassword, auto_bind=True)
except core.exceptions.LDAPBindError as e:
logger.critical("LDAP Bind Failed. {0}".format(e))
exit()
logger.debug("Bind successful.")
# sync ad users with seafile, if disabled or deleted ad user, disable in seafile
# I don't think this will work as saml/openid users are not listed with the admin/users/ nor the admin/search-users/ returns those users
#logger.debug("Searching for users that have a email address, are enabled, and in the {} group.".format(config['LDAP SERVER']['seafileGroupDN']))
#ldap.search(config['LDAP SERVER']['groupBaseDN'], '(&(mail=*)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(memberof={0}))'.format(config['LDAP SERVER']['seafileGroupDN']), attributes=['*'])
#logger.debug("Found {0} users.".format(len(ldap.entries)))
#for user in ldap.entries:
# logger.debug("User: {0} -- UserDN: {1}".format(user.name, user.distinguishedName))
#seafileUsers = request('admin/search-user/?query=@', seafile)['response']
#print(ldap.entries[0].distinguishedName)
# get ad groups and import them into seafile
# loop through each group and list members
# compare members to users in seafile group
# add users to group if missing and in the seafile group
# remove members in not in group or seafile group
# remove seafile groups if ad group is removed
ldap.search(config['LDAP SERVER']['groupBaseDN'], '(objectClass=group)', attributes=['*'])
#print(ldap.entries)
for group in ldap.entries:
try:
if group.member:
logger.debug("{0}".format(group.name))
finally:
continue