Synchronize Dolibarr extra fields to LDAP
This commit is contained in:
commit
123c7f1209
17
.env.example
Normal file
17
.env.example
Normal file
@ -0,0 +1,17 @@
|
||||
DOLIBARR_URL=https://dolibarr.example.com
|
||||
DOLIBARR_API_TOKEN=DOLAPIKEY
|
||||
DOLIBARR_API_DEBUG=false
|
||||
|
||||
LDAP_HOST=127.0.0.1
|
||||
LDAP_PORT=389
|
||||
LDAP_BIND_USER=
|
||||
LDAP_BIND_PASSWORD=
|
||||
LDAP_BASE="dc=example,dc=com"
|
||||
|
||||
# LDAP_USERS_OU="ou=users,dc=example,dc=com"
|
||||
LDAP_USERS_EXTRA_FIELDS=
|
||||
LDAP_USERS_EXTRA_OBJECT_CLASSES=
|
||||
|
||||
# LDAP_GROUPS_OU="ou=groups,dc=example,dc=com"
|
||||
LDAP_GROUPS_EXTRA_FIELDS=
|
||||
LDAP_GROUPS_EXTRA_OBJECT_CLASSES=
|
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
__pycache__
|
||||
|
||||
.env
|
||||
|
||||
venv
|
25
config.py
Normal file
25
config.py
Normal file
@ -0,0 +1,25 @@
|
||||
import os
|
||||
|
||||
|
||||
DOLIBARR_URL = os.getenv("DOLIBARR_URL", "https://dolibarr.example.com")
|
||||
DOLIBARR_API_BASE = DOLIBARR_URL + "/api/index.php/"
|
||||
DOLIBARR_API_TOKEN = os.getenv("DOLIBARR_API_TOKEN", "DOLAPIKEY")
|
||||
DOLIBARR_API_DEBUG = os.getenv("DOLIBARR_API_DEBUG", "False").lower() == "true"
|
||||
|
||||
LDAP_HOST = os.getenv("LDAP_HOST", "locahost")
|
||||
LDAP_PORT = int(os.getenv("LDAP_PORT", 389))
|
||||
LDAP_BIND_USER = os.getenv("LDAP_BIND_USER", None) or None
|
||||
LDAP_BIND_PASSWORD = os.getenv("LDAP_BIND_PASSWORD", None) or None
|
||||
LDAP_BASE = os.getenv("LDAP_BASE", "dc=example,dc=com")
|
||||
|
||||
LDAP_USERS_OU = os.getenv("LDAP_USERS_OU", f"ou=users,{LDAP_BASE}")
|
||||
LDAP_USERS_EXTRA_FIELDS = os.getenv("LDAP_USERS_EXTRA_FIELDS", "")
|
||||
LDAP_USERS_EXTRA_FIELDS = LDAP_USERS_EXTRA_FIELDS.split(';') if LDAP_USERS_EXTRA_FIELDS else []
|
||||
LDAP_USERS_EXTRA_OBJECT_CLASSES = os.getenv("LDAP_USERS_EXTRA_OBJECT_CLASSES", "")
|
||||
LDAP_USERS_EXTRA_OBJECT_CLASSES = LDAP_USERS_EXTRA_OBJECT_CLASSES.split(';') if LDAP_USERS_EXTRA_OBJECT_CLASSES else []
|
||||
|
||||
LDAP_GROUPS_OU = os.getenv("LDAP_GROUPS_OU", f"ou=groups,{LDAP_BASE}")
|
||||
LDAP_GROUPS_EXTRA_FIELDS = os.getenv("LDAP_GROUPS_EXTRA_FIELDS", "")
|
||||
LDAP_GROUPS_EXTRA_FIELDS = LDAP_GROUPS_EXTRA_FIELDS.split(';') if LDAP_GROUPS_EXTRA_FIELDS else []
|
||||
LDAP_GROUPS_EXTRA_OBJECT_CLASSES = os.getenv("LDAP_GROUPS_EXTRA_OBJECT_CLASSES", "")
|
||||
LDAP_GROUPS_EXTRA_OBJECT_CLASSES = LDAP_GROUPS_EXTRA_OBJECT_CLASSES.split(';') if LDAP_GROUPS_EXTRA_OBJECT_CLASSES else []
|
90
main.py
Normal file
90
main.py
Normal file
@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from dolibarrpy import Dolibarrpy
|
||||
from ldap3 import ALL, Connection, ObjectDef, Reader, Server, Writer
|
||||
|
||||
import config
|
||||
|
||||
|
||||
def main():
|
||||
dolibarr_client = Dolibarrpy(url=config.DOLIBARR_API_BASE, token=config.DOLIBARR_API_TOKEN, timeout=16, debug=config.DOLIBARR_API_DEBUG)
|
||||
|
||||
ldap_server = Server(config.LDAP_HOST, config.LDAP_PORT, get_info=ALL)
|
||||
with Connection(ldap_server, config.LDAP_BIND_USER, config.LDAP_BIND_PASSWORD) as ldap_conn:
|
||||
if config.LDAP_USERS_EXTRA_FIELDS or config.LDAP_USERS_EXTRA_OBJECT_CLASSES:
|
||||
manage_users_extra_fields(ldap_conn, dolibarr_client)
|
||||
|
||||
if config.LDAP_GROUPS_EXTRA_FIELDS or config.LDAP_GROUPS_EXTRA_OBJECT_CLASSES:
|
||||
manage_groups_extra_fields(ldap_conn, dolibarr_client)
|
||||
|
||||
|
||||
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:
|
||||
if dolibarr_user['login'] == uid:
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
for extra_object_class in config.LDAP_USERS_EXTRA_OBJECT_CLASSES:
|
||||
if extra_object_class not in ldap_user.objectClass:
|
||||
ldap_user.objectClass.append(extra_object_class)
|
||||
|
||||
for extra_field in config.LDAP_USERS_EXTRA_FIELDS:
|
||||
dolibarr_attr, ldap_attr = extra_field.split(':')
|
||||
if dolibarr_attr.endswith('[]'):
|
||||
dolibarr_attr = dolibarr_attr[:-2]
|
||||
value = dolibarr_user['array_options'][f'options_{dolibarr_attr}']
|
||||
value = value.split() if value else []
|
||||
setattr(ldap_user, ldap_attr, value)
|
||||
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:
|
||||
if dolibarr_group['nom'] == name:
|
||||
break
|
||||
else:
|
||||
continue
|
||||
|
||||
for extra_object_class in config.LDAP_GROUPS_EXTRA_OBJECT_CLASSES:
|
||||
if extra_object_class not in ldap_group.objectClass:
|
||||
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)
|
||||
groups_writer.commit()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
4
requirements.txt
Normal file
4
requirements.txt
Normal file
@ -0,0 +1,4 @@
|
||||
ldap3
|
||||
dolibarrpy
|
||||
icecream
|
||||
requests
|
Loading…
x
Reference in New Issue
Block a user