pyceo/ceod/api/positions.py

63 lines
2.2 KiB
Python

from flask import Blueprint, request
from zope import component
from .utils import authz_restrict_to_syscom, create_streaming_response
from ceo_common.errors import BadRequest
from ceo_common.interfaces import ILDAPService, IConfig
from ceod.transactions.members import UpdateMemberPositionsTransaction
bp = Blueprint('positions', __name__)
@bp.route('/', methods=['GET'], strict_slashes=False)
def get_positions():
ldap_srv = component.getUtility(ILDAPService)
positions = {}
for user in ldap_srv.get_users_with_positions():
for position in user.positions:
if position not in positions:
positions[position] = []
positions[position].append(user.uid)
return positions
@bp.route('/', methods=['POST'], strict_slashes=False)
@authz_restrict_to_syscom
def update_positions():
cfg = component.getUtility(IConfig)
body = request.get_json(force=True)
required = cfg.get('positions_required')
available = cfg.get('positions_available')
# remove falsy values and parse multiple users in each position
# Example: "user1,user2, user3" -> ["user1","user2","user3"]
position_to_usernames = {}
for position, usernames in body.items():
if not usernames:
continue
if type(usernames) is list:
position_to_usernames[position] = usernames
elif type(usernames) is str:
position_to_usernames[position] = usernames.replace(' ', '').split(',')
else:
raise BadRequest('usernames must be a list or comma-separated string')
# check for duplicates (i.e. one username specified twice in the same list)
for usernames in position_to_usernames.values():
if len(usernames) != len(set(usernames)):
raise BadRequest('username may only be specified at most once for a position')
for position in position_to_usernames.keys():
if position not in available:
raise BadRequest(f'unknown position: {position}')
for position in required:
if position not in position_to_usernames:
raise BadRequest(f'missing required position: {position}')
txn = UpdateMemberPositionsTransaction(position_to_usernames)
return create_streaming_response(txn)