From 552c1e6ab0cd60b90f43c83a69e89b2a6af313ff Mon Sep 17 00:00:00 2001 From: ACBerea Date: Wed, 5 Aug 2026 11:50:10 -0400 Subject: [PATCH 01/15] Added isCeltsOperationsTeam to user.py model and a business rule that ensures that the operation team is also a student staff member prior to being assigned to the operations team. Added flash messages for setting a user to an operations team member and removing them from the opperations team in userManagemetn.py. Added isCeltsOperationTeam to demo_data.py for all nessicary users. --- app/controllers/admin/userManagement.py | 19 ++++++++++++++++++- app/logic/userManagement.py | 11 ++++++++--- app/models/user.py | 5 +++++ database/test_data.py | 15 +++++++++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/app/controllers/admin/userManagement.py b/app/controllers/admin/userManagement.py index ca944b7af..65825068b 100644 --- a/app/controllers/admin/userManagement.py +++ b/app/controllers/admin/userManagement.py @@ -48,13 +48,30 @@ def manageUsers(): else: addCeltsStudentStaff(user) flash(user.firstName + " " + user.lastName + " has been added as a CELTS Student Staff", 'success') + elif method == "addCeltsOperationsTeam": + if not user.isCeltsStudentStaff: + flash(username + " cannot be added as CELTS Operations Team", 'danger') + else: + if user.isCeltsOperationsTeam: + flash(user.firstName + " " + user.lastName + " is already a CELTS Operations Team member", 'danger') + else: + user.isCeltsOperationsTeam = True + user.save() + flash(user.firstName + " " + user.lastName + " has been added as a CELTS Operations Team member", 'success') elif method == "removeCeltsAdmin": removeCeltsAdmin(user) flash(user.firstName + " " + user.lastName + " is no longer a CELTS Admin ", 'success') elif method == "removeCeltsStudentStaff": removeCeltsStudentStaff(user) flash(user.firstName + " " + user.lastName + " is no longer a CELTS Student Staff", 'success') - return ("success") + # Double check if this function works as intended. It should remove the user from CELTS Operations Team if they are a member. + elif method == "removeCeltsOperationsTeam": + if not user.isCeltsOperationsTeam: + flash(user.firstName + " " + user.lastName + " is not a CELTS Operations Team member", 'danger') + else: + user.isCeltsOperationsTeam = False + user.save() + flash(user.firstName + " " + user.lastName + " is no longer a CELTS Operations Team member", 'success') @admin_bp.route('/deleteProgramFile', methods=['POST']) diff --git a/app/logic/userManagement.py b/app/logic/userManagement.py index 8819dfc22..4e756878b 100644 --- a/app/logic/userManagement.py +++ b/app/logic/userManagement.py @@ -16,13 +16,18 @@ def addCeltsAdmin(user): user.save() createActivityLog(f'Made {user.firstName} {user.lastName} a CELTS admin member.') - -def addCeltsStudentStaff(user): +#FIXME: Rename to addCeltsProgramManager (Once the Program Manager is implemented in the model.) +def addCeltsStudentStaff(user): #Change to Program Manager user = User.get_by_id(user) - user.isCeltsStudentStaff = True + user.isCeltsStudentStaff = True # May change to account for Operations Team rules. (Ex and user.isCeltsOperationsTeam == False) user.save() createActivityLog(f'Made {user.firstName} {user.lastName} a CELTS student staff member.') +def addCeltsOperationsTeam(user): + user = User.get_by_id(user) + user.isOperationsTeam = True + user.save() + createActivityLog(f'Made {user.firstName} {user.lastName} a CELTS operations team member.') def removeCeltsAdmin(user): user = User.get_by_id(user) diff --git a/app/models/user.py b/app/models/user.py index c9652f86c..8e93a15b9 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -15,6 +15,7 @@ class User(baseModel): isStaff = BooleanField(default=False) isCeltsAdmin = BooleanField(default=False) isCeltsStudentStaff = BooleanField(default=False) + isCeltsOperationsTeam = BooleanField(default=False) # A user MUST be a CELTS Student Staff member to be a CELTS Operations Team member. dietRestriction = TextField(null=True) minorInterest = BooleanField(null=True) hasGraduated = BooleanField(default=False) @@ -47,6 +48,10 @@ def isCurrentlyEnrolled(self): def isAdmin(self): return (self.isCeltsAdmin or self.isCeltsStudentStaff) + @property + def isOperationsTeam(self): + return self.isCeltsStudentStaff and self.isCeltsOperationsTeam + @property def isBonnerScholar(self): from app.models.bonnerCohort import BonnerCohort diff --git a/database/test_data.py b/database/test_data.py index 847bc2a4d..7b4d5b5f5 100644 --- a/database/test_data.py +++ b/database/test_data.py @@ -46,6 +46,7 @@ "isStaff": True, "isCeltsAdmin": True, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "dietRestriction": "Diary", "major": None, "rawClassLevel": None, @@ -63,6 +64,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "major": "Computer Science", "rawClassLevel": "Senior", "minorInterest": 1, @@ -78,6 +80,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": True, + "isCeltsOperationsTeam": False, "major": "Psychology", "rawClassLevel": "Sophomore", "minorInterest": 0, @@ -94,6 +97,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "major": "Computer and Information Science", "rawClassLevel": "Junior", "minorInterest": None, @@ -109,6 +113,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "major": "Chemistry", "rawClassLevel": "Junior", "minorInterest": None, @@ -125,6 +130,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "major": None, "rawClassLevel": None, "minorInterest": None, @@ -164,6 +170,7 @@ "isStudent": True, "phoneNumber": "(859)463-1159", "isCeltsStudentStaff": True, + "isCeltsOperationsTeam": False, "major": None, "rawClassLevel": None, "minorInterest": None, @@ -179,6 +186,7 @@ "isCeltsAdmin": False, "isFaculty": True, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "isStaff": True, "major": None, "rawClassLevel": None, @@ -194,6 +202,7 @@ "isCeltsAdmin": True, "isFaculty": True, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "isStaff": True, "major": None, "rawClassLevel": None, @@ -211,6 +220,7 @@ "isStaff": True, "isCeltsAdmin": True, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "major": None, "rawClassLevel": None, "minorInterest": None, @@ -225,6 +235,7 @@ "isCeltsAdmin": False, "isFaculty": False, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "isStaff": True, "minorInterest": None, }, @@ -239,6 +250,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "major": "Computer Science", "rawClassLevel": "Senior", "minorInterest": None, @@ -254,6 +266,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "major": "Computer Science", "rawClassLevel": "Junior", "minorInterest": None, @@ -269,6 +282,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "major": "Computer Science", "rawClassLevel": "Senior", "minorInterest": None, @@ -284,6 +298,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": False, + "isCeltsOperationsTeam": False, "major": "Computer Science", "rawClassLevel": "Senior", "minorInterest": None, From 38850db6ec66e374e6ddf948a403193bb92869f8 Mon Sep 17 00:00:00 2001 From: ACBerea Date: Wed, 5 Aug 2026 16:30:20 -0400 Subject: [PATCH 02/15] Finished functionality for removing Operation Team members and gave operation team members access to Shortcuts in create an event on userManagement. Gave Operation Team members access to Program Details page and access to view and edit all programs. Changed user profile CELTS Labor section to a specialized version in userProfile.HTML. Added isCeltsOperationTeam to areas where isProgramMangerFor was being used. --- app/controllers/admin/routes.py | 4 ++-- app/controllers/admin/userManagement.py | 8 ++++---- app/controllers/admin/volunteers.py | 12 ++++++------ app/logic/searchUsers.py | 4 +++- app/logic/userManagement.py | 8 +++++++- app/templates/events/eventNav.html | 2 +- app/templates/main/userProfile.html | 14 ++++++++++++-- app/templates/sidebar.html | 4 ++-- database/test_data.py | 2 +- 9 files changed, 38 insertions(+), 20 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index 8d24ffdf6..582bc2af2 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -194,7 +194,7 @@ def createEvent(templateid, programid): @admin_bp.route('/event//rsvp', methods=['GET']) def rsvpLogDisplay(eventId): event = Event.get_by_id(eventId) - if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerFor(event.program)): + if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerFor(event.program) or g.current_user.isCeltsOperationsTeam): allLogs = EventRsvpLog.select(EventRsvpLog, User).join(User, on=(EventRsvpLog.createdBy == User.username)).where(EventRsvpLog.event_id == eventId).order_by(EventRsvpLog.createdOn.desc()) return render_template("/events/rsvpLog.html", event = event, @@ -270,7 +270,7 @@ def eventDisplay(eventId): print(f"Unknown event: {eventId}") abort(404) - notPermitted = not (g.current_user.isCeltsAdmin or g.current_user.isProgramManagerForEvent(event)) + notPermitted = not (g.current_user.isCeltsAdmin or g.current_user.isProgramManagerForEvent(event) or g.current_user.isCeltsOperationsTeam) if 'edit' in request.url_rule.rule and notPermitted: abort(403) diff --git a/app/controllers/admin/userManagement.py b/app/controllers/admin/userManagement.py index 65825068b..cca906d0a 100644 --- a/app/controllers/admin/userManagement.py +++ b/app/controllers/admin/userManagement.py @@ -82,7 +82,7 @@ def deleteProgramFile(): @admin_bp.route('/admin/updateProgramInfo/', methods=['POST']) def updateProgramInfo(programID): - if g.current_user.isCeltsAdmin or g.current_user.isProgramManagerFor(programID): + if g.current_user.isCeltsAdmin or g.current_user.isProgramManagerFor(programID) or g.current_user.isCeltsOperationsTeam: try: programInfo = request.form # grabs user inputs uploadedFile = request.files.get('modalProgramImage') @@ -98,7 +98,7 @@ def updateProgramInfo(programID): @admin_bp.route('/admin/getProgramInfo/', methods = ['GET']) def getProgramInfo(programID): - if g.current_user.isCeltsAdmin or g.current_user.isProgramManagerFor(programID): + if g.current_user.isCeltsAdmin or g.current_user.isProgramManagerFor(programID) or g.current_user.isCeltsOperationsTeam: try: targetProgram = Program.get_by_id(programID) programInfo = model_to_dict(targetProgram, recurse=False) @@ -128,14 +128,14 @@ def userManagement(): .join(User, JOIN.LEFT_OUTER, on=(ProgramManager.user == User.username)) ) - if not g.current_user.isCeltsAdmin: + if not g.current_user.isCeltsAdmin and not g.current_user.isCeltsOperationsTeam: #Allows CELTS Operations Team to view all programs. currentPrograms = currentPrograms.where(ProgramManager.user == g.current_user.username) currentPrograms = currentPrograms.group_by(Program.id) currentAdmins = list(User.select().where(User.isCeltsAdmin)) currentStudentStaff = list(User.select().where(User.isCeltsStudentStaff)) - if g.current_user.isCeltsAdmin or g.current_user.isProgramManager: + if g.current_user.isCeltsAdmin or g.current_user.isProgramManager or g.current_user.isCeltsOperationsTeam: return render_template('admin/userManagement.html', terms = terms, programs = list(currentPrograms), diff --git a/app/controllers/admin/volunteers.py b/app/controllers/admin/volunteers.py index c16012803..5e53373f3 100644 --- a/app/controllers/admin/volunteers.py +++ b/app/controllers/admin/volunteers.py @@ -56,7 +56,7 @@ def manageVolunteersPage(eventID): # ------------ GET request ------------ elif request.method == "GET": - if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event))): + if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event)) or g.current_user.isOperationsTeam): abort(403) # ------- Grab the different lists of participants ------- @@ -98,7 +98,7 @@ def volunteerDetailsPage(eventID): print(f"No event found for {eventID}", e) abort(404) - if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event))): + if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event)) or g.current_user.isOperationsTeam): abort(403) eventRsvpData = list(EventRsvp.select(EmergencyContact, InsuranceInfo, EventRsvp) @@ -165,7 +165,7 @@ def addVolunteer(eventId): def rsvpFromWaitlist(username, eventId): event = Event.get_by_id(eventId) isProgramManager = g.current_user.isProgramManagerFor(event.program) - if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and isProgramManager): + if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and isProgramManager) or g.current_user.isOperationsTeam: waitlistUsers = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == username, EventRsvp.event==eventId).execute() if (waitlistUsers): createRsvpLog(event.id, f"Moved {waitlistUsers[0].user.fullName} from waitlist to RSVP.") @@ -180,7 +180,7 @@ def isVolunteerBanned(username, eventId): def removeVolunteerFromEvent(): user = request.form.get('username') eventID = request.form.get('eventId') - if g.current_user.isAdmin: + if g.current_user.isAdmin: # Unsure if I should add isOperationsTeam to this check. userInRsvpTable = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == user, EventRsvp.event==eventID).execute() if (userInRsvpTable): rsvpUser = userInRsvpTable[0] @@ -195,7 +195,7 @@ def removeVolunteerFromEvent(): @admin_bp.route('/addBackgroundCheck', methods = ['POST']) def addBackgroundCheck(): - if g.current_user.isCeltsAdmin: + if g.current_user.isCeltsAdmin or g.current_user.isOperationsTeam: eventData = request.form user = eventData['user'] bgStatus = eventData['bgStatus'] @@ -206,7 +206,7 @@ def addBackgroundCheck(): @admin_bp.route('/deleteBackgroundCheck', methods = ['POST']) def deleteBackgroundCheck(): - if g.current_user.isCeltsAdmin: + if g.current_user.isCeltsAdmin or g.current_user.isOperationsTeam: backgroundData = request.form bgToDelete = BackgroundCheck.get_by_id(backgroundData['bgID']) session["lastDeletedBgCheck"] = bgToDelete.id diff --git a/app/logic/searchUsers.py b/app/logic/searchUsers.py index 92ee2c76a..a4bc829a3 100644 --- a/app/logic/searchUsers.py +++ b/app/logic/searchUsers.py @@ -22,8 +22,10 @@ def searchUsers(query, category=None): userWhere = (User.isCeltsAdmin) elif category == "studentstaff": userWhere = (User.isCeltsStudentStaff) + elif category == "operationsTeam": + userWhere = (User.isCeltsOperationsTeam) elif category == "celtsLinkAdmin": - userWhere = (User.isFaculty | User.isStaff | User.isCeltsStudentStaff) + userWhere = (User.isFaculty | User.isStaff | User.isCeltsStudentStaff | User.isCeltsOperationsTeam) elif category == "all": userWhere = (True) else: diff --git a/app/logic/userManagement.py b/app/logic/userManagement.py index 4e756878b..1f92c7eca 100644 --- a/app/logic/userManagement.py +++ b/app/logic/userManagement.py @@ -46,6 +46,12 @@ def removeCeltsStudentStaff(user): createActivityLog(f'Removed {user.firstName} {user.lastName} from a CELTS student staff member'+ (f', and as a manager of {programManagerRoles}.' if programManagerRoles else ".")) +def removeCeltsOperationsTeam(user): # May need more detail. + user = User.get_by_id(user) + user.isOperationsTeam = False + user.save() + createActivityLog(f'Removed {user.firstName} {user.lastName} from CELTS operations team members.') + def changeProgramInfo(programId, attachment, programName= None, @@ -106,7 +112,7 @@ def getAllowedPrograms(currentUser): def getAllowedTemplates(currentUser): """Returns a list of all visible templates depending on who the current user is. If they are not an admin it should always be none.""" - if currentUser.isCeltsAdmin: + if currentUser.isCeltsAdmin or currentUser.isCeltsOperationsTeam: # Gave access to the short cut. return EventTemplate.select().where(EventTemplate.isVisible==True).order_by(EventTemplate.name) else: return [] \ No newline at end of file diff --git a/app/templates/events/eventNav.html b/app/templates/events/eventNav.html index fb480c46a..e695ac243 100644 --- a/app/templates/events/eventNav.html +++ b/app/templates/events/eventNav.html @@ -44,7 +44,7 @@ {% endblock %} {% block navbar %} - {% if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerFor(event.program)) %} + {% if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerFor(event.program)) or g.current_user.isCeltsOperationsTeam %}
{% endif %} - {% if volunteer.isCeltsStudentStaff %} + {% if volunteer.isCeltsStudentStaff and not volunteer.isCeltsOperationsTeam %}
{{volunteer.firstName}} {{volunteer.lastName}} is the current manager of:
    @@ -304,6 +304,16 @@
    {{volunteer.firstName}} {{volunteer.lastName}} is the current manager of: {% endif %} + {% if volunteer.isCeltsOperationsTeam %} +
    +
    {{volunteer.firstName}} {{volunteer.lastName}} currently manages all programs. (Operations Team)
    +
    +
    + {% if g.current_user.isCeltsAdmin %} + Update Program Managers + {% endif %} +
    + {% endif %}
@@ -326,7 +336,7 @@

Description - {% if g.current_user.isCeltsAdmin %} + {% if g.current_user.isCeltsAdmin or g.current_user.isCeltsOperationsTeam %} Status Date diff --git a/app/templates/sidebar.html b/app/templates/sidebar.html index e1dd71e24..bd3bbf031 100644 --- a/app/templates/sidebar.html +++ b/app/templates/sidebar.html @@ -29,7 +29,7 @@ {% endif %} - {% if g.current_user.isCeltsAdmin or g.current_user.isProgramManager %} + {% if g.current_user.isCeltsAdmin or g.current_user.isProgramManager or g.current_user.isCeltsOperationsTeam %}
  • Create Event @@ -90,7 +90,7 @@
  • {% endif %} - {% if g.current_user.isProgramManager %} + {% if g.current_user.isProgramManager or g.current_user.isCeltsOperationsTeam %} diff --git a/database/test_data.py b/database/test_data.py index 7b4d5b5f5..737e311dd 100644 --- a/database/test_data.py +++ b/database/test_data.py @@ -80,7 +80,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": True, - "isCeltsOperationsTeam": False, + "isCeltsOperationsTeam": True, "major": "Psychology", "rawClassLevel": "Sophomore", "minorInterest": 0, From eb9be0aa61d8abb50872245cb1f3ee144315ae7d Mon Sep 17 00:00:00 2001 From: ACBerea Date: Thu, 6 Aug 2026 11:20:44 -0400 Subject: [PATCH 03/15] Enabled event creation for Operation Team members in routes.py, enabled access for Operation Team members to view and edit all programs, and edited userProfile.html to allow Operation Team members to view and edit background check information. --- app/controllers/admin/routes.py | 2 +- app/logic/userManagement.py | 4 ++-- app/templates/main/userProfile.html | 12 ++++++------ 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index 582bc2af2..2c6eb6b8d 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -82,7 +82,7 @@ def templateSelect(): @admin_bp.route('/eventTemplates///create', methods=['GET','POST']) def createEvent(templateid, programid): - if not (g.current_user.isCeltsAdmin or g.current_user.isProgramManagerFor(programid)): + if not (g.current_user.isCeltsAdmin or g.current_user.isProgramManagerFor(programid) or g.current_user.isCeltsOperationsTeam): abort(403) # Validate given URL diff --git a/app/logic/userManagement.py b/app/logic/userManagement.py index 1f92c7eca..fabf58721 100644 --- a/app/logic/userManagement.py +++ b/app/logic/userManagement.py @@ -103,7 +103,7 @@ def changeProgramInfo(programId, def getAllowedPrograms(currentUser): """Returns a list of all visible programs depending on who the current user is.""" - if currentUser.isCeltsAdmin: + if currentUser.isCeltsAdmin or currentUser.isCeltsOperationsTeam: return Program.select().order_by(Program.programName) else: return Program.select().join(ProgramManager).where(ProgramManager.user==currentUser).order_by(Program.programName) @@ -112,7 +112,7 @@ def getAllowedPrograms(currentUser): def getAllowedTemplates(currentUser): """Returns a list of all visible templates depending on who the current user is. If they are not an admin it should always be none.""" - if currentUser.isCeltsAdmin or currentUser.isCeltsOperationsTeam: # Gave access to the short cut. + if currentUser.isCeltsAdmin or currentUser.isCeltsOperationsTeam: return EventTemplate.select().where(EventTemplate.isVisible==True).order_by(EventTemplate.name) else: return [] \ No newline at end of file diff --git a/app/templates/main/userProfile.html b/app/templates/main/userProfile.html index 6b10ef83e..cebffb76c 100644 --- a/app/templates/main/userProfile.html +++ b/app/templates/main/userProfile.html @@ -306,7 +306,7 @@
    {{volunteer.firstName}} {{volunteer.lastName}} is the current manager of: -
    {{volunteer.firstName}} {{volunteer.lastName}} currently manages all programs. (Operations Team)
    +
    {{volunteer.firstName}} {{volunteer.lastName}} is currently an Operations Team member who manages all programs.
    {% if g.current_user.isCeltsAdmin %} @@ -346,7 +346,7 @@

    {% set ns = namespace(backgroundChecksExist=false) %} {% for bgType in backgroundTypes %} - {% if not g.current_user.isCeltsAdmin and not allBackgroundHistory[bgType.id] %} + {% if not g.current_user.isCeltsAdmin and not g.current_user.isCeltsOperationsTeam and not allBackgroundHistory[bgType.id] %} {% continue %} {% endif %} {% set ns.backgroundChecksExist = true %} @@ -360,7 +360,7 @@

    {{bgType.description}}
    {{ bgStatus.backgroundCheckStatus }}: {{ bgStatus.dateCompleted.strftime("%m/%d/%Y") }} - {% if g.current_user.isCeltsAdmin %} + {% if g.current_user.isCeltsAdmin or g.current_user.isCeltsOperationsTeam %}

    {% endfor %} - {% if g.current_user.isCeltsAdmin %} + {% if g.current_user.isCeltsAdmin or g.current_user.isCeltsOperationsTeam %} + + {{studentStaff.firstName}} {{studentStaff.lastName}} From 620a82d70b639ef09ca869159ac4a20e23e8210f Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 08:31:05 -0400 Subject: [PATCH 05/15] Removed unneeded comments. --- app/controllers/admin/volunteers.py | 2 +- app/logic/userManagement.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/volunteers.py b/app/controllers/admin/volunteers.py index 52ac2ce3d..61576a1cd 100644 --- a/app/controllers/admin/volunteers.py +++ b/app/controllers/admin/volunteers.py @@ -180,7 +180,7 @@ def isVolunteerBanned(username, eventId): def removeVolunteerFromEvent(): user = request.form.get('username') eventID = request.form.get('eventId') - if g.current_user.isAdmin: # Unsure if I should add isOnOperationsTeam to this check. + if g.current_user.isAdmin: userInRsvpTable = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == user, EventRsvp.event==eventID).execute() if (userInRsvpTable): rsvpUser = userInRsvpTable[0] diff --git a/app/logic/userManagement.py b/app/logic/userManagement.py index 94dc0f298..3a448a571 100644 --- a/app/logic/userManagement.py +++ b/app/logic/userManagement.py @@ -19,7 +19,7 @@ def addCeltsAdmin(user): def addCeltsStudentStaff(user): user = User.get_by_id(user) - user.isCeltsStudentStaff = True # May change to account for Operations Team rules. (Ex and user.isCeltsOperationsTeam == False) + user.isCeltsStudentStaff = True user.save() createActivityLog(f'Made {user.firstName} {user.lastName} a CELTS student staff member.') @@ -48,7 +48,7 @@ def removeCeltsStudentStaff(user): createActivityLog(f'Removed {user.firstName} {user.lastName} from a CELTS student staff member'+ (f', and as a manager of {programManagerRoles}.' if programManagerRoles else ".")) -def removeCeltsOperationsTeam(user): # May need more detail. +def removeCeltsOperationsTeam(user): user = User.get_by_id(user) user.isCeltsOperationsTeam = False user.save() From ed6cb7abc614f07785de8ab123f58de9bdc79f6c Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 09:45:43 -0400 Subject: [PATCH 06/15] Improved message for Operations Team Members in CELTS Labor section on profile page. --- app/templates/main/userProfile.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/templates/main/userProfile.html b/app/templates/main/userProfile.html index c4256602b..d722da904 100644 --- a/app/templates/main/userProfile.html +++ b/app/templates/main/userProfile.html @@ -312,7 +312,8 @@
    {{volunteer.firstName}} {{volunteer.lastName}} is the current manager of: -
    {{volunteer.firstName}} {{volunteer.lastName}} is currently an Operations Team member who manages all programs.
    +
    Operations Team Member:
    +

    {{volunteer.firstName}} {{volunteer.lastName}} is currently an Operations Team member who manages all programs.

    {% if g.current_user.isCeltsAdmin %} From 209006eafb04180d5e64e48761e1ee43cf2570bf Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 10:06:03 -0400 Subject: [PATCH 07/15] Added test suite function for Operation Team in test_userManagement.py and reverted some test data. --- database/test_data.py | 2 +- tests/code/test_userManagement.py | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/database/test_data.py b/database/test_data.py index 800ffb3f2..bf368e113 100644 --- a/database/test_data.py +++ b/database/test_data.py @@ -80,7 +80,7 @@ "isFaculty": False, "isCeltsAdmin": False, "isCeltsStudentStaff": True, - "isCeltsOperationsTeam": True, + "isCeltsOperationsTeam": False, "major": "Psychology", "rawClassLevel": "Sophomore", "minorInterest": 0, diff --git a/tests/code/test_userManagement.py b/tests/code/test_userManagement.py index 723ba0c73..6983fbe40 100644 --- a/tests/code/test_userManagement.py +++ b/tests/code/test_userManagement.py @@ -81,6 +81,32 @@ def test_modifyCeltsStudentStaff(): transaction.rollback() +@pytest.mark.integration +def test_modifyCeltsOperationsTeam(): + with mainDB.atomic() as transaction: + + username = "neillz" + userInTest = User.get(User.username == username) + + assert userInTest.isCeltsStudentStaff + assert userInTest.isCeltsOperationsTeam == False + + with app.app_context(): + g.current_user = "ramsayb2" + + addCeltsOperationsTeam(userInTest) + + userInTest = User.get(User.username == username) + assert userInTest.isCeltsOperationsTeam == True + assert userInTest.isOperationsTeam == True + + removeCeltsOperationsTeam(userInTest) + + userInTest = User.get(User.username == username) + assert userInTest.isCeltsOperationsTeam == False + assert userInTest.isOperationsTeam == False + + transaction.rollback() @pytest.mark.integration def test_changeProgramInfo(): From adb83e3762680c189d99d919f4bac50d36e1cb5c Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 10:13:06 -0400 Subject: [PATCH 08/15] Fixed error in test suite. --- tests/code/test_userManagement.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/code/test_userManagement.py b/tests/code/test_userManagement.py index 6983fbe40..eac7211ce 100644 --- a/tests/code/test_userManagement.py +++ b/tests/code/test_userManagement.py @@ -98,13 +98,13 @@ def test_modifyCeltsOperationsTeam(): userInTest = User.get(User.username == username) assert userInTest.isCeltsOperationsTeam == True - assert userInTest.isOperationsTeam == True + assert userInTest.isOnOperationsTeam == True removeCeltsOperationsTeam(userInTest) userInTest = User.get(User.username == username) assert userInTest.isCeltsOperationsTeam == False - assert userInTest.isOperationsTeam == False + assert userInTest.isOnOperationsTeam == False transaction.rollback() From d789454955aeb5447faae9d387230908d937739d Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 11:45:27 -0400 Subject: [PATCH 09/15] Removed all instances of isInOperationsTeam, including the property, and replace it with the existing isCeltsOperationsTeam. Removed unnessicary checks from userManagement.py for isCeltsOperationsTeam. --- app/controllers/admin/userManagement.py | 13 ++----------- app/controllers/admin/volunteers.py | 10 +++++----- app/models/user.py | 4 ---- tests/code/test_userManagement.py | 2 -- 4 files changed, 7 insertions(+), 22 deletions(-) diff --git a/app/controllers/admin/userManagement.py b/app/controllers/admin/userManagement.py index e49398de5..e68321a1a 100644 --- a/app/controllers/admin/userManagement.py +++ b/app/controllers/admin/userManagement.py @@ -60,14 +60,8 @@ def manageUsers(): addCeltsStudentStaff(user) flash(user.firstName + " " + user.lastName + " has been added as a CELTS Student Staff", 'success') elif method == "addCeltsOperationsTeam": - if not user.isCeltsStudentStaff: - flash(username + " cannot be added as CELTS Operations Team", "danger") - else: - if user.isCeltsOperationsTeam: - flash(user.firstName + " " + user.lastName +" is already a CELTS Operations Team member", "danger") - else: - addCeltsOperationsTeam(user) - flash(user.firstName + " " + user.lastName + " has been added as a CELTS Operations Team member", "success") + addCeltsOperationsTeam(user) + flash(user.firstName + " " + user.lastName + " has been added as a CELTS Operations Team member", "success") elif method == "removeCeltsAdmin": removeCeltsAdmin(user) flash(user.firstName + " " + user.lastName + " is no longer a CELTS Admin ", 'success') @@ -75,9 +69,6 @@ def manageUsers(): removeCeltsStudentStaff(user) flash(user.firstName + " " + user.lastName + " is no longer a CELTS Student Staff", 'success') elif method == "removeCeltsOperationsTeam": - if not user.isCeltsOperationsTeam: - flash(user.firstName + " " + user.lastName +" is not a CELTS Operations Team member", "danger") - else: removeCeltsOperationsTeam(user) flash(user.firstName + " " + user.lastName + " is no longer a CELTS Operations Team member", "success") return ("success", 200) diff --git a/app/controllers/admin/volunteers.py b/app/controllers/admin/volunteers.py index 1b4f53706..f594cec55 100644 --- a/app/controllers/admin/volunteers.py +++ b/app/controllers/admin/volunteers.py @@ -56,7 +56,7 @@ def manageVolunteersPage(eventID): # ------------ GET request ------------ elif request.method == "GET": - if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event)) or g.current_user.isOnOperationsTeam): + if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event)) or g.current_user.isCeltsOperationsTeam): abort(403) # ------- Grab the different lists of participants ------- @@ -98,7 +98,7 @@ def volunteerDetailsPage(eventID): print(f"No event found for {eventID}", e) abort(404) - if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event)) or g.current_user.isOnOperationsTeam): + if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event)) or g.current_user.isCeltsOperationsTeam): abort(403) eventRsvpData = list(EventRsvp.select(EmergencyContact, InsuranceInfo, EventRsvp) @@ -165,7 +165,7 @@ def addVolunteer(eventId): def rsvpFromWaitlist(username, eventId): event = Event.get_by_id(eventId) isProgramManager = g.current_user.isProgramManagerFor(event.program) - if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and isProgramManager) or g.current_user.isOnOperationsTeam: + if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and isProgramManager) or g.current_user.isCeltsOperationsTeam: waitlistUsers = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == username, EventRsvp.event==eventId).execute() if (waitlistUsers): createRsvpLog(event.id, f"Moved {waitlistUsers[0].user.fullName} from waitlist to RSVP.") @@ -195,7 +195,7 @@ def removeVolunteerFromEvent(): @admin_bp.route('/addBackgroundCheck', methods = ['POST']) def addBackgroundCheck(): - if g.current_user.isCeltsAdmin or g.current_user.isOnOperationsTeam: + if g.current_user.isCeltsAdmin or g.current_user.isCeltsOperationsTeam: eventData = request.form user = eventData['user'] bgStatus = eventData['bgStatus'] @@ -206,7 +206,7 @@ def addBackgroundCheck(): @admin_bp.route('/deleteBackgroundCheck', methods = ['POST']) def deleteBackgroundCheck(): - if g.current_user.isCeltsAdmin or g.current_user.isOnOperationsTeam: + if g.current_user.isCeltsAdmin or g.current_user.isCeltsOperationsTeam: backgroundData = request.form bgToDelete = BackgroundCheck.get_by_id(backgroundData['bgID']) session["lastDeletedBgCheck"] = bgToDelete.id diff --git a/app/models/user.py b/app/models/user.py index ea6d40cde..a859e776e 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -51,10 +51,6 @@ def isCurrentlyEnrolled(self): def isAdmin(self): return (self.isCeltsAdmin or self.isCeltsStudentStaff) - @property - def isOnOperationsTeam(self): - return self.isCeltsStudentStaff and self.isCeltsOperationsTeam - @property def isBonnerScholar(self): from app.models.bonnerCohort import BonnerCohort diff --git a/tests/code/test_userManagement.py b/tests/code/test_userManagement.py index eac7211ce..d6f44756d 100644 --- a/tests/code/test_userManagement.py +++ b/tests/code/test_userManagement.py @@ -98,13 +98,11 @@ def test_modifyCeltsOperationsTeam(): userInTest = User.get(User.username == username) assert userInTest.isCeltsOperationsTeam == True - assert userInTest.isOnOperationsTeam == True removeCeltsOperationsTeam(userInTest) userInTest = User.get(User.username == username) assert userInTest.isCeltsOperationsTeam == False - assert userInTest.isOnOperationsTeam == False transaction.rollback() From 80db683e614562f87ad8e4da3f36404eec7b22d2 Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 13:41:07 -0400 Subject: [PATCH 10/15] Added a new function to main routes that handles situations where authorization is enabled for program managers, operations team members, and admins. All related code was changed to accomodate this change. --- app/controllers/admin/routes.py | 2 +- app/controllers/admin/userManagement.py | 4 ++-- app/controllers/admin/volunteers.py | 6 +++--- app/models/user.py | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index 031f5b4a5..cd507a3fb 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -90,7 +90,7 @@ def templateSelect(): @admin_bp.route('/eventTemplates///create', methods=['GET','POST']) def createEvent(templateid, programid): - if not (g.current_user.isCeltsAdmin or g.current_user.isProgramManagerFor(programid) or g.current_user.isCeltsOperationsTeam): + if not g.current_user.canManagePrograms(programid): abort(403) # Validate given URL diff --git a/app/controllers/admin/userManagement.py b/app/controllers/admin/userManagement.py index e68321a1a..d9836ede5 100644 --- a/app/controllers/admin/userManagement.py +++ b/app/controllers/admin/userManagement.py @@ -81,7 +81,7 @@ def deleteProgramFile(): @admin_bp.route('/admin/updateProgramInfo/', methods=['POST']) def updateProgramInfo(programID): - if g.current_user.isCeltsAdmin or g.current_user.isProgramManagerFor(programID) or g.current_user.isCeltsOperationsTeam: + if g.current_user.canManagePrograms(programID): try: programInfo = request.form # grabs user inputs uploadedFile = request.files.get('modalProgramImage') @@ -97,7 +97,7 @@ def updateProgramInfo(programID): @admin_bp.route('/admin/getProgramInfo/', methods = ['GET']) def getProgramInfo(programID): - if g.current_user.isCeltsAdmin or g.current_user.isProgramManagerFor(programID) or g.current_user.isCeltsOperationsTeam: + if g.current_user.canManagePrograms(programID): try: targetProgram = Program.get_by_id(programID) programInfo = model_to_dict(targetProgram, recurse=False) diff --git a/app/controllers/admin/volunteers.py b/app/controllers/admin/volunteers.py index f594cec55..6350cd1bc 100644 --- a/app/controllers/admin/volunteers.py +++ b/app/controllers/admin/volunteers.py @@ -56,7 +56,7 @@ def manageVolunteersPage(eventID): # ------------ GET request ------------ elif request.method == "GET": - if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event)) or g.current_user.isCeltsOperationsTeam): + if not (g.current_user.canManagePrograms(event.program)): abort(403) # ------- Grab the different lists of participants ------- @@ -98,7 +98,7 @@ def volunteerDetailsPage(eventID): print(f"No event found for {eventID}", e) abort(404) - if not (g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerForEvent(event)) or g.current_user.isCeltsOperationsTeam): + if not g.current_user.canManagePrograms(event.program): abort(403) eventRsvpData = list(EventRsvp.select(EmergencyContact, InsuranceInfo, EventRsvp) @@ -165,7 +165,7 @@ def addVolunteer(eventId): def rsvpFromWaitlist(username, eventId): event = Event.get_by_id(eventId) isProgramManager = g.current_user.isProgramManagerFor(event.program) - if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and isProgramManager) or g.current_user.isCeltsOperationsTeam: + if g.current_user.canManagePrograms(event.program) or isProgramManager: waitlistUsers = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == username, EventRsvp.event==eventId).execute() if (waitlistUsers): createRsvpLog(event.id, f"Moved {waitlistUsers[0].user.fullName} from waitlist to RSVP.") diff --git a/app/models/user.py b/app/models/user.py index a859e776e..cb8383422 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -104,6 +104,9 @@ def isProgramManagerFor(self, program): def isProgramManagerForEvent(self, event): # Looks to see who the Program Manager for a specific event is return self.isProgramManagerFor(event.program) + + def canManagePrograms(self, program): + return self.isCeltsAdmin or self.isCeltsOperationsTeam or (self.isCeltsStudentStaff and self.isProgramManager(program)) @property def isProgramManager(self): @@ -113,5 +116,3 @@ def isProgramManager(self): self._isProgramManagerCache = ProgramManager.select().where(ProgramManager.user == self).exists() return self._isProgramManagerCache - - From 8d5022660f6ad8a6949a6fadec9d336af9c5b0d5 Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 13:55:00 -0400 Subject: [PATCH 11/15] Fixed position on checkbox and provided a label for the Operations Team toggle in the User Management page on userManagement.html. --- app/templates/admin/userManagement.html | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/templates/admin/userManagement.html b/app/templates/admin/userManagement.html index 2fb9d207d..fe97b48d4 100644 --- a/app/templates/admin/userManagement.html +++ b/app/templates/admin/userManagement.html @@ -97,13 +97,16 @@

    - + + + {% for studentStaff in currentStudentStaff %} - + - {% endfor %} From 1409c690bb615d97a261a09bfe08e3898f769b39 Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 13:59:23 -0400 Subject: [PATCH 12/15] Changed canManagePrograms to canManageProgram. --- app/controllers/admin/routes.py | 2 +- app/controllers/admin/userManagement.py | 4 ++-- app/controllers/admin/volunteers.py | 6 +++--- app/models/user.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index cd507a3fb..9b0ca374b 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -90,7 +90,7 @@ def templateSelect(): @admin_bp.route('/eventTemplates///create', methods=['GET','POST']) def createEvent(templateid, programid): - if not g.current_user.canManagePrograms(programid): + if not g.current_user.canManageProgram(programid): abort(403) # Validate given URL diff --git a/app/controllers/admin/userManagement.py b/app/controllers/admin/userManagement.py index d9836ede5..37fe14916 100644 --- a/app/controllers/admin/userManagement.py +++ b/app/controllers/admin/userManagement.py @@ -81,7 +81,7 @@ def deleteProgramFile(): @admin_bp.route('/admin/updateProgramInfo/', methods=['POST']) def updateProgramInfo(programID): - if g.current_user.canManagePrograms(programID): + if g.current_user.canManageProgram(programID): try: programInfo = request.form # grabs user inputs uploadedFile = request.files.get('modalProgramImage') @@ -97,7 +97,7 @@ def updateProgramInfo(programID): @admin_bp.route('/admin/getProgramInfo/', methods = ['GET']) def getProgramInfo(programID): - if g.current_user.canManagePrograms(programID): + if g.current_user.canManageProgram(programID): try: targetProgram = Program.get_by_id(programID) programInfo = model_to_dict(targetProgram, recurse=False) diff --git a/app/controllers/admin/volunteers.py b/app/controllers/admin/volunteers.py index 6350cd1bc..0b23a9455 100644 --- a/app/controllers/admin/volunteers.py +++ b/app/controllers/admin/volunteers.py @@ -56,7 +56,7 @@ def manageVolunteersPage(eventID): # ------------ GET request ------------ elif request.method == "GET": - if not (g.current_user.canManagePrograms(event.program)): + if not (g.current_user.canManageProgram(event.program)): abort(403) # ------- Grab the different lists of participants ------- @@ -98,7 +98,7 @@ def volunteerDetailsPage(eventID): print(f"No event found for {eventID}", e) abort(404) - if not g.current_user.canManagePrograms(event.program): + if not g.current_user.canManageProgram(event.program): abort(403) eventRsvpData = list(EventRsvp.select(EmergencyContact, InsuranceInfo, EventRsvp) @@ -165,7 +165,7 @@ def addVolunteer(eventId): def rsvpFromWaitlist(username, eventId): event = Event.get_by_id(eventId) isProgramManager = g.current_user.isProgramManagerFor(event.program) - if g.current_user.canManagePrograms(event.program) or isProgramManager: + if g.current_user.canManageProgram(event.program) or isProgramManager: waitlistUsers = EventRsvp.select(EventRsvp, User).join(User).where(EventRsvp.user == username, EventRsvp.event==eventId).execute() if (waitlistUsers): createRsvpLog(event.id, f"Moved {waitlistUsers[0].user.fullName} from waitlist to RSVP.") diff --git a/app/models/user.py b/app/models/user.py index cb8383422..ad4696cc1 100644 --- a/app/models/user.py +++ b/app/models/user.py @@ -105,7 +105,7 @@ def isProgramManagerForEvent(self, event): # Looks to see who the Program Manager for a specific event is return self.isProgramManagerFor(event.program) - def canManagePrograms(self, program): + def canManageProgram(self, program): return self.isCeltsAdmin or self.isCeltsOperationsTeam or (self.isCeltsStudentStaff and self.isProgramManager(program)) @property From cd909d84b247db5901acd0ba2b780f97427525b9 Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 14:12:56 -0400 Subject: [PATCH 13/15] Fixed remaining replacements. --- app/controllers/admin/routes.py | 4 ++-- app/controllers/admin/userManagement.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/routes.py b/app/controllers/admin/routes.py index 9b0ca374b..5fc6ee7be 100644 --- a/app/controllers/admin/routes.py +++ b/app/controllers/admin/routes.py @@ -198,7 +198,7 @@ def createEvent(templateid, programid): @admin_bp.route('/event//rsvp', methods=['GET']) def rsvpLogDisplay(eventId): event = Event.get_by_id(eventId) - if g.current_user.isCeltsAdmin or (g.current_user.isCeltsStudentStaff and g.current_user.isProgramManagerFor(event.program) or g.current_user.isCeltsOperationsTeam): + if g.current_user.canManageProgram(event.program): allLogs = EventRsvpLog.select(EventRsvpLog, User).join(User, on=(EventRsvpLog.createdBy == User.username)).where(EventRsvpLog.event_id == eventId).order_by(EventRsvpLog.createdOn.desc()) return render_template("/events/rsvpLog.html", event = event, @@ -274,7 +274,7 @@ def eventDisplay(eventId): print(f"Unknown event: {eventId}") abort(404) - notPermitted = not (g.current_user.isCeltsAdmin or g.current_user.isProgramManagerForEvent(event) or g.current_user.isCeltsOperationsTeam) + notPermitted = not g.current_user.canManageProgram(event.program) if 'edit' in request.url_rule.rule and notPermitted: abort(403) diff --git a/app/controllers/admin/userManagement.py b/app/controllers/admin/userManagement.py index 37fe14916..a1c3e3000 100644 --- a/app/controllers/admin/userManagement.py +++ b/app/controllers/admin/userManagement.py @@ -133,7 +133,7 @@ def userManagement(): currentPrograms = list(currentPrograms.group_by(Program.id)) currentAdmins = list(User.select().where(User.isCeltsAdmin)) currentStudentStaff = list(User.select().where(User.isCeltsStudentStaff)) - if g.current_user.isCeltsAdmin or g.current_user.isProgramManager or g.current_user.isCeltsOperationsTeam: + if g.current_user.canManagePrograms(currentPrograms): return render_template('admin/userManagement.html', terms = terms, programs = currentPrograms, From f840316171704acbc92822e9e5c92ad0b64a4c70 Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 14:18:31 -0400 Subject: [PATCH 14/15] Fixed left over canManagePrograms to canManageProgram. --- app/controllers/admin/userManagement.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/userManagement.py b/app/controllers/admin/userManagement.py index a1c3e3000..d39e095ea 100644 --- a/app/controllers/admin/userManagement.py +++ b/app/controllers/admin/userManagement.py @@ -133,7 +133,7 @@ def userManagement(): currentPrograms = list(currentPrograms.group_by(Program.id)) currentAdmins = list(User.select().where(User.isCeltsAdmin)) currentStudentStaff = list(User.select().where(User.isCeltsStudentStaff)) - if g.current_user.canManagePrograms(currentPrograms): + if g.current_user.canManageProgram(currentPrograms): return render_template('admin/userManagement.html', terms = terms, programs = currentPrograms, From b7d02c78740c24dabf3a8c01bbfdf645ccae5b81 Mon Sep 17 00:00:00 2001 From: ACBerea Date: Fri, 7 Aug 2026 14:31:46 -0400 Subject: [PATCH 15/15] Reverted use of canManageProgram. --- app/controllers/admin/userManagement.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/userManagement.py b/app/controllers/admin/userManagement.py index d39e095ea..37fe14916 100644 --- a/app/controllers/admin/userManagement.py +++ b/app/controllers/admin/userManagement.py @@ -133,7 +133,7 @@ def userManagement(): currentPrograms = list(currentPrograms.group_by(Program.id)) currentAdmins = list(User.select().where(User.isCeltsAdmin)) currentStudentStaff = list(User.select().where(User.isCeltsStudentStaff)) - if g.current_user.canManageProgram(currentPrograms): + if g.current_user.isCeltsAdmin or g.current_user.isProgramManager or g.current_user.isCeltsOperationsTeam: return render_template('admin/userManagement.html', terms = terms, programs = currentPrograms,
    Current Student StaffCurrent Student StaffOperations Team
    + {{studentStaff.firstName}} {{studentStaff.lastName}} {{studentStaff.firstName}} {{studentStaff.lastName}}