ldap: Add option to use a customer LDAP query for looking up the user logging in

This allows for more advanced integration of LDAP databases that are not
covered by the default behaviour of is_active_directory.

Signed-off-by: Nick Douma <n.douma@nekoconeko.nl>
This commit is contained in:
Nick Douma 2022-10-22 00:20:32 +02:00 committed by Eric Callahan
parent 379bcb10f9
commit 6afa664ac9
2 changed files with 21 additions and 1 deletions

View File

@ -381,7 +381,16 @@ group_dn: CN=moonraker,OU=Groups,DC=ldap,DC=local
# authentication. This option accepts Jinja2 Templates, see the [secrets]
# section for details. The default is no group requirement.
is_active_directory: True
# Enables support for Microsoft Active Directory. The default is False.
# Enables support for Microsoft Active Directory. This option changes the
# field used to lookup a user by username to sAMAccountName.
# The default is False.
user_filter: (&(objectClass=user)(cn=USERNAME))
# Allows filter of users by custom LDAP query. Must contain the USERNAME
# token, it will be replaced by the user's username during lookup. Will
# override the change done by is_active_directory. This option accepts
# Jinja2 Templates, see the [secrets] section for details.
# The default is empty, which will change the lookup query depending on
# is_active_directory.
```
### `[octoprint_compat]`

View File

@ -46,6 +46,15 @@ class MoonrakerLDAP:
"required when 'bind_dn' is provided"
)
self.bind_password = bind_pass_template.render()
self.user_filter: Optional[str] = None
user_filter_template = config.gettemplate('user_filter', None)
if user_filter_template is not None:
self.user_filter = user_filter_template.render()
if "USERNAME" not in self.user_filter:
raise config.error(
"Section [ldap]: Option 'user_filter' is "
"is missing required token USERNAME"
)
self.lock = asyncio.Lock()
async def authenticate_ldap_user(self, username, password) -> None:
@ -67,6 +76,8 @@ class MoonrakerLDAP:
}
attr_name = "sAMAccountName" if self.active_directory else "uid"
ldfilt = f"(&(objectClass=Person)({attr_name}={username}))"
if self.user_filter:
ldfilt = self.user_filter.replace("USERNAME", username)
try:
with ldap3.Connection(server, **conn_args) as conn:
ret = conn.search(