diff --git a/docker-compose.yml b/docker-compose.yml index faf3221..ff3c3c4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,6 +10,7 @@ services: volumes: - ./lumi2/__init__.py:/app/lumi2/__init__.py:ro - ./lumi2/usermanager.py:/app/lumi2/usermanager.py:ro + - ./lumi2/ldap.py:/app/lumi2/ldap.py:ro - ./lumi2/static/:/app/lumi2/static/:ro - ./lumi2/templates/:/app/lumi2/templates/:ro ports: diff --git a/lumi2/__init__.py b/lumi2/__init__.py index b30ea09..1937e73 100644 --- a/lumi2/__init__.py +++ b/lumi2/__init__.py @@ -16,6 +16,14 @@ def create_app(test_config=None): SITE_TITLE='LUMI 2', SITE_AUTHOR='LUMI 2 Development Team', SITE_DESCRIPTION='A simple frontend for LDAP account management.', + LDAP_HOSTNAME='ldap://openldap', + LDAP_BIND_USER_DN='cn=admin,dc=example,dc=com', + LDAP_BIND_USER_PASSWORD='admin', + LDAP_ROOT_DN='cn=example,cn=com', + LDAP_USER_PARENT_DN='ou=users,cn=example,cn=com', + LDAP_GROUPS_PARENT_DN='ou=groups,cn=example,cn=com', + LDAP_USER_OBJECT_CLASS='inetOrgPerson', + LDAP_GROUP_OBJECT_CLASS='groupOfUniqueNames', ) if test_config is None: diff --git a/lumi2/ldap.py b/lumi2/ldap.py new file mode 100644 index 0000000..2922a90 --- /dev/null +++ b/lumi2/ldap.py @@ -0,0 +1,46 @@ +"""Interactions with an OpenLDAP server. + +Interactions include setting up authenticated connections, querying the DIT and +creating/reading/updating/deleting DIT entries. + +All function calls within this module rely heavily on the `ldap3 module `_. +""" + +from flask import current_app + +from ldap3 import Connection, Server, ALL + +def get_authenticated_connection( + hostname=current_app.config['LDAP_HOSTNAME'], + user=current_app.config['LDAP_BIND_USER_DN'], + password=current_app.config['LDAP_BIND_USER_PASSWORD'], + ) -> Connection: + """Returns a Connection object to the LDAP server using bind credentials. + + The bind credentials and server hostname are read from the :mod:`core.settings` + module. + + Attributes + ---------- + hostname : str + Hostname at which the LDAP server can be reached. + user : str + DN of the bind user used to authenticate to the server. + password : str + Password of the bind user authenticating to the server. + + Raises + ------ + :class:`ldap3.core.exceptions.LDAPSocketOpenError` + If the server specified by the ``hostname`` cannot be reached. + :class:`ldap3.core.exceptions.LDAPBindError` + If the bind credentials ``user`` and/or ``password`` are + invalid. + """ + + return Connection( + Server(hostname, get_info=ALL), + user=user, + password=password, + auto_bind=True, + ) diff --git a/requirements.txt b/requirements.txt index c9edc1a..1ec5d0f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ Flask==2.2.2 +ldap3==2.9.1