Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions conditional/blueprints/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def display_dashboard(user_dict=None):
log.info('display dashboard')

# Get the list of voting members.

can_vote = get_voting_members()

data = {}
Expand Down
47 changes: 28 additions & 19 deletions conditional/util/housing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

from conditional.models.models import InHousingQueue
from conditional.models.models import OnFloorStatusAssigned
from conditional.util.ldap import ldap_get_current_students
from conditional.util.ldap import ldap_is_onfloor
from conditional.util.ldap import ldap_get_member, ldap_is_current_student


def get_housing_queue(is_eval_director=False):
Expand All @@ -12,23 +11,34 @@ def get_housing_queue(is_eval_director=False):
# and {'time': <datetime obj>} is the value. We are doing a left
# outer join on the two tables to get a single result that has
# both the member's UID and their on-floor datetime.
in_queue = {entry.uid: {'time': entry.onfloor_granted} for entry
in InHousingQueue.query.outerjoin(OnFloorStatusAssigned,
OnFloorStatusAssigned.uid == InHousingQueue.uid)\
.with_entities(InHousingQueue.uid, OnFloorStatusAssigned.onfloor_granted)\
.all()}
in_queue = {
entry.uid: {
'time': entry.onfloor_granted
} for entry in InHousingQueue.query.outerjoin(
OnFloorStatusAssigned,
OnFloorStatusAssigned.uid == InHousingQueue.uid
).with_entities(
InHousingQueue.uid,
OnFloorStatusAssigned.onfloor_granted
).all()
}

# CSHMember accounts that are in queue
potential_accounts = [ldap_get_member(username) for username in in_queue]

# Populate a list of dictionaries containing the name, username,
# and on-floor datetime for each member who has on-floor status,
# is not already assigned to a room and is in the above query.
queue = [{"uid": account.uid,
"name": account.cn,
"points": account.housingPoints,
"time": in_queue.get(account.uid, {}).get('time', datetime.now()) or datetime.now(),
"in_queue": account.uid in in_queue}
for account in ldap_get_current_students()
if ldap_is_onfloor(account) and (is_eval_director or account.uid in in_queue)
and account.roomNumber is None]
# and on-floor datetime for each current studetn who has on-floor status
# and is not already assigned to a room
queue = [
{
"uid": account.uid,
"name": account.cn,
"points": account.housingPoints,
"time": in_queue.get(account.uid, {}).get('time', datetime.now()) or datetime.now(),
"in_queue": account.uid in in_queue
} for account in potential_accounts
if ldap_is_current_student(account) and (is_eval_director or account.roomNumber is None)
]

# Sort based on time (ascending) and then points (decending).
queue.sort(key=lambda m: m['time'])
Expand All @@ -40,8 +50,7 @@ def get_housing_queue(is_eval_director=False):
def get_queue_position(username):
queue = get_housing_queue()
try:
index = next(index for (index, d) in enumerate(get_housing_queue())
if d["uid"] == username) + 1
index = next(index for (index, d) in enumerate(queue) if d["uid"] == username) + 1
except (KeyError, StopIteration):
index = None
return index, len(queue)
62 changes: 27 additions & 35 deletions conditional/util/ldap.py
Original file line number Diff line number Diff line change
@@ -1,123 +1,115 @@
from csh_ldap import CSHMember

from conditional import ldap
from conditional.util.cache import service_cache


def _ldap_get_group_members(group):
def _ldap_get_group_members(group: str) -> list[CSHMember]:
return ldap.get_group(group).get_members()


def _ldap_is_member_of_group(member, group):
group_list = member.get("memberOf")
for group_dn in group_list:
if group == group_dn.split(",")[0][3:]:
return True
return False
def _ldap_is_member_of_group(member: CSHMember, group: str) -> bool:
return ldap.get_group(group).check_member(member)


def _ldap_add_member_to_group(account, group):
def _ldap_add_member_to_group(account: CSHMember, group: str):
if not _ldap_is_member_of_group(account, group):
ldap.get_group(group).add_member(account, dn=False)


def _ldap_remove_member_from_group(account, group):
def _ldap_remove_member_from_group(account: CSHMember, group: str):
if _ldap_is_member_of_group(account, group):
ldap.get_group(group).del_member(account, dn=False)


@service_cache(maxsize=256)
def _ldap_is_member_of_directorship(account, directorship):
directors = ldap.get_directorship_heads(directorship)
for director in directors:
if director.uid == account.uid:
return True
return False

def _ldap_is_member_of_directorship(account: CSHMember, directorship: str):
return account.in_group(f'eboard-{directorship}', dn=True)
# TODO: try in_group(ldap.get_group(f'eboard-{directorship}')) and profile

@service_cache(maxsize=1024)
def ldap_get_member(username):
def ldap_get_member(username: str) -> CSHMember:
return ldap.get_member(username, uid=True)


@service_cache(maxsize=1024)
def ldap_get_active_members():
def ldap_get_active_members() -> list[CSHMember]:
return _ldap_get_group_members("active")


@service_cache(maxsize=1024)
def ldap_get_intro_members():
def ldap_get_intro_members() -> list[CSHMember]:
return _ldap_get_group_members("intromembers")


@service_cache(maxsize=1024)
def ldap_get_onfloor_members():
def ldap_get_onfloor_members() -> list[CSHMember]:
return _ldap_get_group_members("onfloor")


@service_cache(maxsize=1024)
def ldap_get_current_students():
def ldap_get_current_students() -> list[CSHMember]:
return _ldap_get_group_members("current_student")


@service_cache(maxsize=128)
def ldap_get_roomnumber(account):
def ldap_get_roomnumber(account) -> str:
try:
return account.roomNumber
except AttributeError:
return ""


@service_cache(maxsize=128)
def ldap_is_active(account):
def ldap_is_active(account) -> bool:
return _ldap_is_member_of_group(account, 'active')


@service_cache(maxsize=128)
def ldap_is_bad_standing(account):
def ldap_is_bad_standing(account) -> bool:
return _ldap_is_member_of_group(account, 'bad_standing')


@service_cache(maxsize=128)
def ldap_is_alumni(account):
def ldap_is_alumni(account) -> bool:
# If the user is not active, they are an alumni.
return not _ldap_is_member_of_group(account, 'active')


@service_cache(maxsize=128)
def ldap_is_eboard(account):
def ldap_is_eboard(account) -> bool:
return _ldap_is_member_of_group(account, 'eboard')


@service_cache(maxsize=128)
def ldap_is_rtp(account):
def ldap_is_rtp(account) -> bool:
return _ldap_is_member_of_group(account, 'rtp')


@service_cache(maxsize=128)
def ldap_is_intromember(account):
def ldap_is_intromember(account) -> bool:
return _ldap_is_member_of_group(account, 'intromembers')


@service_cache(maxsize=128)
def ldap_is_onfloor(account):
def ldap_is_onfloor(account) -> bool:
return _ldap_is_member_of_group(account, 'onfloor')


@service_cache(maxsize=128)
def ldap_is_financial_director(account):
def ldap_is_financial_director(account) -> bool:
return _ldap_is_member_of_directorship(account, 'Financial')


@service_cache(maxsize=128)
def ldap_is_eval_director(account):
def ldap_is_eval_director(account) -> bool:
return _ldap_is_member_of_directorship(account, 'Evaluations')


@service_cache(maxsize=256)
def ldap_is_current_student(account):
def ldap_is_current_student(account) -> bool:
return _ldap_is_member_of_group(account, 'current_student')


def ldap_set_housingpoints(account, housing_points):
def ldap_set_housingpoints(account, housing_points) -> bool:
account.housingPoints = housing_points
ldap_get_current_students.cache_clear()
ldap_get_member.cache_clear()
Expand Down
Loading