diff --git a/README.md b/README.md index 06d4e1a4..d9d4271f 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,20 @@ If it doesn't work for some reason, you may have to globally install gulp throug npm install -g gulp ``` +### Local Development +* PostgreSQL +You'll need a postgres instance to use as a development DB. +You can use an existing database, like the instance used for the dev branch, use a database on another server, or spin up a container using docker or podman. +To get setup using docker, run +```bash +docker run --name packet-postgres -e POSTGRES_PASSWORD=mysecretpassword -d -p 5432:5432 postgres +``` +After the container starts up, you should be able to connect with the connection string `postgresql://postgres:mysecretpassword@localhost:5432/postgres`, which is the default connection string in `config.env.py`. +Once the container is up, run the following to set up the database tables. +```bash +flask db upgrade +``` + ### Secrets and configuration Packet supports 2 primary configuration methods: 1. Environment variables - See `config.env.py` for the expected names and default values. diff --git a/config.env.py b/config.env.py index 02125fad..b14e3eb2 100644 --- a/config.env.py +++ b/config.env.py @@ -3,7 +3,7 @@ See the readme for more information """ from distutils.util import strtobool -from os import environ +from os import environ, path, getcwd # Flask config DEBUG = False @@ -25,12 +25,25 @@ OIDC_CLIENT_SECRET = environ.get("PACKET_OIDC_CLIENT_SECRET", "PLEASE_REPLACE_ME") # SQLAlchemy config -SQLALCHEMY_DATABASE_URI = environ.get("PACKET_DATABASE_URI", None) +SQLALCHEMY_DATABASE_URI = environ.get("PACKET_DATABASE_URI", "postgresql://postgres:mysecretpassword@localhost:5432/postgres") SQLALCHEMY_TRACK_MODIFICATIONS = False # LDAP config LDAP_BIND_DN = environ.get("PACKET_LDAP_BIND_DN", None) LDAP_BIND_PASS = environ.get("PACKET_LDAP_BIND_PASS", None) +LDAP_MOCK_MEMBERS = [ + {'uid':'evals', 'groups': ['eboard', 'eboard-evaluations', 'active']}, + {'uid':'imps-3da', 'groups': ['eboard', 'eboard-imps', '3da', 'active']}, + { + 'uid':'rtp-cm-webs-onfloor', + 'groups': ['active-rtp', 'rtp', 'constitutional_maintainers', 'webmaster', 'active', 'onfloor'], + 'room_number': 1024 + }, + {'uid':'misc-rtp', 'groups': ['rtp']}, + {'uid':'onfloor', 'groups': ['active', 'onfloor'], 'room_number': 1024}, + {'uid':'active-offfloor', 'groups': ['active']}, + {'uid':'alum', 'groups': ['member']}, + ] # Mail Config MAIL_PROD = strtobool(environ.get("PACKET_MAIL_PROD", "False")) diff --git a/packet/__init__.py b/packet/__init__.py index 32e9fe74..89b7728b 100644 --- a/packet/__init__.py +++ b/packet/__init__.py @@ -50,19 +50,31 @@ app.config['OIDC_CLIENT_SECRET'])) # Initialize Onesignal Notification apps -csh_onesignal_client = onesignal.Client(user_auth_key=app.config['ONESIGNAL_USER_AUTH_KEY'], - app_auth_key=app.config['ONESIGNAL_CSH_APP_AUTH_KEY'], - app_id=app.config['ONESIGNAL_CSH_APP_ID']) - -intro_onesignal_client = onesignal.Client(user_auth_key=app.config['ONESIGNAL_USER_AUTH_KEY'], - app_auth_key=app.config['ONESIGNAL_INTRO_APP_AUTH_KEY'], - app_id=app.config['ONESIGNAL_INTRO_APP_ID']) +csh_onesignal_client = None +if app.config['ONESIGNAL_USER_AUTH_KEY'] and \ + app.config['ONESIGNAL_CSH_APP_AUTH_KEY'] and \ + app.config['ONESIGNAL_CSH_APP_ID']: + csh_onesignal_client = onesignal.Client( + user_auth_key=app.config['ONESIGNAL_USER_AUTH_KEY'], + app_auth_key=app.config['ONESIGNAL_CSH_APP_AUTH_KEY'], + app_id=app.config['ONESIGNAL_CSH_APP_ID'] + ) + app.logger.info('CSH Onesignal configured and notifications enabled') + +intro_onesignal_client = None +if app.config['ONESIGNAL_USER_AUTH_KEY'] and \ + app.config['ONESIGNAL_INTRO_APP_AUTH_KEY'] and \ + app.config['ONESIGNAL_INTRO_APP_ID']: + intro_onesignal_client = onesignal.Client( + user_auth_key=app.config['ONESIGNAL_USER_AUTH_KEY'], + app_auth_key=app.config['ONESIGNAL_INTRO_APP_AUTH_KEY'], + app_id=app.config['ONESIGNAL_INTRO_APP_ID'] + ) + app.logger.info('Intro Onesignal configured and notifications enabled') # OIDC Auth auth = OIDCAuthentication({'app': APP_CONFIG}, app) - -# LDAP -_ldap = csh_ldap.CSHLDAP(app.config['LDAP_BIND_DN'], app.config['LDAP_BIND_PASS']) +app.logger.info('OIDCAuth configured') # Sentry sentry_sdk.init( @@ -70,9 +82,9 @@ integrations=[FlaskIntegration(), SqlalchemyIntegration()] ) -app.logger.info('OIDCAuth and LDAP configured') # pylint: disable=wrong-import-position +from .ldap import ldap from . import models from . import context_processors from . import commands diff --git a/packet/context_processors.py b/packet/context_processors.py index 2e8d5c55..bff75b15 100644 --- a/packet/context_processors.py +++ b/packet/context_processors.py @@ -6,16 +6,15 @@ from functools import lru_cache from datetime import datetime -from packet.ldap import ldap_get_member from packet.models import Freshman -from packet import app +from packet import app, ldap # pylint: disable=bare-except @lru_cache(maxsize=128) def get_csh_name(username): try: - member = ldap_get_member(username) + member = ldap.get_member(username) return member.cn + ' (' + member.uid + ')' except: return username diff --git a/packet/ldap.py b/packet/ldap.py index 29b1bf27..4fcb7387 100644 --- a/packet/ldap.py +++ b/packet/ldap.py @@ -5,197 +5,260 @@ from functools import lru_cache from datetime import date -from packet import _ldap +from csh_ldap import CSHLDAP +from packet import app -def _ldap_get_group_members(group): - """ - :return: A list of CSHMember instances - """ - return _ldap.get_group(group).get_members() +class MockMember: -def _ldap_is_member_of_group(member, group): - """ - :param member: A CSHMember instance - """ - for group_dn in member.get('memberOf'): - if group == group_dn.split(',')[0][3:]: - return True + def __init__(self, uid: str, groups: list = None, cn: str = None, room_number: int = None): + self.uid = uid + self.groups = groups if groups else list() + if room_number: + self.room_number = room_number + self.cn = cn if cn else uid.title() # pylint: disable=invalid-name - return False + def __eq__(self, other): + if type(other) is type(self): + return self.uid == other.uid + return False -# Getters -@lru_cache(maxsize=256) -def ldap_get_member(username): - """ - :return: A CSHMember instance - """ - return _ldap.get_member(username, uid=True) + def __hash__(self): + return hash(self.uid) -def ldap_get_active_members(): - """ - Gets all current, dues-paying members - :return: A list of CSHMember instances - """ - return _ldap_get_group_members('active') + def __repr__(self): + return f'MockMember(uid: {self.uid}, groups: {self.groups})' -def ldap_get_intro_members(): - """ - Gets all freshmen members - :return: A list of CSHMember instances - """ - return _ldap_get_group_members('intromembers') - - -def ldap_get_eboard(): - """ - Gets all voting members of eboard - :return: A list of CSHMember instances - """ - members = _ldap_get_group_members('eboard-chairman') + _ldap_get_group_members('eboard-evaluations' - ) + _ldap_get_group_members('eboard-financial') + _ldap_get_group_members('eboard-history' - ) + _ldap_get_group_members('eboard-imps') + _ldap_get_group_members('eboard-opcomm' - ) + _ldap_get_group_members('eboard-research') + _ldap_get_group_members('eboard-social' - ) - - return members - - -def ldap_get_live_onfloor(): - """ - All upperclassmen who live on floor and are not eboard - :return: A list of CSHMember instances - """ - members = [] - onfloor = _ldap_get_group_members('onfloor') - for member in onfloor: - if ldap_get_roomnumber(member) and not ldap_is_eboard(member): - members.append(member) +class LDAPWrapper: - return members + def __init__(self, cshldap=None, mock_members=None): + self.ldap = cshldap + self.mock_members = mock_members + if self.ldap: + app.logger.info('LDAP configured with CSH LDAP') + else: + app.logger.info('LDAP configured with local mock') -def ldap_get_active_rtps(): - """ - All active RTPs - :return: A list of CSHMember instances - """ - return [member.uid for member in _ldap_get_group_members('active_rtp')] + def _get_group_members(self, group): + """ + :return: A list of CSHMember instances + """ + if self.ldap: + return self.ldap.get_group(group).get_members() + else: + return list(filter(lambda member: group in member.groups, self.mock_members)) -def ldap_get_3das(): - """ - All 3das - :return: A list of CSHMember instances - """ - return [member.uid for member in _ldap_get_group_members('3da')] + def _is_member_of_group(self, member, group): + """ + :param member: A CSHMember instance + """ + if self.ldap: + for group_dn in member.get('memberOf'): + if group == group_dn.split(',')[0][3:]: + return True + return False + else: + return group in member.groups -def ldap_get_webmasters(): - """ - All webmasters - :return: A list of CSHMember instances - """ - return [member.uid for member in _ldap_get_group_members('webmaster')] - - -def ldap_get_constitutional_maintainers(): - """ - All constitutional maintainers - :return: A list of CSHMember instances - """ - return [member.uid for member in _ldap_get_group_members('constitutional_maintainers')] - - -def ldap_get_wiki_maintainers(): - """ - All wiki maintainers - :return: A list of CSHMember instances - """ - return [member.uid for member in _ldap_get_group_members('wiki_maintainers')] - - -def ldap_get_drink_admins(): - """ - All drink admins - :return: A list of CSHMember instances - """ - return [member.uid for member in _ldap_get_group_members('drink')] - - -def ldap_get_eboard_role(member): - """ - :param member: A CSHMember instance - :return: A String or None - """ - - return_val = None - - if _ldap_is_member_of_group(member, 'eboard-chairman'): - return_val = 'Chairperson' - elif _ldap_is_member_of_group(member, 'eboard-evaluations'): - return_val = 'Evals' - elif _ldap_is_member_of_group(member, 'eboard-financial'): - return_val = 'Financial' - elif _ldap_is_member_of_group(member, 'eboard-history'): - return_val = 'History' - elif _ldap_is_member_of_group(member, 'eboard-imps'): - return_val = 'Imps' - elif _ldap_is_member_of_group(member, 'eboard-opcomm'): - return_val = 'OpComm' - elif _ldap_is_member_of_group(member, 'eboard-research'): - return_val = 'R&D' - elif _ldap_is_member_of_group(member, 'eboard-social'): - return_val = 'Social' - elif _ldap_is_member_of_group(member, 'eboard-secretary'): - return_val = 'Secretary' - - return return_val - - -# Status checkers -def ldap_is_eboard(member): - """ - :param member: A CSHMember instance - """ - return _ldap_is_member_of_group(member, 'eboard') - - -def ldap_is_evals(member): - return _ldap_is_member_of_group(member, 'eboard-evaluations') - - -def ldap_is_rtp(member): - return _ldap_is_member_of_group(member, 'rtp') - - -def ldap_is_intromember(member): - """ - :param member: A CSHMember instance - """ - return _ldap_is_member_of_group(member, 'intromembers') - - -def ldap_is_on_coop(member): - """ - :param member: A CSHMember instance - """ - if date.today().month > 6: - return _ldap_is_member_of_group(member, 'fall_coop') - else: - return _ldap_is_member_of_group(member, 'spring_coop') - - -def ldap_get_roomnumber(member): - """ - :param member: A CSHMember instance - """ - try: - return member.roomNumber - except AttributeError: - return None + # Getters + + @lru_cache(maxsize=256) + def get_member(self, username): + """ + :return: A CSHMember instance + """ + if self.ldap: + return self.ldap.get_member(username, uid=True) + else: + member = next(filter(lambda member: member.uid == username, self.mock_members), None) + if member: + return member + raise KeyError('Invalid Search Name') + + + def get_active_members(self): + """ + Gets all current, dues-paying members + :return: A list of CSHMember instances + """ + return self._get_group_members('active') + + + def get_intro_members(self): + """ + Gets all freshmen members + :return: A list of CSHMember instances + """ + return self._get_group_members('intromembers') + + + def get_eboard(self): + """ + Gets all voting members of eboard + :return: A list of CSHMember instances + """ + members = self._get_group_members('eboard-chairman') + self._get_group_members('eboard-evaluations' + ) + self._get_group_members('eboard-financial') + self._get_group_members('eboard-history' + ) + self._get_group_members('eboard-imps') + self._get_group_members('eboard-opcomm' + ) + self._get_group_members('eboard-research') + self._get_group_members('eboard-social' + ) + + return members + + + def get_live_onfloor(self): + """ + All upperclassmen who live on floor and are not eboard + :return: A list of CSHMember instances + """ + members = [] + onfloor = self._get_group_members('onfloor') + for member in onfloor: + if self.get_roomnumber(member) and not self.is_eboard(member): + members.append(member) + + return members + + + def get_active_rtps(self): + """ + All active RTPs + :return: A list of CSHMember instances + """ + return [member.uid for member in self._get_group_members('active_rtp')] + + + def get_3das(self): + """ + All 3das + :return: A list of CSHMember instances + """ + return [member.uid for member in self._get_group_members('3da')] + + + def get_webmasters(self): + """ + All webmasters + :return: A list of CSHMember instances + """ + return [member.uid for member in self._get_group_members('webmaster')] + + + def get_constitutional_maintainers(self): + """ + All constitutional maintainers + :return: A list of CSHMember instances + """ + return [member.uid for member in self._get_group_members('constitutional_maintainers')] + + def get_wiki_maintainers(self): + """ + All wiki maintainers + :return: A list of CSHMember instances + """ + return [member.uid for member in self._get_group_members('wiki_maintainers')] + + + def get_drink_admins(self): + """ + All drink admins + :return: A list of CSHMember instances + """ + return [member.uid for member in self._get_group_members('drink')] + + + def get_eboard_role(self, member): + """ + :param member: A CSHMember instance + :return: A String or None + """ + + return_val = None + + if self._is_member_of_group(member, 'eboard-chairman'): + return_val = 'Chairperson' + elif self._is_member_of_group(member, 'eboard-evaluations'): + return_val = 'Evals' + elif self._is_member_of_group(member, 'eboard-financial'): + return_val = 'Financial' + elif self._is_member_of_group(member, 'eboard-history'): + return_val = 'History' + elif self._is_member_of_group(member, 'eboard-imps'): + return_val = 'Imps' + elif self._is_member_of_group(member, 'eboard-opcomm'): + return_val = 'OpComm' + elif self._is_member_of_group(member, 'eboard-research'): + return_val = 'R&D' + elif self._is_member_of_group(member, 'eboard-social'): + return_val = 'Social' + elif self._is_member_of_group(member, 'eboard-secretary'): + return_val = 'Secretary' + + return return_val + + + # Status checkers + def is_eboard(self, member): + """ + :param member: A CSHMember instance + """ + return self._is_member_of_group(member, 'eboard') + + + def is_evals(self, member): + return self._is_member_of_group(member, 'eboard-evaluations') + + + def is_rtp(self, member): + return self._is_member_of_group(member, 'rtp') + + + def is_intromember(self, member): + """ + :param member: A CSHMember instance + """ + return self._is_member_of_group(member, 'intromembers') + + + def is_on_coop(self, member): + """ + :param member: A CSHMember instance + """ + if date.today().month > 6: + return self._is_member_of_group(member, 'fall_coop') + else: + return self._is_member_of_group(member, 'spring_coop') + + + def get_roomnumber(self, member): # pylint: disable=no-self-use + """ + :param member: A CSHMember instance + """ + try: + return member.roomNumber + except AttributeError: + return None + + +if app.config['LDAP_BIND_DN'] and app.config['LDAP_BIND_PASS']: + ldap = LDAPWrapper(cshldap=CSHLDAP(app.config['LDAP_BIND_DN'], + app.config['LDAP_BIND_PASS'] + ) +) +else: + ldap = LDAPWrapper( + mock_members=list( + map( + lambda mock_dict: MockMember(**mock_dict), + app.config['LDAP_MOCK_MEMBERS'] + ) + ) + ) diff --git a/packet/log_utils.py b/packet/log_utils.py index 66c14531..5481bef9 100644 --- a/packet/log_utils.py +++ b/packet/log_utils.py @@ -5,9 +5,8 @@ from functools import wraps from datetime import datetime -from packet import app +from packet import app, ldap from packet.context_processors import get_rit_name -from packet.ldap import ldap_get_member from packet.utils import is_freshman_on_floor @@ -39,7 +38,7 @@ def _format_cache(func): # Tuple of lru_cache functions to log stats from -_caches = (get_rit_name, ldap_get_member, is_freshman_on_floor) +_caches = (get_rit_name, ldap.get_member, is_freshman_on_floor) def log_cache(func): diff --git a/packet/notifications.py b/packet/notifications.py index a3a93f2c..e7182653 100644 --- a/packet/notifications.py +++ b/packet/notifications.py @@ -11,6 +11,20 @@ 'url': app.config['PROTOCOL'] + app.config['SERVER_NAME'] } +def require_onesignal_intro(func): + def require_onesignal_intro_wrapper(*args, **kwargs): + if intro_onesignal_client: + return func(*args, **kwargs) + return None + return require_onesignal_intro_wrapper + +def require_onesignal_csh(func): + def require_onesignal_csh_wrapper(*args, **kwargs): + if csh_onesignal_client: + return func(*args, **kwargs) + return None + return require_onesignal_csh_wrapper + def send_notification(notification_body, subscriptions, client): tokens = list(map(lambda subscription: subscription.token, subscriptions)) @@ -24,6 +38,7 @@ def send_notification(notification_body, subscriptions, client): app.logger.warn('The notification ({}) was unsuccessful'.format(notification.post_body)) +@require_onesignal_intro def packet_signed_notification(packet, signer): subscriptions = NotificationSubscription.query.filter_by(freshman_username=packet.freshman_username) if subscriptions: @@ -36,6 +51,8 @@ def packet_signed_notification(packet, signer): send_notification(notification_body, subscriptions, intro_onesignal_client) +@require_onesignal_csh +@require_onesignal_intro def packet_100_percent_notification(packet): member_subscriptions = NotificationSubscription.query.filter(NotificationSubscription.member.isnot(None)) intro_subscriptions = NotificationSubscription.query.filter(NotificationSubscription.freshman_username.isnot(None)) @@ -50,6 +67,7 @@ def packet_100_percent_notification(packet): send_notification(notification_body, intro_subscriptions, intro_onesignal_client) +@require_onesignal_intro def packet_starting_notification(packet): subscriptions = NotificationSubscription.query.filter_by(freshman_username=packet.freshman_username) if subscriptions: @@ -62,6 +80,7 @@ def packet_starting_notification(packet): send_notification(notification_body, subscriptions, intro_onesignal_client) +@require_onesignal_csh def packets_starting_notification(start_date): member_subscriptions = NotificationSubscription.query.filter(NotificationSubscription.member.isnot(None)) if member_subscriptions: diff --git a/packet/routes/api.py b/packet/routes/api.py index 828ac968..ee582ced 100644 --- a/packet/routes/api.py +++ b/packet/routes/api.py @@ -6,9 +6,8 @@ from flask import session, request -from packet import app, db +from packet import app, db, ldap from packet.context_processors import get_rit_name -from packet.ldap import _ldap_is_member_of_group, ldap_get_member from packet.log_utils import log_time from packet.mail import send_report_mail from packet.utils import before_request, packet_auth, notify_slack, sync_freshman as sync_freshman_list, \ @@ -42,7 +41,7 @@ def sync_freshman(): # Only allow evals to create new frosh username = str(session['userinfo'].get('preferred_username', '')) - if not _ldap_is_member_of_group(ldap_get_member(username), 'eboard-evaluations'): + if not ldap.is_evals(ldap.get_member(username)): return 'Forbidden: not Evaluations Director', 403 freshmen_in_post = {freshman.rit_username: freshman for freshman in map(POSTFreshman, request.json)} @@ -71,7 +70,7 @@ def create_packet(): # Only allow evals to create new packets username = str(session['userinfo'].get('preferred_username', '')) - if not _ldap_is_member_of_group(ldap_get_member(username), 'eboard-evaluations'): + if not ldap.is_evals(ldap.get_member(username)): return 'Forbidden: not Evaluations Director', 403 base_date = datetime.strptime(request.json['start_date'], '%m/%d/%Y').date() @@ -89,7 +88,7 @@ def create_packet(): def sync_ldap(): # Only allow evals to sync ldap username = str(session['userinfo'].get('preferred_username', '')) - if not _ldap_is_member_of_group(ldap_get_member(username), 'eboard-evaluations'): + if not ldap.is_evals(ldap.get_member(username)): return 'Forbidden: not Evaluations Director', 403 sync_with_ldap() return dumps('Done'), 201 diff --git a/packet/utils.py b/packet/utils.py index 0f979f8c..4caa6734 100644 --- a/packet/utils.py +++ b/packet/utils.py @@ -7,12 +7,9 @@ import requests from flask import session, redirect -from packet import auth, app, db +from packet import auth, app, db, ldap from packet.mail import send_start_packet_mail from packet.models import Freshman, FreshSignature, Packet, UpperSignature, MiscSignature -from packet.ldap import ldap_get_member, ldap_is_intromember, ldap_is_evals, ldap_is_on_coop, \ - ldap_get_active_members, ldap_get_active_rtps, ldap_get_3das, ldap_get_wiki_maintainers, ldap_get_webmasters, \ - ldap_get_constitutional_maintainers, ldap_get_drink_admins, ldap_get_eboard_role from packet.notifications import packets_starting_notification, packet_starting_notification INTRO_REALM = 'https://sso.csh.rit.edu/auth/realms/intro' @@ -35,11 +32,11 @@ def wrapped_function(*args, **kwargs): 'admin': False # It's always false if frosh } else: - member = ldap_get_member(uid) + member = ldap.get_member(uid) info = { 'realm': 'csh', 'uid': uid, - 'admin': ldap_is_evals(member) + 'admin': ldap.is_evals(member) } kwargs['info'] = info @@ -70,7 +67,7 @@ def packet_auth(func): def wrapped_function(*args, **kwargs): if app.config['REALM'] == 'csh': username = str(session['userinfo'].get('preferred_username', '')) - if ldap_is_intromember(ldap_get_member(username)): + if ldap.is_intromember(ldap.get_member(username)): app.logger.warn('Stopped intro member {} from accessing upperclassmen packet'.format(username)) return redirect(app.config['PROTOCOL'] + app.config['PACKET_INTRO'], code=301) @@ -89,8 +86,8 @@ def admin_auth(func): def wrapped_function(*args, **kwargs): if app.config['REALM'] == 'csh': username = str(session['userinfo'].get('preferred_username', '')) - member = ldap_get_member(username) - if not ldap_is_evals(member): + member = ldap.get_member(username) + if not ldap.is_evals(member): app.logger.warn('Stopped member {} from accessing admin UI'.format(username)) return redirect(app.config['PROTOCOL'] + app.config['PACKET_UPPER'], code=301) else: @@ -160,14 +157,15 @@ def create_new_packets(base_date: date, freshmen_list: dict): print('Fetching data from LDAP...') all_upper = list(filter( - lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members())) + lambda member: not ldap.is_intromember(member) and not ldap.is_on_coop(member), ldap.get_active_members())) - rtp = ldap_get_active_rtps() - three_da = ldap_get_3das() - webmaster = ldap_get_webmasters() - c_m = ldap_get_constitutional_maintainers() - w_m = ldap_get_wiki_maintainers() - drink = ldap_get_drink_admins() + + rtp = ldap.get_active_rtps() + three_da = ldap.get_3das() + webmaster = ldap.get_webmasters() + c_m = ldap.get_constitutional_maintainers() + w_m = ldap.get_wiki_maintainers() + drink = ldap.get_drink_admins() # Packet starting notifications packets_starting_notification(start) @@ -182,7 +180,7 @@ def create_new_packets(base_date: date, freshmen_list: dict): for member in all_upper: sig = UpperSignature(packet=packet, member=member.uid) - sig.eboard = ldap_get_eboard_role(member) + sig.eboard = ldap.get_eboard_role(member) sig.active_rtp = member.uid in rtp sig.three_da = member.uid in three_da sig.webmaster = member.uid in webmaster @@ -201,20 +199,20 @@ def create_new_packets(base_date: date, freshmen_list: dict): def sync_with_ldap(): print('Fetching data from LDAP...') all_upper = {member.uid: member for member in filter( - lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members())} + lambda member: not ldap.is_intromember(member) and not ldap.is_on_coop(member), ldap.get_active_members())} - rtp = ldap_get_active_rtps() - three_da = ldap_get_3das() - webmaster = ldap_get_webmasters() - c_m = ldap_get_constitutional_maintainers() - w_m = ldap_get_wiki_maintainers() - drink = ldap_get_drink_admins() + rtp = ldap.get_active_rtps() + three_da = ldap.get_3das() + webmaster = ldap.get_webmasters() + c_m = ldap.get_constitutional_maintainers() + w_m = ldap.get_wiki_maintainers() + drink = ldap.get_drink_admins() print('Applying updates to the DB...') for packet in Packet.query.filter(Packet.end > datetime.now()).all(): # Update the role state of all UpperSignatures for sig in filter(lambda sig: sig.member in all_upper, packet.upper_signatures): - sig.eboard = ldap_get_eboard_role(all_upper[sig.member]) + sig.eboard = ldap.get_eboard_role(all_upper[sig.member]) sig.active_rtp = sig.member in rtp sig.three_da = sig.member in three_da sig.webmaster = sig.member in webmaster @@ -233,7 +231,7 @@ def sync_with_ldap(): for sig in filter(lambda sig: sig.member in all_upper, packet.misc_signatures): MiscSignature.query.filter_by(packet_id=packet.id, member=sig.member).delete() sig = UpperSignature(packet=packet, member=sig.member, signed=True) - sig.eboard = ldap_get_eboard_role(all_upper[sig.member]) + sig.eboard = ldap.get_eboard_role(all_upper[sig.member]) sig.active_rtp = sig.member in rtp sig.three_da = sig.member in three_da sig.webmaster = sig.member in webmaster @@ -247,7 +245,7 @@ def sync_with_ldap(): upper_sigs = set(map(lambda sig: sig.member, packet.upper_signatures)) for member in filter(lambda member: member not in upper_sigs, all_upper): sig = UpperSignature(packet=packet, member=member) - sig.eboard = ldap_get_eboard_role(all_upper[sig.member]) + sig.eboard = ldap.get_eboard_role(all_upper[sig.member]) sig.active_rtp = sig.member in rtp sig.three_da = sig.member in three_da sig.webmaster = sig.member in webmaster