コード例 #1
0
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
コード例 #2
0
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
コード例 #3
0
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
コード例 #4
0
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
コード例 #5
0
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
コード例 #6
0
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
コード例 #7
0
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
コード例 #8
0
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