From 6f23d2f6912a593add280b9feee9a0a6f7cb46a3 Mon Sep 17 00:00:00 2001 From: Greg Price Date: Tue, 25 Sep 2018 15:05:58 -0700 Subject: [PATCH] docs: Make a pass over LDAP config/setup docs. Expand on a few things that tend to confuse people (especially the `%(user)s` thing); move the `LDAPSearchUnion` example out to docs; adjust the instructions to fit a bit better in their new docs/ home. --- docs/production/authentication-methods.md | 28 ++++++++++++++++------- zproject/prod_settings_template.py | 26 +++++++++++++-------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/docs/production/authentication-methods.md b/docs/production/authentication-methods.md index aacac9da28..ae1e631db6 100644 --- a/docs/production/authentication-methods.md +++ b/docs/production/authentication-methods.md @@ -81,23 +81,35 @@ You can quickly test whether your configuration works by running: ``` ./manage.py query_ldap username@example.com ``` -From the root of your Zulip installation; if your configuration is working +from the root of your Zulip installation. If your configuration is working, that will output the full name for your user. -**If you are using LDAP for authentication**, you will need to enable -the zproject.backends.ZulipLDAPAuthBackend auth backend in -AUTHENTICATION_BACKENDS above. After doing so, you should be able -to login to Zulip by entering your email address and LDAP password -on the Zulip login form. +**If you are using LDAP for authentication**: you will need to enable +the `zproject.backends.ZulipLDAPAuthBackend` auth backend, in +`AUTHENTICATION_BACKENDS` in `/etc/zulip/settings.py`. After doing +so (and as always [restarting the Zulip server](settings.html) to ensure +your settings changes take effect), you should be able to log into +Zulip by entering your email address and LDAP password on the Zulip +login form. -**If you are using LDAP to populate names in Zulip**, once you finish +**If you are using LDAP to populate names in Zulip**: once you finish configuring this integration, you will need to run: ``` ./manage.py sync_ldap_user_data ``` -To sync names for existing users; you may want to run this in a cron +to sync names for existing users. You may want to run this in a cron job to pick up name changes made on your LDAP server. +### Multiple LDAP searches + +To do the union of multiple LDAP searches, use `LDAPSearchUnion`. For example: +``` +AUTH_LDAP_USER_SEARCH = LDAPSearchUnion( + LDAPSearch("ou=users,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"), + LDAPSearch("ou=otherusers,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"), +) +``` + ## Apache-based SSO with `REMOTE_USER` If you have any existing SSO solution where a preferred way to deploy diff --git a/zproject/prod_settings_template.py b/zproject/prod_settings_template.py index df36865692..28813bce40 100644 --- a/zproject/prod_settings_template.py +++ b/zproject/prod_settings_template.py @@ -382,12 +382,13 @@ from django_auth_ldap.config import LDAPSearch, GroupOfNamesType, LDAPSearchUnio ######## # LDAP integration, part 1: Connecting to the LDAP server. -# URI of your LDAP server. If set, LDAP is used to prepopulate a user's name in -# Zulip. Example: "ldaps://ldap.example.com" +# The LDAP server to connect to. Setting this enables Zulip +# automatically fetching each new user's name from LDAP. +# Example: "ldaps://ldap.example.com" AUTH_LDAP_SERVER_URI = "" -# This DN will be used to bind to your server. If unset, anonymous -# binds are performed. +# The DN of the user to bind as (i.e., authenticate as) in order to +# query LDAP. If unset, Zulip does an anonymous bind. AUTH_LDAP_BIND_DN = "" # Passwords and secrets are not stored in this file. The password @@ -399,14 +400,15 @@ AUTH_LDAP_BIND_DN = "" ######## # LDAP integration, part 2: Mapping user info from LDAP to Zulip. -# Specify the search base and the property to filter on that corresponds to the -# username. One can use LDAPSearchUnion to do the union of multiple LDAP searches. +# The LDAP search query to find a given user. +# +# The arguments to `LDAPSearch` are (base DN, scope, filter). In the +# filter, the string `%(user)s` is a Python placeholder; the Zulip +# server will replace this with the user's Zulip username. For more +# details and alternatives, see the Zulip documentation: +# https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#ldap AUTH_LDAP_USER_SEARCH = LDAPSearch("ou=users,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)") -#AUTH_LDAP_USER_SEARCH = LDAPSearchUnion( -# LDAPSearch("ou=users,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"), -# LDAPSearch("ou=otherusers,dc=example,dc=com", ldap.SCOPE_SUBTREE, "(uid=%(user)s)"), -#) # If the value of a user's "uid" (or similar) property is not their email # address, specify the domain to append here. @@ -417,6 +419,10 @@ LDAP_APPEND_DOMAIN = None # type: Optional[str] LDAP_EMAIL_ATTR = None # type: Optional[str] # This map defines how to populate attributes of a Zulip user from LDAP. +# +# The format is `zulip_name: ldap_name`; each entry maps a Zulip +# concept (on the left) to the LDAP attribute name (on the right) your +# LDAP database uses for the same concept. AUTH_LDAP_USER_ATTR_MAP = { # full_name is required; common values include "cn" or "displayName". "full_name": "cn",