diff --git a/README.rst b/README.rst index 87c3a1a..ebce850 100644 --- a/README.rst +++ b/README.rst @@ -70,6 +70,12 @@ To configure LDAP, create a yaml file with a dictionary containing another dicti ``timeout`` The timeout for connections to the LDAP server. Defaults to 10 seconds. + ``login_template`` + Template to insert the result from ``user_search`` into before attempting login + + ``group_required`` + Require the group search to be successful for authentication + The ``user_search`` and ``group_search`` settings are dictionaries with the following options: ``base`` @@ -90,7 +96,7 @@ The ``user_search`` and ``group_search`` settings are dictionaries with the foll password. ``devpi-ldap`` will extract this attribute from the search results and attempt to bind to the LDAP server using this DN and the password supplied by the user. If this bind succeeds, access is granted. - + ``userdn`` The distinguished name of the user which should be used for the search operation. For ``user_search``, if you don't have anonymous user search or for ``group_search`` if the users can't search their own groups, then you need to set this to a user which has the necessary rights. diff --git a/devpi_ldap/__init__.py b/devpi_ldap/__init__.py index a33997d..55fa725 100644 --- a/devpi_ldap/__init__.py +++ b/devpi_ldap/__init__.py @@ -1 +1 @@ -__version__ = '2.1.0' +__version__ = '2.1.1' diff --git a/devpi_ldap/main.py b/devpi_ldap/main.py index 743829a..4e8ac0b 100644 --- a/devpi_ldap/main.py +++ b/devpi_ldap/main.py @@ -80,6 +80,8 @@ def __init__(self, path): 'referrals', 'reject_as_unknown', 'tls', + 'login_template', + 'group_required' )) unknown_keys = set(self.keys()) - known_keys if unknown_keys: @@ -256,7 +258,11 @@ def validate(self, username, password): else: threadlog.debug("Validating user '%s' against LDAP at %s." % (username, self['url'])) username = escape(username) - userdn = self._userdn(username) + if 'login_template' in self: + userdn = self['login_template'].format(self._userdn(username)) + else: + userdn = self._userdn(username) + if not userdn: return dict(status="unknown") if not password.strip(): @@ -268,6 +274,9 @@ def validate(self, username, password): if not config: return dict(status="ok") groups = self._search(conn, config, username=username, userdn=userdn) + group_required = self.get('group_required', False) + if group_required and len(groups) < 1: + return self._rejection() return dict(status="ok", groups=groups) @@ -342,3 +351,4 @@ def main(argv=None): raise SystemExit(2) print("Authentication successful, the user is member of the following groups: %s" % ', '.join(result.get("groups", []))) +