mirror of
https://github.com/zulip/zulip.git
synced 2025-11-09 16:37:23 +00:00
ldap: Add a setting to automatically deactivate non_matching users.
Fixes: #11151.
This commit is contained in:
committed by
Tim Abbott
parent
6797dea6c3
commit
71761bc2da
@@ -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/)
|
[this handy resource](https://jackstromberg.com/2013/01/useraccountcontrol-attributeflag-values/)
|
||||||
for details on the various `userAccountControl` flags.
|
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
|
||||||
|
|
||||||
Other fields you may want to sync from LDAP include:
|
Other fields you may want to sync from LDAP include:
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ def sync_ldap_user_data(user_profiles: List[UserProfile]) -> None:
|
|||||||
logger.info("Updated %s." % (u.email,))
|
logger.info("Updated %s." % (u.email,))
|
||||||
else:
|
else:
|
||||||
logger.warning("Did not find %s in LDAP." % (u.email,))
|
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:
|
except ZulipLDAPException as e:
|
||||||
logger.error("Error attempting to update user %s:" % (u.email,))
|
logger.error("Error attempting to update user %s:" % (u.email,))
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
|
|||||||
@@ -2587,6 +2587,19 @@ class TestZulipLDAPUserPopulator(ZulipLDAPTestCase):
|
|||||||
hamlet = self.example_user('hamlet')
|
hamlet = self.example_user('hamlet')
|
||||||
self.assertEqual(hamlet.avatar_source, UserProfile.AVATAR_FROM_USER)
|
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):
|
class TestZulipAuthMixin(ZulipTestCase):
|
||||||
def test_get_user(self) -> None:
|
def test_get_user(self) -> None:
|
||||||
backend = ZulipAuthMixin()
|
backend = ZulipAuthMixin()
|
||||||
|
|||||||
@@ -443,7 +443,11 @@ class ZulipLDAPUserPopulator(ZulipLDAPAuthBackendBase):
|
|||||||
def sync_user_from_ldap(user_profile: UserProfile) -> bool:
|
def sync_user_from_ldap(user_profile: UserProfile) -> bool:
|
||||||
backend = ZulipLDAPUserPopulator()
|
backend = ZulipLDAPUserPopulator()
|
||||||
updated_user = backend.populate_user(backend.django_to_ldap_username(user_profile.email))
|
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):
|
class DevAuthBackend(ZulipAuthMixin):
|
||||||
# Allow logging in as any user without a password.
|
# Allow logging in as any user without a password.
|
||||||
|
|||||||
@@ -478,6 +478,11 @@ AUTH_LDAP_USER_ATTR_MAP = {
|
|||||||
# "userAccountControl": "userAccountControl",
|
# "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.
|
# Miscellaneous settings.
|
||||||
|
|||||||
@@ -1297,6 +1297,11 @@ ZULIP_IOS_APP_ID = 'org.zulip.Zulip'
|
|||||||
|
|
||||||
USING_APACHE_SSO = ('zproject.backends.ZulipRemoteUserBackend' in AUTHENTICATION_BACKENDS)
|
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] ==
|
if len(AUTHENTICATION_BACKENDS) == 1 and (AUTHENTICATION_BACKENDS[0] ==
|
||||||
"zproject.backends.ZulipRemoteUserBackend"):
|
"zproject.backends.ZulipRemoteUserBackend"):
|
||||||
HOME_NOT_LOGGED_IN = "/accounts/login/sso/"
|
HOME_NOT_LOGGED_IN = "/accounts/login/sso/"
|
||||||
|
|||||||
Reference in New Issue
Block a user