예제 #1
0
def user_statistics_by_username_get(username) -> Response:
    """
    Get exercise statistics for a user.
    :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/statistics/{username}',
            'stats': None,
            'error': 'there is no user with this username'
        })
        response.status_code = 400
        return response

    response = jsonify({
        'self': f'/v2/users/statistics/{username}',
        'stats': compile_user_statistics(user, username)
    })
    response.status_code = 200
    return response
예제 #2
0
def user_lookup_by_username_get(username: str) -> Response:
    """
    Check if a user exists based on its username or email.
    :param username: Username that uniquely identifies a user.
    :return: A response object for the GET API request.
    """
    existing_user: User = UserDao.get_user_by_username(username=username)

    # If the user cant be found, try searching the email column in the database
    if existing_user is None:
        email = username
        existing_user: User = UserDao.get_user_by_email(email=email)

    # If the user still can't be found, return with an error code
    if existing_user is None:
        response = jsonify({
            'self':
            f'/v2/users/lookup/{username}',
            'exists':
            False,
            'error':
            'There is no user with this username or email.'
        })
        response.status_code = 400
        return response
    else:
        response = jsonify({
            'self': f'/v2/users/lookup/{username}',
            'exists': True
        })
        response.status_code = 200
        return response
예제 #3
0
def user_by_username_get(username) -> Response:
    """
    Retrieve a user based on its 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/{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

        response = jsonify({
            'self': f'/v2/users/{username}',
            'user': user_dict
        })
        response.status_code = 200
        return response
예제 #4
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
예제 #5
0
def forgot_password_get(username) -> Response:
    """
    Retrieve an existing forgot password code for a specific user.
    :param username: Uniquely identifies a user.
    :return: JSON with the resulting Forgot Password object and relevant metadata.
    """
    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 user is None:
        response = jsonify({
            'self':
            f'/v2/forgot_password/{username}',
            'forgot_password_codes': [],
            'error':
            'There is no user associated with this username/email.'
        })
        response.status_code = 400
        return response

    jwt_claims: dict = get_claims(request)
    jwt_username = jwt_claims.get('sub')

    if user.username == jwt_username:
        current_app.logger.info(
            f'User {jwt_username} is accessing their forgot password codes.')
    else:
        current_app.logger.info(
            f'User {jwt_username} is not authorized to access forgot password codes for user {user.username}.'
        )
        response = jsonify({
            'self':
            f'/v2/forgot_password/{username}',
            'created':
            False,
            'error':
            f'User {jwt_username} is not authorized to access forgot password codes for user {user.username}.'
        })
        response.status_code = 400
        return response

    forgot_password_codes: ResultProxy = ForgotPasswordDao.get_forgot_password_codes(
        username=user.username)

    if forgot_password_codes is None:
        response = jsonify({
            'self': f'/v2/forgot_password/{username}',
            'forgot_password_codes': [],
            'error': 'This user has no forgot password codes.'
        })
        response.status_code = 400
        return response
    else:
        forgot_password_list = []
        for code in forgot_password_codes:
            fpw = ForgotPasswordData(None)
            fpw.forgot_code = code[0]
            fpw.username = code[1]
            fpw.expires = code[2]
            fpw.deleted = code[3]
            forgot_password_list.append(fpw.__dict__)

        response = jsonify({
            'self': f'/v2/forgot_password/{username}',
            'forgot_password_codes': forgot_password_list,
        })
        response.status_code = 200
        return response
예제 #6
0
def forgot_password_post(username) -> Response:
    """
    Create a new forgot password code for a specific user.
    :param username: Uniquely identifies a user.
    :return: JSON with the resulting Forgot Password object and relevant metadata.
    """
    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 user is None:
        response = jsonify({
            'self':
            f'/v2/forgot_password/{username}',
            'created':
            False,
            'error':
            'There is no user associated with this username/email.'
        })
        response.status_code = 400
        return response

    code = generate_code(length=8)
    expires = datetime.now() + timedelta(hours=2)

    new_forgot_password = ForgotPassword({
        'forgot_code': code,
        'username': user.username,
        'expires': expires
    })

    new_forgot_password.created_date = datetime.now()
    new_forgot_password.created_app = 'saints-xctf-api'
    new_forgot_password.created_user = None
    new_forgot_password.modified_date = None
    new_forgot_password.modified_app = None
    new_forgot_password.modified_user = None
    new_forgot_password.deleted_date = None
    new_forgot_password.deleted_app = None
    new_forgot_password.deleted_user = None
    new_forgot_password.deleted = False

    forgot_password_inserted = ForgotPasswordDao.add_forgot_password_code(
        new_forgot_password)

    if forgot_password_inserted:
        new_forgot_password = ForgotPasswordDao.get_forgot_password_code(code)

        async def send_forgot_password_email():
            async with aiohttp.ClientSession() as session:
                async with session.post(
                        url=
                        f"{current_app.config['FUNCTION_URL']}/email/forgot-password",
                        json={
                            'to': user.email,
                            'code': new_forgot_password.forgot_code,
                            'username': user.username,
                            'firstName': user.first,
                            'lastName': user.last
                        }) as response:
                    response_body = await response.json()
                    if not response_body.get('result'):
                        current_app.logger.error(
                            'Failed to send the activation code to the user')
                        abort(424)

        asyncio.run(send_forgot_password_email())

        response = jsonify({
            'self': f'/v2/forgot_password/{username}',
            'created': True
        })
        response.status_code = 201
        return response
    else:
        response = jsonify({
            'self':
            f'/v2/forgot_password/{username}',
            'created':
            False,
            'error':
            'An unexpected error occurred while creating the new forgot password code.'
        })
        response.status_code = 500
        return response