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