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
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
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
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
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
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