141 lines
6.6 KiB
Python
141 lines
6.6 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
|
|
import json
|
|
|
|
def request(resource, seafileURL, seafileToken, method='GET', data=None, dataIsJson=True):
|
|
if data is None:
|
|
httpHeaders = {'Accept': 'application/json; charset=utf-8; indent=4', 'Authorization': 'Token {0}'.format(seafileToken)}
|
|
data = ''
|
|
else:
|
|
if dataIsJson:
|
|
data = json.dumps(data)
|
|
httpHeaders = {'Content-type': 'application/json', 'Accept': 'application/json; charset=utf-8; indent=4', 'Authorization': 'Token {0}'.format(seafileToken)}
|
|
else:
|
|
httpHeaders = {'Content-type': 'application/x-www-form-urlencoded', 'Accept': 'application/json; charset=utf-8; indent=4', 'Authorization': 'Token {0}'.format(seafileToken)}
|
|
url = '{0}/api/v2.1/{1}'.format(seafileURL, resource)
|
|
logger.debug('Request URL: {0}'.format(url))
|
|
logger.debug('Request Method: {0}'.format(method))
|
|
logger.debug('Request Headers: {0}'.format(httpHeaders))
|
|
logger.debug('Request Data: {0}'.format(data))
|
|
r = requests.request(
|
|
method,
|
|
url,
|
|
data = data,
|
|
headers = httpHeaders,
|
|
)
|
|
logger.debug('Response: {0}'.format(r))
|
|
logger.debug('Request Status Code: {0}'.format(r.status_code))
|
|
if r.ok:
|
|
try:
|
|
logger.debug('Request Returned JSON: {0}'.format(r.json()))
|
|
return {'ok': r.ok, 'status_code': r.status_code, 'response': r.json()}
|
|
except:
|
|
logger.debug('Request Returned Text: {0}'.format(r.text))
|
|
return {'ok': r.ok, 'status_code': r.status_code, 'response': r.text}
|
|
raise ValueError(r)
|
|
|
|
#def
|
|
parser = argparse.ArgumentParser(description='Sync LDAP with Seafile')
|
|
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 config.ini file.")
|
|
logger.debug("Using file {0}.".format(configPath))
|
|
if os.path.exists(configPath):
|
|
config = configparser.ConfigParser()
|
|
config.read(configPath)
|
|
else:
|
|
logger.critical("Unable to find/read config file. Please ensure the config.ini is in the same directory as this script and readable.")
|
|
exit(1)
|
|
|
|
seafileToken = config['Seafile']['token']
|
|
adminEmail = config['Seafile']['adminEmail']
|
|
seafileURL = config['Seafile']['SERVICE_URL']
|
|
logger.debug("Seafile URL: {0}".format(seafileURL))
|
|
logger.debug("Seafile Token: {0}".format(seafileToken))
|
|
logger.debug("Seafile Admin Email: {0}".format(adminEmail))
|
|
ldapHost = config['LDAP']['HOST']
|
|
#ldapPort = config['LDAP SERVER'].getint('port')
|
|
#ldapSSL = config['LDAP SERVER'].getboolean('ssl')
|
|
ldapBase = config['LDAP']['BASE']
|
|
ldapUserDN = config['LDAP']['USER_DN']
|
|
ldapUserPassword = config['LDAP']['PASSWORD']
|
|
ldapFilter = config['LDAP']['FILTER']
|
|
logger.debug("LDAP Host: {0}, LDAP Base: {1}, LDAP User DN: {2}, LDAP Filter: {3}".format(ldapHost, ldapBase, ldapUserDN, ldapFilter))
|
|
logger.debug("Finished reading the config.ini file.")
|
|
|
|
# setup the server
|
|
ldapServer = Server(ldapHost)
|
|
logger.debug("Setup LDAP server connection uri: {0}".format(ldapServer))
|
|
try:
|
|
ldap = Connection(ldapServer, ldapUserDN, ldapUserPassword, auto_bind=True)
|
|
except core.exceptions.LDAPBindError as e:
|
|
logger.critical("LDAP Bind Failed. {0}".format(e))
|
|
exit()
|
|
logger.debug("Bind successful.")
|
|
|
|
|
|
# get seafile users and loop through and check group membership and disable or not
|
|
logger.debug("Starting query for users in Seafile")
|
|
seafileUsers = request('admin/users/', seafileURL, seafileToken)['response']['data']
|
|
# need to substract one from the len as the admin account is in the list
|
|
logger.debug("Found {0} Seafile users excluding the admin account, {1}".format(len(seafileUsers)-1, adminEmail))
|
|
for seafileUser in seafileUsers:
|
|
if seafileUser['email'] == adminEmail:
|
|
continue
|
|
else:
|
|
logger.debug("Found user {0} with active status {1} in seafile".format(seafileUser['email'], bool(seafileUser['is_active'])))
|
|
logger.debug("Checking if {0} user has extensionAttribute1 set, is active, and is in the seafile group".format(seafileUser['email']))
|
|
ldap.search(ldapBase, '(&(extensionAttribute1={0})(!(userAccountControl:1.2.840.113556.1.4.803:=2))({1}))'.format(seafileUser['email'], ldapFilter), attributes=['*'])
|
|
count = len(ldap.entries)
|
|
logger.debug("Found {0} LDAP user.".format(count))
|
|
if count == 0:
|
|
logger.debug("User {0} doesn't have extensionAttribute1 set, isn't active, or isn't in the seafile group, disabling in seafile...".format(seafileUser['email']))
|
|
if not seafileUser['is_active']:
|
|
logger.debug("User {0} is already disabled in Seafile".format(seafileUser['email']))
|
|
continue
|
|
disableUserinSeafile = request('admin/users/{0}/'.format(seafileUser['email']), seafileURL, seafileToken, "PUT", {"is_active": "false"})['response']
|
|
if not disableUserinSeafile['is_active']:
|
|
logger.info("User {0} was set to disabled in Seafile".format(seafileUser['email']))
|
|
else:
|
|
logger.error("There was an error setting user {0} to disabled in Seafile".format(seafileUser['email']))
|
|
else:
|
|
logger.debug("User {0} has extensionAttribute1 set, is active, and is in the seafile group".format(seafileUser['email']))
|
|
if seafileUser['is_active']:
|
|
logger.debug("User {0} is already active in Seafile".format(seafileUser['email']))
|
|
continue
|
|
ActiveUserinSeafile = request('admin/users/{0}/'.format(seafileUser['email']), seafileURL, seafileToken, "PUT", {"is_active": "true"})['response']
|
|
if ActiveUserinSeafile['is_active']:
|
|
logger.info("User {0} was set to active in Seafile".format(seafileUser['email']))
|
|
else:
|
|
logger.error("There was an error setting user {0} to active in Seafile".format(seafileUser['email'])) |