132 lines
5.4 KiB
Python
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
|