Browse Source

Add synchronous user sync

master
klonfish 6 years ago
parent
commit
38716eb822
  1. 5
      README.md
  2. 3
      bam/apps.py
  3. 11
      bam/ldap_sync.py
  4. 38
      bam/signals.py

5
README.md

@ -82,6 +82,11 @@ ln -sr bam PROJECT_DIRECTORY/bam
} }
``` ```
* `BAM_LDAP_SYNCHRONOUS_SYNC_ENABLED`: If `True`, changes are immediately
propagated to LDAP when they are made through the web frontend. If `False`,
the `sync_users` management command has to be used to perform this task for
all users. (Optional, default: `True`)
## ToDo ## ToDo
### Essential ### Essential

3
bam/apps.py

@ -3,3 +3,6 @@ from django.apps import AppConfig
class BamConfig(AppConfig): class BamConfig(AppConfig):
name = 'bam' name = 'bam'
def ready(self):
import bam.signals

11
bam/ldap_sync.py

@ -77,7 +77,7 @@ class LDAPUserEntry():
pw_hash = transform_password(self.user.password) pw_hash = transform_password(self.user.password)
attrs[cls.passw_attr] = pw_hash attrs[cls.passw_attr] = pw_hash
return {k: [v.encode('utf8')] for k, v in attrs.items()} return {k: [v.encode('utf8')] for k, v in attrs.items()}
def get(self): def get(self):
@ -150,3 +150,12 @@ class LDAPUserSyncer():
actions.append(action) actions.append(action)
return actions return actions
def remove_user(self, user):
actions = []
for base_dn in self.base_dn_map:
user_entry = LDAPUserEntry(user, self.conn, base_dn)
action = user_entry.delete_if_present()
actions.append(action)
return actions

38
bam/signals.py

@ -0,0 +1,38 @@
from django.dispatch import receiver
from django.db.models.signals import post_save, post_delete, m2m_changed
from django.contrib.auth import get_user_model
from django.conf import settings
from .ldap_sync import make_ldap_conn, LDAPAction, LDAPUserSyncer
User = get_user_model()
def synchronous_user_sync(user, remove=False):
sync_enabled = getattr(settings, 'BAM_LDAP_SYNCHRONOUS_SYNC_ENABLED', True)
if sync_enabled:
uri = settings.BAM_LDAP_URI
bind_dn = settings.BAM_LDAP_BIND_DN
secret = settings.BAM_LDAP_SECRET
base_dn_map = settings.BAM_LDAP_BASE_DN_MAP
ldap_conn = make_ldap_conn(uri, bind_dn, secret)
try:
syncer = LDAPUserSyncer(ldap_conn, base_dn_map)
if remove:
syncer.remove_user(user)
else:
syncer.sync_user(user)
finally:
ldap_conn.unbind_s()
@receiver(post_save, sender=User)
def handle_user_save(sender, instance, **kwargs):
synchronous_user_sync(instance)
@receiver(post_delete, sender=User)
def handle_user_delete(sender, instance, **kwargs):
synchronous_user_sync(instance, remove=True)
@receiver(m2m_changed, sender=User.groups.through)
def handle_user_groups_change(sender, instance, action, **kwargs):
if action in ('post_add', 'post_remove'):
synchronous_user_sync(instance)
Loading…
Cancel
Save