ldap: Add a setting to automatically deactivate non_matching users.

Fixes: #11151.
This commit is contained in:
Harshit Bansal 2019-01-13 12:53:52 +00:00 committed by Tim Abbott
parent 6797dea6c3
commit 71761bc2da
6 changed files with 42 additions and 1 deletions

View File

@ -179,6 +179,18 @@ This feature works by checking for the `ACCOUNTDISABLE` flag on the
[this handy resource](https://jackstromberg.com/2013/01/useraccountcontrol-attributeflag-values/)
for details on the various `userAccountControl` flags.
#### Deactivating non-matching users
Starting with Zulip 2.0, Zulip supports automatically deactivating
users if they are not found by the `AUTH_LDAP_USER_SEARCH` query
(either because the user is no longer in LDAP/Active Directory, or
because the user no longer matches the query). This feature is
enabled by default if LDAP is the only authentication backend
configured on the Zulip server. Otherwise, you can enable this
feature by setting `LDAP_DEACTIVATE_NON_MATCHING_USERS` to `True` in
`/etc/zulip/settings.py`. Nonmatching users will be fully deactivated
the next time your `manage.py sync_ldap_user_data` cron job runs.
#### Other fields
Other fields you may want to sync from LDAP include:

View File

@ -28,6 +28,8 @@ def sync_ldap_user_data(user_profiles: List[UserProfile]) -> None:
logger.info("Updated %s." % (u.email,))
else:
logger.warning("Did not find %s in LDAP." % (u.email,))
if settings.LDAP_DEACTIVATE_NON_MATCHING_USERS:
logger.info("Deactivated non-matching user: %s" % (u.email,))
except ZulipLDAPException as e:
logger.error("Error attempting to update user %s:" % (u.email,))
logger.error(e)

View File

@ -2587,6 +2587,19 @@ class TestZulipLDAPUserPopulator(ZulipLDAPTestCase):
hamlet = self.example_user('hamlet')
self.assertEqual(hamlet.avatar_source, UserProfile.AVATAR_FROM_USER)
def test_deactivate_non_matching_users(self) -> None:
self.mock_ldap.directory = {}
with self.settings(LDAP_APPEND_DOMAIN='zulip.com',
AUTH_LDAP_BIND_PASSWORD='',
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com',
LDAP_DEACTIVATE_NON_MATCHING_USERS=True):
result = sync_user_from_ldap(self.example_user('hamlet'))
self.assertFalse(result)
hamlet = self.example_user('hamlet')
self.assertFalse(hamlet.is_active)
class TestZulipAuthMixin(ZulipTestCase):
def test_get_user(self) -> None:
backend = ZulipAuthMixin()

View File

@ -443,7 +443,11 @@ class ZulipLDAPUserPopulator(ZulipLDAPAuthBackendBase):
def sync_user_from_ldap(user_profile: UserProfile) -> bool:
backend = ZulipLDAPUserPopulator()
updated_user = backend.populate_user(backend.django_to_ldap_username(user_profile.email))
return updated_user is not None
if not updated_user:
if settings.LDAP_DEACTIVATE_NON_MATCHING_USERS:
do_deactivate_user(user_profile)
return False
return True
class DevAuthBackend(ZulipAuthMixin):
# Allow logging in as any user without a password.

View File

@ -478,6 +478,11 @@ AUTH_LDAP_USER_ATTR_MAP = {
# "userAccountControl": "userAccountControl",
}
# Whether to automatically deactivate users not found in LDAP. If LDAP
# is the only authentication method, then this setting defaults to
# True. If other authentication methods are enabled, it defaults to
# False.
#LDAP_DEACTIVATE_NON_MATCHING_USERS = True
################
# Miscellaneous settings.

View File

@ -1297,6 +1297,11 @@ ZULIP_IOS_APP_ID = 'org.zulip.Zulip'
USING_APACHE_SSO = ('zproject.backends.ZulipRemoteUserBackend' in AUTHENTICATION_BACKENDS)
if 'LDAP_DEACTIVATE_NON_MATCHING_USERS' not in vars():
LDAP_DEACTIVATE_NON_MATCHING_USERS = (
len(AUTHENTICATION_BACKENDS) == 1 and (AUTHENTICATION_BACKENDS[0] ==
"zproject.backends.ZulipLDAPAuthBackend"))
if len(AUTHENTICATION_BACKENDS) == 1 and (AUTHENTICATION_BACKENDS[0] ==
"zproject.backends.ZulipRemoteUserBackend"):
HOME_NOT_LOGGED_IN = "/accounts/login/sso/"