def notification_by_id_get(notification_id) -> Response: """ Retrieve a notification based on its identifier. :param notification_id: Unique identifier for a user's notification. :return: A response object for the GET API request. """ notification = NotificationDao.get_notification_by_id( notification_id=notification_id) if notification is None: response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'notification': None, 'error': 'there is no notification with this identifier' }) response.status_code = 400 return response else: notification_dict = NotificationData(notification).__dict__ notification_dict['time'] = str(notification_dict['time']) response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'notification': notification_dict }) response.status_code = 200 return response
def notifications_get() -> Response: """ Retrieve all the notifications in the database. :return: A response object for the GET API request. """ notifications = NotificationDao.get_notifications() if notifications is None: response = jsonify({ 'self': '/v2/notifications', 'notifications': None, 'error': 'an unexpected error occurred retrieving notifications' }) response.status_code = 500 return response else: notification_dicts = [] for notification in notifications: notification_dict = NotificationData(notification).__dict__ notification_dict['time'] = str(notification_dict['time']) notification_dicts.append(notification_dict) response = jsonify({ 'self': '/v2/notifications', 'notifications': notification_dicts }) response.status_code = 200 return response
def user_notifications_by_username_get(username) -> Response: """ Get the notifications for a user. :param username: Username that uniquely identifies a user. :return: A response object for the GET API request. """ notifications: ResultProxy = NotificationDao.get_notification_by_username( username=username) notification_dicts = [] for notification in notifications: notification_dicts.append({ 'notification_id': notification['notification_id'], 'username': notification['username'], 'time': notification['time'], 'link': notification['link'], 'viewed': notification['viewed'], 'description': notification['description'] }) response = jsonify({ 'self': f'/v2/users/notifications/{username}', 'notifications': notification_dicts }) response.status_code = 200 return response
def notification_by_id_soft_delete(notification_id) -> Response: """ Soft delete an existing notification with a given unique ID. :param notification_id: The unique identifier for a user notification :return: A response object for the DELETE API request. """ existing_notification: Notification = NotificationDao.get_notification_by_id( notification_id=notification_id) if existing_notification is None: response = jsonify({ 'self': f'/v2/notifications/soft/{notification_id}', 'deleted': False, 'error': 'there is no existing notification with this id' }) response.status_code = 400 return response jwt_claims: dict = get_claims(request) jwt_username = jwt_claims.get('sub') if existing_notification.username == jwt_username: current_app.logger.info( f'User {jwt_username} is soft deleting their notification with id {existing_notification.notification_id}.' ) else: current_app.logger.info( f'User {jwt_username} is not authorized to soft delete a notification sent to ' f'{existing_notification.username}.') response = jsonify({ 'self': f'/v2/notifications/soft/{notification_id}', 'deleted': False, 'error': f'User {jwt_username} is not authorized to soft delete a notification sent to ' f'{existing_notification.username}.' }) response.status_code = 400 return response # Update the notification model to reflect the soft delete existing_notification.deleted = True existing_notification.deleted_date = datetime.now() existing_notification.deleted_app = 'saints-xctf-api' existing_notification.modified_date = datetime.now() existing_notification.modified_app = 'saints-xctf-api' is_deleted: bool = NotificationDao.soft_delete_notification( existing_notification) if is_deleted: response = jsonify({ 'self': f'/v2/notifications/soft/{notification_id}', 'deleted': True, }) response.status_code = 204 return response else: response = jsonify({ 'self': f'/v2/notifications/soft/{notification_id}', 'deleted': False, 'error': 'failed to soft delete the notification' }) response.status_code = 500 return response
def notification_by_id_delete(notification_id) -> Response: """ Hard delete an existing notification with a given unique ID. :param notification_id: Unique identifier for a user's notification. :return: A response object for the DELETE API request. """ existing_notification: Notification = NotificationDao.get_notification_by_id( notification_id=notification_id) if existing_notification is None: response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'deleted': False, 'error': 'There is no existing notification with this id.' }) response.status_code = 400 return response jwt_claims: dict = get_claims(request) jwt_username = jwt_claims.get('sub') if existing_notification.username == jwt_username: current_app.logger.info( f'User {jwt_username} is deleting their notification with id {existing_notification.notification_id}.' ) else: current_app.logger.info( f'User {jwt_username} is not authorized to delete a notification sent to {existing_notification.username}.' ) response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'deleted': False, 'error': f'User {jwt_username} is not authorized to delete a notification sent to ' f'{existing_notification.username}.' }) response.status_code = 400 return response is_deleted = NotificationDao.delete_notification_by_id( notification_id=notification_id) if is_deleted: response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'deleted': True, }) response.status_code = 204 return response else: response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'deleted': False, 'error': 'failed to delete the notification' }) response.status_code = 500 return response
def notification_by_id_put(notification_id) -> Response: """ Update an existing notification based on its identifier. :param notification_id: Unique identifier for a user's notification. :return: A response object for the PUT API request. """ notification_id = int(notification_id) old_notification = NotificationDao.get_notification_by_id( notification_id=notification_id) if old_notification is None: response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'updated': False, 'notification': None, 'error': 'there is no existing notification with this id' }) response.status_code = 400 return response notification_data: dict = request.get_json() new_notification = Notification(notification_data) new_notification.notification_id = notification_id jwt_claims: dict = get_claims(request) jwt_username = jwt_claims.get('sub') if old_notification.username == jwt_username: current_app.logger.info( f'User {jwt_username} is updating their notification with id {new_notification.notification_id}.' ) else: current_app.logger.info( f'User {jwt_username} is not authorized to update a notification sent to {old_notification.username}.' ) response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'updated': False, 'notification': None, 'error': f'User {jwt_username} is not authorized to update a notification sent to ' f'{old_notification.username}.' }) response.status_code = 400 return response if old_notification != new_notification: new_notification.modified_date = datetime.now() new_notification.modified_app = 'saints-xctf-api' is_updated = NotificationDao.update_notification( notification=new_notification) if is_updated: updated_notification = NotificationDao.get_notification_by_id( notification_id=notification_id) notification_dict = NotificationData(updated_notification).__dict__ notification_dict['time'] = str(notification_dict['time']) response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'updated': True, 'notification': notification_dict }) response.status_code = 200 return response else: response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'updated': False, 'notification': None, 'error': 'the notification failed to update' }) response.status_code = 500 return response else: response = jsonify({ 'self': f'/v2/notifications/{notification_id}', 'updated': False, 'notification': None, 'error': 'the notification submitted is equal to the existing notification with the same id' }) response.status_code = 400 return response
def notification_post() -> Response: """ Create a new notification for a user. :return: A response object for the POST API request. """ notification_data: dict = request.get_json() if notification_data is None: response = jsonify({ 'self': f'/v2/notifications', 'added': False, 'notification': None, 'error': "the request body isn't populated" }) response.status_code = 400 return response notification_to_add = Notification(notification_data) if None in [notification_to_add.username, notification_to_add.description]: response = jsonify({ 'self': f'/v2/notifications', 'added': False, 'notification': None, 'error': "'username' and 'description' are required fields" }) response.status_code = 400 return response notification_to_add.time = datetime.now() notification_to_add.viewed = 'N' notification_to_add.created_date = datetime.now() notification_to_add.created_app = 'saints-xctf-api' notification_to_add.created_user = None notification_to_add.modified_date = None notification_to_add.modified_app = None notification_to_add.modified_user = None notification_to_add.deleted_date = None notification_to_add.deleted_app = None notification_to_add.deleted_user = None notification_to_add.deleted = False notification_added_successfully = NotificationDao.add_notification( new_notification=notification_to_add) if notification_added_successfully: notification_added = NotificationDao.get_notification_by_id( notification_to_add.notification_id) notification_dict = NotificationData(notification_added).__dict__ notification_dict['time'] = str(notification_dict['time']) response = jsonify({ 'self': '/v2/notifications', 'added': True, 'notification': notification_dict }) response.status_code = 200 return response else: response = jsonify({ 'self': '/v2/notifications', 'added': False, 'notification': None, 'error': 'failed to create a new notification' }) response.status_code = 500 return response
def user_snapshot_by_username_get(username) -> Response: """ Get a snapshot with information about a user with a given username. :param username: Username that uniquely identifies a user. :return: A response object for the GET API request. """ user: User = UserDao.get_user_by_username(username=username) # If the user cant be found, try searching the email column in the database if user is None: email = username user: User = UserDao.get_user_by_email(email=email) # If the user still can't be found, return with an error code if user is None: response = jsonify({ 'self': f'/v2/users/snapshot/{username}', 'user': None, 'error': 'there is no user with this username' }) response.status_code = 400 return response else: user_dict: dict = UserData(user).__dict__ if user_dict.get('member_since') is not None: user_dict['member_since'] = str(user_dict['member_since']) if user_dict.get('last_signin') is not None: user_dict['last_signin'] = str(user_dict['last_signin']) if user_dict.get('profilepic') is not None: try: user_dict['profilepic'] = user_dict['profilepic'].decode( 'utf-8') except AttributeError: pass username = user_dict['username'] groups: ResultProxy = GroupMemberDao.get_user_groups(username=username) group_list = [] for group in groups: group_dict = { 'id': group['id'], 'group_name': group['group_name'], 'group_title': group['group_title'], 'status': group['status'], 'user': group['user'] } newest_log: Column = GroupDao.get_newest_log_date( group['group_name']) group_dict['newest_log'] = newest_log['newest'] newest_message = GroupDao.get_newest_message_date( group['group_name']) group_dict['newest_message'] = newest_message['newest'] group_list.append(group_dict) user_dict['groups'] = group_list forgot_password_codes: ResultProxy = ForgotPasswordDao.get_forgot_password_codes( username=username) forgot_password_list = [] for forgot_password_code in forgot_password_codes: forgot_password_list.append({ 'forgot_code': forgot_password_code['forgot_code'], 'username': forgot_password_code['username'], 'expires': forgot_password_code['expires'], 'deleted': forgot_password_code['deleted'], }) user_dict['forgotpassword'] = forgot_password_list flairs: List[Flair] = FlairDao.get_flair_by_username(username=username) flair_dicts = [] for flair in flairs: flair_dicts.append(FlairData(flair).__dict__) user_dict['flair'] = flair_dicts notifications: ResultProxy = NotificationDao.get_notification_by_username( username=username) notification_dicts = [] for notification in notifications: notification_dicts.append({ 'notification_id': notification['notification_id'], 'username': notification['username'], 'time': notification['time'], 'link': notification['link'], 'viewed': notification['viewed'], 'description': notification['description'] }) user_dict['notifications'] = notification_dicts stats = compile_user_statistics(user, username) user_dict['statistics'] = stats response = jsonify({ 'self': f'/v2/users/snapshot/{username}', 'user': user_dict }) response.status_code = 200 return response