Compare commits

..

No commits in common. "811811455136500a83bdd46889116b54558a70e1" and "01fdd6cc019d07cb8a6ba325d93e0e02714b50a4" have entirely different histories.

4 changed files with 55 additions and 118 deletions

View File

@ -2,10 +2,9 @@ FROM python:3-alpine
COPY requirements.txt /code/requirements.txt
RUN pip install -r /code/requirements.txt
RUN echo '0 1,13 * * * python3 /code/main.py' | crontab -
RUN echo '*/5 * * * * python3 /code/main.py' | crontab -
COPY . /code
WORKDIR /code
EXPOSE 5000
ENTRYPOINT ["/code/entrypoint.sh"]
CMD ["/usr/sbin/crond", "-f", "-d", "0"]

View File

@ -1,3 +0,0 @@
#!/usr/bin/env sh
crond
flask --app main run -h 0.0.0.0

116
main.py Executable file → Normal file
View File

@ -1,8 +1,7 @@
#!/usr/bin/env python3
from dolibarrpy import Dolibarrpy
from flask import Flask, abort, request
from ldap3 import ALL, Connection, ObjectDef, Reader, Server, WritableEntry, Writer
from ldap3 import ALL, Connection, ObjectDef, Reader, Server, Writer
import config
@ -21,48 +20,22 @@ def main():
def manage_users_extra_fields(ldap_conn: Connection, dolibarr_client: Dolibarrpy):
dolibarr_users = dolibarr_client.find_all_users()
obj_inetorgperson = ObjectDef(['inetOrgPerson'] + config.LDAP_USERS_EXTRA_OBJECT_CLASSES, ldap_conn)
users_reader = Reader(ldap_conn, obj_inetorgperson, config.LDAP_USERS_OU)
users_reader.search()
users_writer = Writer.from_cursor(users_reader)
for ldap_user in users_writer:
uid = ldap_user.uid
for dolibarr_user in dolibarr_users:
manage_user_extra_fields(ldap_conn, dolibarr_user)
def manage_user_extra_fields(ldap_conn: Connection, dolibarr_user: dict):
login = dolibarr_user['login']
obj_inetorgperson = ObjectDef(['top', 'inetOrgPerson', 'posixAccount'], ldap_conn)
obj_user = ObjectDef(['top', 'inetOrgPerson', 'posixAccount'] + config.LDAP_GROUPS_EXTRA_OBJECT_CLASSES, ldap_conn)
users_reader = Reader(ldap_conn, obj_inetorgperson, config.LDAP_USERS_OU, f"uid:={login}")
users_reader.search()
users_writer = Writer.from_cursor(users_reader, object_def=obj_user)
if users_writer.entries:
ldap_user = users_writer[0]
if dolibarr_user['login'] == uid:
break
else:
attrs = {
'cn': f"{dolibarr_user['firstname']} {dolibarr_user['lastname']}".strip(),
'givenName': dolibarr_user['firstname'],
'sn': dolibarr_user['lastname'],
'mail': dolibarr_user['email'],
'street': dolibarr_user['address'],
'postalCode': dolibarr_user['zip'],
'l': dolibarr_user['town'],
'mobile': dolibarr_user['user_mobile'],
'uidNumber': dolibarr_user['id'],
'gidNumber': dolibarr_user['id'],
'homeDirectory': f"/home/{login}",
}
for key, value in list(attrs.items()):
if not value:
del attrs[key]
ldap_conn.add(f"uid={login},{config.LDAP_USERS_OU}", ["top", "inetOrgPerson", "posixAccount", "shadowAccount"], attrs)
users_reader.search()
users_writer = Writer.from_cursor(users_reader, object_def=obj_user)
ldap_user = users_writer[0]
append_extra_fields_to_ldap_user(ldap_user, dolibarr_user)
users_writer.commit()
continue
def append_extra_fields_to_ldap_user(ldap_user: WritableEntry, dolibarr_user: dict):
for extra_object_class in config.LDAP_USERS_EXTRA_OBJECT_CLASSES:
if extra_object_class not in ldap_user.objectClass:
ldap_user.objectClass += extra_object_class
ldap_user.objectClass.append(extra_object_class)
for extra_field in config.LDAP_USERS_EXTRA_FIELDS:
dolibarr_attr, ldap_attr = extra_field.split(':')
@ -74,74 +47,43 @@ def append_extra_fields_to_ldap_user(ldap_user: WritableEntry, dolibarr_user: di
else:
value = dolibarr_user['array_options'][f'options_{dolibarr_attr}'] or ""
setattr(ldap_user, ldap_attr, value)
users_writer.commit()
def manage_groups_extra_fields(ldap_conn: Connection, dolibarr_client: Dolibarrpy):
dolibarr_groups = dolibarr_client.call_list_api('users/groups')
obj_posixgroup = ObjectDef(['posixGroup'] + config.LDAP_GROUPS_EXTRA_OBJECT_CLASSES, ldap_conn)
groups_reader = Reader(ldap_conn, obj_posixgroup, config.LDAP_GROUPS_OU)
groups_reader.search()
groups_writer = Writer.from_cursor(groups_reader)
for ldap_group in groups_writer:
print(ldap_group)
name = ldap_group.cn
for dolibarr_group in dolibarr_groups:
manage_group_extra_fields(ldap_conn, dolibarr_group)
def manage_group_extra_fields(ldap_conn: Connection, dolibarr_group: dict):
name = dolibarr_group['name']
obj_posixgroup = ObjectDef(['posixGroup'], ldap_conn)
obj_group = ObjectDef(['posixGroup'] + config.LDAP_GROUPS_EXTRA_OBJECT_CLASSES, ldap_conn)
groups_reader = Reader(ldap_conn, obj_posixgroup, config.LDAP_GROUPS_OU, f"cn:={name}")
groups_reader.search()
groups_writer = Writer.from_cursor(groups_reader, object_def=obj_group)
if groups_writer.entries:
ldap_group = groups_writer[0]
if dolibarr_group['nom'] == name:
break
else:
attrs = {
'cn': name,
'gidNumber': dolibarr_group['id'],
}
for key, value in list(attrs.items()):
if not value:
del attrs[key]
ldap_conn.add(f"cn={name},{config.LDAP_GROUPS_OU}", ["top", "posixGroup"], attrs)
groups_reader.search()
groups_writer = Writer.from_cursor(groups_reader, object_def=obj_group)
ldap_group = groups_writer[0]
append_extra_fields_to_ldap_group(ldap_group, dolibarr_group)
groups_writer.commit()
continue
def append_extra_fields_to_ldap_group(ldap_group: WritableEntry, dolibarr_group: dict):
for extra_object_class in config.LDAP_GROUPS_EXTRA_OBJECT_CLASSES:
if extra_object_class not in ldap_group.objectClass:
ldap_group.objectClass += extra_object_class
ldap_group.objectClass.append(extra_object_class)
for extra_field in config.LDAP_GROUPS_EXTRA_FIELDS:
dolibarr_attr, ldap_attr = extra_field.split(':')
if dolibarr_attr.endswith('[]'):
dolibarr_attr = dolibarr_attr[:-2]
print(dolibarr_group)
value = dolibarr_group['array_options'][f'options_{dolibarr_attr}']
value = value.split() if value else []
print(ldap_attr, value)
setattr(ldap_group, ldap_attr, value)
else:
value = dolibarr_group['array_options'][f'options_{dolibarr_attr}'] or ""
print(ldap_attr, value)
setattr(ldap_group, ldap_attr, value)
flask_app = Flask(__name__)
@flask_app.post('/webhook')
def webhook_receiver():
data = request.json
if 'triggercode' not in data or 'object' not in data:
abort(400)
triggercode = data['triggercode']
obj = data['object']
ldap_server = Server(config.LDAP_HOST, config.LDAP_PORT, get_info=ALL)
if triggercode.startswith('USER_'):
with Connection(ldap_server, config.LDAP_BIND_USER, config.LDAP_BIND_PASSWORD) as ldap_conn:
manage_user_extra_fields(ldap_conn, obj)
elif triggercode.startswith('GROUP_'):
with Connection(ldap_server, config.LDAP_BIND_USER, config.LDAP_BIND_PASSWORD) as ldap_conn:
manage_group_extra_fields(ldap_conn, obj)
else:
abort(400)
return "", 204
groups_writer.commit()
if __name__ == '__main__':

View File

@ -1,4 +1,3 @@
flask
ldap3
dolibarrpy
icecream