Tiered LDAP groups

This commit is contained in:
2026-10-29 14:17:16 -04:00
parent 0bffd7d993
commit 920a608fba
10 changed files with 565 additions and 8 deletions
+8 -4
View File
@@ -112,8 +112,12 @@ def reconcile_groups(account, desired, managed):
raise ImproperlyConfigured("The LDAP sentinel must not be a login account.")
if not conn.search(placeholder, "(objectClass=*)", search_scope=BASE, attributes=["objectClass"]):
raise ImproperlyConfigured("LDAP sentinel does not exist.")
# Revoke obsolete tiers before granting new tiers on plan changes.
for group_dn in sorted(managed, key=lambda group: (group in desired, group)):
# A DN shared by multiple service levels is one target, even if its
# spelling changes case between mappings or historical records.
desired_keys = {group.casefold() for group in desired}
managed_targets = {group.casefold(): group for group in managed}
# Revoke obsolete grants before granting new ones on plan changes.
for group_dn in sorted(managed_targets.values(), key=lambda group: (group.casefold() in desired_keys, group)):
if not conn.search(group_dn, "(objectClass=groupOfUniqueNames)", search_scope=BASE, attributes=["uniqueMember"]):
raise ImproperlyConfigured("Managed group is missing or not groupOfUniqueNames.")
members = {str(value).casefold() for value in conn.entries[0].uniqueMember.values}
@@ -123,9 +127,9 @@ def reconcile_groups(account, desired, managed):
# Remove a stale DN too, e.g. after a directory rename.
candidates = {value.casefold(): value for value in (account.ldap_dn, dn)}
for candidate in candidates.values():
if candidate.casefold() in members and (group_dn not in desired or candidate.casefold() != dn.casefold()):
if candidate.casefold() in members and (group_dn.casefold() not in desired_keys or candidate.casefold() != dn.casefold()):
changes.append((MODIFY_DELETE, [candidate]))
if group_dn in desired and dn.casefold() not in members:
if group_dn.casefold() in desired_keys and dn.casefold() not in members:
changes.append((MODIFY_ADD, [dn]))
if changes and not conn.modify(group_dn, {"uniqueMember": changes}):
raise LDAPException("LDAP group synchronization failed.")