add new execs to exec group

This commit is contained in:
Max Erenberg 2021-08-22 01:27:39 +00:00
parent 2c150193fc
commit 5e8415ad5d
7 changed files with 45 additions and 15 deletions

View File

@ -1,3 +1,5 @@
from typing import List
from zope.interface import Interface, Attribute
@ -21,5 +23,8 @@ class IGroup(Interface):
def remove_member(username: str):
"""Remove the member from this group in LDAP."""
def set_members(usernames: List[str]):
"""Set all of the members of this group in LDAP."""
def to_dict():
"""Serialize this group as JSON."""

View File

@ -25,7 +25,7 @@ class ILDAPService(Interface):
"""
def get_users_with_positions(self) -> List[IUser]:
"""Retrieve users who has their position set"""
"""Retrieve users who have a non-empty position attribute."""
def add_user(user: IUser):
"""

View File

@ -27,6 +27,6 @@ class Config:
return True
if val.lower() in ['false', 'no']:
return False
if section.startswith('auxiliary '):
if section.startswith('auxiliary ') or section == 'positions':
return val.split(',')
return val

View File

@ -29,9 +29,8 @@ def create_app(flask_config={}):
# Only ceod_admin_host should serve the /api/members endpoints because
# it needs to run kadmin
if hostname == cfg.get('ceod_admin_host'):
from ceod.api import members, positions
from ceod.api import members
app.register_blueprint(members.bp, url_prefix='/api/members')
app.register_blueprint(positions.bp, url_prefix='/api/positions')
# Only offer mailman API if this host is running Mailman
if hostname == cfg.get('ceod_mailman_host'):
@ -41,6 +40,9 @@ def create_app(flask_config={}):
from ceod.api import groups
app.register_blueprint(groups.bp, url_prefix='/api/groups')
from ceod.api import positions
app.register_blueprint(positions.bp, url_prefix='/api/positions')
from ceod.api import uwldap
app.register_blueprint(uwldap.bp, url_prefix='/api/uwldap')

View File

@ -105,3 +105,10 @@ class Group:
logger.warning(err)
raise UserNotInGroupError()
self.members.remove(username)
def set_members(self, usernames: List[str]):
DNs = [
self.ldap_srv.uid_to_dn(username) for username in usernames
]
with self.ldap_srv.entry_ctx_for_group(self) as entry:
entry.uniqueMember = DNs

View File

@ -96,7 +96,7 @@ class LDAPService:
{
'uid': entry.uid.value,
'cn': entry.cn.value,
'program': entry.program.value,
'program': entry.program.value or 'Unknown',
}
for entry in conn.entries
]

View File

@ -16,14 +16,13 @@ class UpdateMemberPositionsTransaction(AbstractTransaction):
operations = [
'update_positions_ldap',
'update_exec_group_ldap',
'subscribe_to_mailing_lists',
]
def __init__(self, positions_reversed: Dict[str, str]):
# positions_reversed is position -> username
super().__init__()
# self.old_positions is username -> positions
self.old_positions = {} # For rollback
self.ldap_srv = component.getUtility(ILDAPService)
# Reverse the dict so it's easier to use (username -> positions)
@ -34,11 +33,14 @@ class UpdateMemberPositionsTransaction(AbstractTransaction):
# a cached Dict of the Users who need to be modified (username -> User)
self.users: Dict[str, IUser] = {}
# for rollback purposes
self.old_positions = {} # username -> positions
self.old_execs = []
def child_execute_iter(self):
cfg = component.getUtility(IConfig)
mailing_lists = cfg.get('auxiliary mailing lists_exec')
subscribe_status: Dict[str, bool] = {}
# position -> username
new_positions_reversed = {} # For returning result
@ -53,9 +55,9 @@ class UpdateMemberPositionsTransaction(AbstractTransaction):
self.positions[user.uid] = []
self.users[user.uid] = user
# Update positions via ldap
for username, user in self.users.items():
new_positions = self.positions[username]
# Update positions in LDAP
for username, new_positions in self.positions.items():
user = self.users[username]
old_positions = user.positions[:]
user.set_positions(new_positions)
@ -63,14 +65,24 @@ class UpdateMemberPositionsTransaction(AbstractTransaction):
self.old_positions[username] = old_positions
for position in new_positions:
new_positions_reversed[position] = username
subscribe_status[username] = len(new_positions) > 0
yield 'update_positions_ldap'
# Update mailing list subscription
for username, subscribe in subscribe_status.items():
# update exec group in LDAP
exec_group = self.ldap_srv.get_group('exec')
self.old_execs = exec_group.members[:]
new_execs = [
username for username, new_positions in self.positions.items()
if len(new_positions) > 0
]
exec_group.set_members(new_execs)
yield 'update_exec_group_ldap'
# Update mailing list subscriptions
for username, new_positions in self.positions.items():
user = self.users[username]
for mailing_list in mailing_lists:
try:
if subscribe:
if len(new_positions) > 0:
user.subscribe_to_mailing_list(mailing_list)
else:
user.unsubscribe_from_mailing_list(mailing_list)
@ -83,6 +95,10 @@ class UpdateMemberPositionsTransaction(AbstractTransaction):
self.finish(new_positions_reversed)
def rollback(self):
if 'update_exec_group_ldap' in self.finished_operations:
exec_group = self.ldap_srv.get_group('exec')
exec_group.set_members(self.old_execs)
for username, positions in self.old_positions.items():
user = self.users[username]
user.set_positions(positions)