-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/main' into mclean/feature/securi…
…ty-improvement
- Loading branch information
Showing
22 changed files
with
692 additions
and
260 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
* @BenMMcLean @naychithanshwe | ||
* @BenMMcLean @ethantr |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from .api import VolunteerShiftV2 | ||
from .response_models import shift |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
from flask_restful import reqparse, Resource, marshal_with, inputs, marshal | ||
from .response_models import shift | ||
from domain import UserType | ||
from repository.shift_repository import ShiftRepository | ||
from services.jwk import requires_auth, is_user_or_has_role | ||
from controllers.v2.v2_blueprint import v2_api | ||
import logging | ||
|
||
|
||
parser = reqparse.RequestParser() | ||
parser.add_argument('title', type=str) | ||
parser.add_argument('start', type=inputs.datetime_from_iso8601, required=True, help="Start time cannot be blank!") | ||
parser.add_argument('end', type=inputs.datetime_from_iso8601, required=True, help="End time cannot be blank!") | ||
parser.add_argument('roles', type=list, location='json', required=True, help="Roles cannot be blank!") | ||
parser_modify_status = reqparse.RequestParser() | ||
parser_modify_status.add_argument('status', type=str, location='json', required=True, help="Status cannot be blank!") | ||
|
||
|
||
class VolunteerShiftV2(Resource): | ||
shift_repository: ShiftRepository | ||
|
||
def __init__(self, shift_repository: ShiftRepository = ShiftRepository()): | ||
self.shift_repository = shift_repository | ||
|
||
@requires_auth | ||
@is_user_or_has_role(None, UserType.ROOT_ADMIN) | ||
def get(self, user_id): | ||
try: | ||
shifts = self.shift_repository.get_shift(user_id) | ||
if shifts: | ||
return marshal(shifts, shift), 200 | ||
else: | ||
return {"message": "No shift record found."}, 400 | ||
except Exception as e: | ||
logging.error(f"Error retrieving shifts for user {user_id}: {e}") | ||
return {"message": "Internal server error"}, 500 | ||
|
||
|
||
def put(self, user_id, shift_id): | ||
args = parser_modify_status.parse_args() | ||
status = args["status"] | ||
try: | ||
success = self.shift_repository.update_shift_status(user_id, shift_id, status) | ||
if success: | ||
return {"message": "Status updated successfully"}, 200 | ||
else: | ||
return {"message": "No user or shift record is found, status not updated."}, 400 | ||
except Exception as e: | ||
logging.error(f"Error updating shifts for user {user_id}: {e}") | ||
return {"message": "Internal server error"}, 500 | ||
|
||
v2_api.add_resource(VolunteerShiftV2,'/v2/volunteers/<user_id>/shift','/v2/volunteers/<user_id>/shift/<shift_id>') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from flask_restful import fields | ||
|
||
shift = { | ||
'shiftId': fields.Integer, | ||
'status': fields.String, | ||
'title': fields.String, | ||
'start': fields.DateTime(dt_format='iso8601'), | ||
'end': fields.DateTime(dt_format='iso8601') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
from datetime import datetime | ||
|
||
from sqlalchemy import Column, String, DateTime, ForeignKey, Integer, Enum | ||
from sqlalchemy.orm import relationship | ||
|
||
from domain import ShiftStatus | ||
from domain.base import Base | ||
|
||
|
||
|
||
class ShiftRequest(Base): | ||
__tablename__ = 'shift_request' | ||
|
||
id = Column(Integer, primary_key=True, autoincrement=True) | ||
user_id = Column(Integer, ForeignKey('user.id'), name='user_id', nullable=False) | ||
title = Column(String(29), name='title', nullable=False) | ||
startTime = Column(DateTime, name='from', nullable=False) | ||
endTime = Column(DateTime, name='to', nullable=False) | ||
status = Column(Enum(ShiftStatus), name='status', default=ShiftStatus.WAITING, nullable=False) | ||
update_date_time = Column(DateTime, name='last_update_datetime', default=datetime.now(), nullable=False) | ||
insert_date_time = Column(DateTime, name='created_datetime', default=datetime.now(), nullable=False) | ||
|
||
user = relationship("User") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from datetime import datetime | ||
|
||
from sqlalchemy import Column, Integer, String, DateTime, ForeignKey, Enum | ||
from sqlalchemy.orm import relationship | ||
|
||
from domain import ShiftVolunteerStatus | ||
from domain.base import Base | ||
|
||
|
||
class ShiftRequestVolunteer(Base): | ||
__tablename__ = 'shift_request_volunteer' | ||
|
||
id = Column(Integer, primary_key=True, autoincrement=True) | ||
user_id = Column(Integer, ForeignKey('user.id'), name='user_id', nullable=False) | ||
request_id = Column(Integer, ForeignKey('shift_request.id'), name='request_id', nullable=False) | ||
status = Column(Enum(ShiftVolunteerStatus), name='status', nullable=False, default=ShiftVolunteerStatus.PENDING) | ||
update_date_time = Column(DateTime, name='last_update_datetime', default=datetime.now(), nullable=False) | ||
insert_date_time = Column(DateTime, name='created_datetime', default=datetime.now(), nullable=False) | ||
|
||
shift_request = relationship("ShiftRequest") | ||
user = relationship("User") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
from dataclasses import dataclass | ||
from datetime import datetime | ||
|
||
from domain.type.shift_volunteer_status import ShiftVolunteerStatus | ||
|
||
|
||
@dataclass | ||
class ShiftRecord: | ||
shiftId: int | ||
status: ShiftVolunteerStatus | ||
title: str | ||
start: datetime | ||
end: datetime |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
from enum import Enum | ||
|
||
|
||
class ShiftStatus(Enum): | ||
WAITING = "waiting" | ||
UNSUBMITTED = "un-submitted" | ||
INPROGRESS = "in-progress" | ||
COMPLETED = "completed" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from enum import Enum | ||
|
||
|
||
class ShiftVolunteerStatus(Enum): | ||
PENDING = "pending" | ||
CONFIRMED = "confirmed" | ||
REJECTED = "rejected" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
import logging | ||
from typing import List | ||
|
||
from dataclasses import asdict | ||
from flask import jsonify | ||
|
||
from datetime import datetime, timezone | ||
|
||
from exception import EventNotFoundError, InvalidArgumentError | ||
from domain import session_scope, ShiftRequestVolunteer, ShiftRequest, ShiftRecord | ||
|
||
|
||
class ShiftRepository: | ||
|
||
def __init__(self): | ||
pass | ||
|
||
def get_shift(self, userId) -> List[ShiftRecord]: | ||
""" | ||
Retrieves all shift events for a given user that have not ended yet. | ||
:param userId: ID of the user whose shifts are being queried. | ||
:return: A list of shift records or an empty list if none found. | ||
""" | ||
now = datetime.now() | ||
with session_scope() as session: | ||
try: | ||
# only show the shift that is end in the future | ||
shifts = session.query(ShiftRequestVolunteer).join(ShiftRequest).filter( | ||
ShiftRequestVolunteer.user_id == userId, | ||
ShiftRequest.endTime > now).all() | ||
# check if there's some results | ||
if not shifts: | ||
logging.info(f"No active shifts found for user {userId}") | ||
return [] | ||
shift_records = [] | ||
# write shift information into list | ||
for shift in shifts: | ||
shift_record = ShiftRecord( | ||
shiftId=shift.request_id, | ||
status=shift.status.value, | ||
title=shift.shift_request.title, | ||
start=shift.shift_request.startTime, | ||
end=shift.shift_request.endTime) | ||
shift_records.append(shift_record) | ||
return shift_records | ||
except Exception as e: | ||
logging.error(f"Error retrieving shifts for user {userId}: {e}") | ||
return [] | ||
|
||
def update_shift_status(self, user_id, shift_id, new_status): | ||
""" | ||
Updates the status of a volunteer's shift request in the database. | ||
Parameters: | ||
---------- | ||
user_id : int | ||
The ID of the user whose shift request status is to be updated. | ||
shift_id : int | ||
The ID of the shift request to be updated. | ||
new_status : str | ||
The new status to set for the shift request. | ||
Returns: | ||
------- | ||
bool | ||
Returns `True` if the status was successfully updated, or `False` if the update | ||
failed due to the shift request not being found or an error occurring during the update. | ||
""" | ||
with session_scope() as session: | ||
try: | ||
# Fetch the shift based on user_id | ||
shift_request_volunteer = session.query(ShiftRequestVolunteer).filter_by( | ||
user_id=user_id, request_id=shift_id).first() | ||
|
||
# If record exists, update the status | ||
if shift_request_volunteer: | ||
shift_request_volunteer.status = new_status | ||
shift_request_volunteer.last_update_datetime = datetime.now() | ||
session.commit() | ||
return True | ||
else: | ||
logging.info(f"No shift request volunteer with user id {user_id} and shift {shift_id} not found") | ||
return False | ||
except Exception as e: | ||
session.rollback() | ||
logging.error(f"Error updating shift request for user {user_id} and shift_id {shift_id}: {e}") | ||
return False |
Oops, something went wrong.