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
Exemple #2
0
    def POST(self):
        postData = web.input()
        username = postData["username"]
        password = postData["password"]
        log = login(username, password)
        loginResult = log.main()

        # 调后台接口
        # 返回值为bool型变量判断是否绑定成功
        #flag = False
        render = web.template.render(
            configfile.getConfig("web", "Templates_Path"))

        if (loginResult == None):
            errMsg = "用户名和密码可能错误"
            return render.error(errMsg)
        else:
            binding = UserDao()
            flag = binding.insertOrUpdateUser(postData)

            if flag:
                return render.success()
            else:
                errMsg = "用户已绑定"
                return render.error(errMsg)
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
Exemple #4
0
 def jiebang(self):
     fromUser = self.xml.find("FromUserName").text
     user = UserDao()
     flag = user.deleteUser(fromUser)
     if (flag == True):
         resultStr = '解绑成功'
     else:
         resultStr = '解绑失败,您未绑定'
     return resultStr
Exemple #5
0
 def GET(self):
     getData = web.input()
     render = web.template.render(
         configfile.getConfig("web", "Templates_Path"))
     name = getData['openid']
     user = UserDao()
     flag = user.selectUserFlag(name)
     if (flag == 3):
         errMsg = '您已绑定'
         return render.error(errMsg)
     return render.bangding(name)
Exemple #6
0
	def bangding(self):
		fromUser = self.xml.find("FromUserName").text
		user = UserDao()
		flag=user.selectUserFlag(fromUser)
		if(flag!=3):
			data = "<a href='http://xiwai.chdbwtx.cn/binding?openid=%s'>绑定</a>"%fromUser
		else:
			userInfo=user.selectUserInfoByOpenid(fromUser)
			username=userInfo[0]
			password=userInfo[1]
			data='您已绑定,您的绑定信息为\n用户名:{username}\n密  码:{password}'.format(username=username,password=password)
		return data
Exemple #7
0
def checkUserName(request):
    print("asdfasdf")
    dictObj = json.loads(request.body.decode('utf-8'))
    userName = dictObj['userName']
    userDao = UserDao()
    result = userDao.findUserByUserName([userName])
    rDict = {}
    if result:
        rDict['result'] = 1
    else:
        rDict['result'] = 0
    return HttpResponse(json.dumps(rDict), content_type='application/json')
    pass
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
Exemple #9
0
def userlogin(request):
    userName = request.POST.get('userName', '')
    userPwd = request.POST.get('userPwd', '')
    remeberme = request.POST.get('remeberme', '')
    #密码加密处理
    userPwd = hashlib.md5(userPwd.encode(encoding='utf-8')).hexdigest()
    userDao = UserDao()
    result = userDao.loginParams([userName, userPwd])
    userDao.close()
    if result and result[0]['role'] == 2:
        user = {}
        user['userName'] = userName
        user['userId'] = result[0]['userid']
        user['userPic'] = result[0]['userpic']
        user['Role'] = result[0]['role']
        request.session['user'] = user
        return render(request, 'user/index.html')
    else:
        return redirect('/ulogin/')
    pass
Exemple #10
0
 def __updateScore(self, flag):
     user = UserDao()
     userInfo = user.selectUserInfoByOpenid(self.openidStr)
     username = userInfo[0]
     password = userInfo[1]
     user = Score(username, password)
     scoreStr = user.parseScorePage()
     if (scoreStr != None):
         if (flag == 0):
             return self.__insertScore(scoreStr)
         else:
             scoreInfo = self.session.query(Scores).filter_by(
                 openid=self.openidStr).first()
             scoreInfo.score = scoreStr
             scoreInfo.updateTime = datetime.datetime.now().date()
             self.session.commit()
             logger.info("用户" + self.openidStr + "成绩更新成功")
             return True
     else:
         logger.error("用户" + self.openidStr + "成绩查询失败")
         return False
Exemple #11
0
    def GET(self):
        render = web.template.render(
            configfile.getConfig("web", "Templates_Path"))
        getData = web.input()
        openid = getData['openid']

        user = UserDao()
        flag = user.selectUserFlag(openid)
        if (flag != 3):
            errMsg = '您未绑定'
            return render.error(errMsg)
        score = ScoreDao(openid)
        scoreStr = score.selectScore()
        # 调取后台接口,获取成绩的数据
        if (scoreStr == 2):
            errMsg = '网络繁忙,稍后再试'
            return render.error(errMsg)
        else:
            data = json.loads(scoreStr)
            # data = [
            # 	{
            # 		'name':'数学',
            # 		'zuizhong':'89',
            # 		'xuefen':'2.1',
            # 		'jidian':'254'

            # 	},
            # 	{
            # 		'name':'数学',
            # 		'zuizhong':'89',
            # 		'xuefen':'2.1',
            # 		'jidian':'254'

            # 	}
            # ]
            return render.detail(data)
Exemple #12
0
 def chengji(self):
     fromUser = self.xml.find("FromUserName").text
     user = UserDao()
     flag = user.selectUserFlag(fromUser)
     if (flag != 3):
         data = '您未绑定'
         return data
     score = ScoreDao(fromUser)
     scoreStr = score.selectScore()
     # 调取后台接口,获取成绩的数据
     if (scoreStr == 2):
         data = '网络繁忙,稍后再试'
         return data
     else:
         data = ''
         jidian = 0.0
         datascore = json.loads(scoreStr)
         for score in datascore:
             jidian += float(score['jidian'])
             data += score['name']+":\n"+\
             "成绩:"+score['zuizhong']+"\n\n"
         data += "平均绩点:" + str(round(jidian / len(datascore), 1)) + "\n"
         data += "<a href='http://xiwai.chdbwtx.cn/Score?openid=%s'>详细成绩</a>" % fromUser
         return data
def user_update_last_login_by_username_put(username) -> Response:
    """
    Change the last login date of a user with a given username.
    :param username: Username that uniquely identifies a user.
    :return: A response object for the PUT API request.
    """
    jwt_claims: dict = get_claims(request)
    jwt_username = jwt_claims.get('sub')

    if username == jwt_username:
        current_app.logger.info(f'User {jwt_username} logged in.')
    else:
        current_app.logger.info(
            f'User {jwt_username} is not authorized to update the last login date of user {username}.'
        )
        response = jsonify({
            'self':
            f'/v2/users/{username}/update_last_login',
            'last_login_updated':
            False,
            'error':
            f'User {jwt_username} is not authorized to update the last login date of user {username}.'
        })
        response.status_code = 400
        return response

    last_login_updated: bool = UserDao.update_user_last_login(username)
    if last_login_updated:
        response = jsonify({
            'self': f'/v2/users/{username}/update_last_login',
            'last_login_updated': True
        })
        response.status_code = 200
        return response
    else:
        response = jsonify({
            'self':
            f'/v2/users/{username}/update_last_login',
            'last_login_updated':
            False,
            'error':
            'an unexpected error occurred updating the users last login date'
        })
        response.status_code = 500
        return response
def users_get() -> Response:
    """
    Retrieve all the users in the database.
    :return: A response object for the GET API request.
    """
    all_users: list = UserDao.get_users()

    if all_users is None:
        response = jsonify({
            'self':
            '/v2/users',
            'users':
            None,
            'error':
            'an unexpected error occurred retrieving users'
        })
        response.status_code = 500
        return response
    else:
        user_dicts = []

        for user in all_users:
            user_dict = UserData(user).__dict__
            user_dict['this_user'] = f'/v2/users/{user_dict["username"]}'

            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

            user_dicts.append(user_dict)

        response = jsonify({'self': '/v2/users', 'users': user_dicts})
        response.status_code = 200
        return response
def user_by_username_delete(username) -> Response:
    """
    Hard delete an existing user with a given username.
    :param username: Username that uniquely identifies a user.
    :return: A response object for the DELETE API request.
    """
    is_deleted = UserDao.delete_user(username=username)

    if is_deleted:
        response = jsonify({
            'self': f'/v2/users/{username}',
            'deleted': True,
        })
        response.status_code = 204
        return response
    else:
        response = jsonify({
            'self': f'/v2/users/{username}',
            'deleted': False,
            'error': 'failed to delete the user'
        })
        response.status_code = 500
        return response
Exemple #16
0
def reNewUser(request):
    #普通的表单项
    userName = request.POST.get('userName', '')
    userPwd = request.POST.get('userPwd', '')
    userPhone = request.POST.get('userPhone', '')
    userIntro = request.POST.get('userIntro', '')
    userPicPath = ""  #保存路径
    print(userName)
    print(userPwd)
    print(userPhone)
    print(userIntro)

    #加密密码
    userPwd = hashlib.md5(userPwd.encode(encoding='utf-8')).hexdigest()
    #文件上传
    if request.POST:
        fileObj = request.FILES.get('userPic', None)
        if fileObj:
            print("pic成功")
            userPicPath = '/static/upload/' + fileObj.name
            print(userPicPath)
            filePath = os.path.join(os.getcwd(),
                                    'static/upload/' + fileObj.name)
            with open(filePath, 'wb+') as fp:
                for chunk in fileObj.chunks():
                    fp.write(chunk)

    userDao = UserDao()
    result = userDao.createUser(
        [userName, userPwd, userPhone, userPicPath, userIntro])
    userDao.commit()
    userDao.close()
    #如果写入成功 跳转到登陆页
    if result == 1:
        return render(request, 'admin/login.html', {'success': 1})
        pass
    else:
        return render(request, 'newuser.html', {'success': 0})
def user_by_username_soft_delete(username) -> Response:
    """
    Soft delete an existing user with a given username.
    :param username: Username that uniquely identifies a user.
    :return: A response object for the DELETE API request.
    """
    jwt_claims: dict = get_claims(request)
    jwt_username = jwt_claims.get('sub')

    if username == jwt_username:
        current_app.logger.info(
            f'User {jwt_username} is soft deleting their user.')
    else:
        current_app.logger.info(
            f'User {jwt_username} is not authorized to soft delete user {username}.'
        )
        response = jsonify({
            'self':
            f'/v2/users/soft/{username}',
            'deleted':
            False,
            'error':
            f'User {jwt_username} is not authorized to soft delete user {username}.'
        })
        response.status_code = 400
        return response

    existing_user: User = UserDao.get_user_by_username(username=username)

    if existing_user is None:
        response = jsonify({
            'self':
            f'/v2/users/soft/{username}',
            'deleted':
            False,
            'error':
            'there is no existing user with this username'
        })
        response.status_code = 400
        return response

    # Update the user model to reflect the soft delete
    existing_user.deleted = True
    existing_user.deleted_date = datetime.now()
    existing_user.deleted_app = 'saints-xctf-api'
    existing_user.modified_date = datetime.now()
    existing_user.modified_app = 'saints-xctf-api'

    is_deleted: bool = UserDao.soft_delete_user(existing_user)

    if is_deleted:
        response = jsonify({
            'self': f'/v2/users/soft/{username}',
            'deleted': True,
        })
        response.status_code = 204
        return response
    else:
        response = jsonify({
            'self': f'/v2/users/soft/{username}',
            'deleted': False,
            'error': 'failed to soft delete the user'
        })
        response.status_code = 500
        return response
def user_by_username_put(username) -> Response:
    """
    Update an existing user with a given username.
    :param username: Username that uniquely identifies a user.
    :return: A response object for the PUT API request.
    """
    old_user: User = UserDao.get_user_by_username(username=username)

    if old_user is None:
        response = jsonify({
            'self':
            f'/v2/users/{username}',
            'updated':
            False,
            'user':
            None,
            'error':
            'there is no existing user with this username'
        })
        response.status_code = 400
        return response

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

    if username == jwt_username:
        current_app.logger.info(
            f'User {jwt_username} is updating their user details.')
    else:
        current_app.logger.info(
            f'User {jwt_username} is not authorized to update user {username}.'
        )
        response = jsonify({
            'self':
            f'/v2/users/{username}',
            'updated':
            False,
            'user':
            None,
            'error':
            f'User {jwt_username} is not authorized to update user {username}.'
        })
        response.status_code = 400
        return response

    user_data: dict = request.get_json()
    new_user = User(user_data)

    if new_user != old_user:
        is_updated = UserDao.update_user(username, new_user)

        if is_updated:
            updated_user = UserDao.get_user_by_username(username)

            updated_user_dict: dict = UserData(updated_user).__dict__

            if updated_user_dict.get('profilepic') is not None:
                try:
                    updated_user_dict['profilepic'] = updated_user_dict[
                        'profilepic'].decode('utf-8')
                except AttributeError:
                    pass

            response = jsonify({
                'self': f'/v2/users/{username}',
                'updated': True,
                'user': updated_user_dict
            })
            response.status_code = 200
            return response
        else:
            response = jsonify({
                'self': f'/v2/users/{username}',
                'updated': False,
                'user': None,
                'error': 'the user failed to update'
            })
            response.status_code = 500
            return response
    else:
        response = jsonify({
            'self':
            f'/v2/users/{username}',
            'updated':
            False,
            'user':
            None,
            'error':
            'the user submitted is equal to the existing user with the same username'
        })
        response.status_code = 400
        return response
def user_post() -> Response:
    """
    Create a new user.
    :return: A response object for the POST API request.
    """
    user_data: dict = request.get_json()

    def create_validation_error_response(message: str):
        """
        Reusable 400 HTTP error response for the users POST request.
        :param message: Message sent in the response JSON's 'error' field.
        :return: An HTTP response object.
        """
        error_response = jsonify({
            'self': f'/v2/users',
            'added': False,
            'user': None,
            'error': message
        })
        error_response.status_code = 400
        return error_response

    if user_data is None:
        return create_validation_error_response(
            "The request body isn't populated.")

    user_to_add = User(user_data)

    if None in [
            user_to_add.username, user_to_add.first, user_to_add.last,
            user_to_add.password, user_to_add.activation_code,
            user_to_add.email
    ]:
        return create_validation_error_response(
            "'username', 'first', 'last', 'email', 'password', and 'activation_code' are required fields"
        )

    if len(user_to_add.password) < 6:
        return create_validation_error_response(
            "Password must contain at least 6 characters.")

    username_pattern = re.compile('^[a-zA-Z0-9]+$')

    if not username_pattern.match(user_to_add.username):
        return create_validation_error_response(
            "Username can only contain Roman characters and numbers.")

    email_pattern = re.compile(
        '^(([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\\.([a-zA-Z])+([a-zA-Z])+)?$')

    if not email_pattern.match(user_to_add.email):
        return create_validation_error_response(
            "The email address is invalid.")

    # Passwords must be hashed before stored in the database
    password = user_to_add.password
    hashed_password = flask_bcrypt.generate_password_hash(password).decode(
        'utf-8')
    user_to_add.password = hashed_password

    activation_code_count = CodeDao.get_code_count(
        activation_code=user_to_add.activation_code)

    if activation_code_count == 1:
        now = datetime.now()
        user_to_add.member_since = now.date()
        user_to_add.created_date = now
        user_to_add.last_signin = now
        user_to_add.created_app = 'saints-xctf-api'
        user_to_add.created_user = None
        user_to_add.modified_date = None
        user_to_add.modified_app = None
        user_to_add.modified_user = None
        user_to_add.deleted_date = None
        user_to_add.deleted_app = None
        user_to_add.deleted_user = None
        user_to_add.deleted = False

        # First, add the user since its activation code is valid.
        UserDao.add_user(user_to_add)

        # Second, set the initial team and group for the user.
        code: Code = ActivationCodeDao.get_activation_code(
            user_to_add.activation_code)

        initial_group_id = int(code.group_id)
        initial_group: Group = GroupDao.get_group_by_id(initial_group_id)
        initial_team: Team = TeamDao.get_team_by_group_id(initial_group_id)

        TeamMemberDao.set_initial_membership(
            username=user_to_add.username,
            team_name=initial_team.name,
            group_id=initial_group_id,
            group_name=initial_group.group_name)

        # Third, remove the activation code so it cant be used again.
        CodeDao.remove_code(code)

        added_user = UserDao.get_user_by_username(user_to_add.username)

        if added_user is None:
            response = jsonify({
                'self':
                '/v2/users',
                'added':
                False,
                'user':
                None,
                'error':
                'An unexpected error occurred creating the user.'
            })
            response.status_code = 500
            return response
        else:
            response = jsonify({
                'self': '/v2/users',
                'added': True,
                'user': UserData(added_user).__dict__,
                'new_user': f'/v2/users/{added_user.username}'
            })
            response.status_code = 201
            return response
    else:
        current_app.logger.error(
            'Failed to create new User: The Activation Code does not exist.')
        response = jsonify({
            'self':
            '/v2/users',
            'added':
            False,
            'user':
            None,
            'error':
            'The activation code is invalid or expired.'
        })
        response.status_code = 400
        return response
Exemple #20
0
def getUserList(request):
    userDao = UserDao()
    # 获取查询条件
    userName = request.POST.get('userName', '')
    userPhone = request.POST.get('userPhone', '')
    userState = request.POST.get('userState', '')
    pageSize = request.POST.get('pageSize', '0')
    currentPage = request.POST.get('currentPage', '0')
    userId = request.POST.get('userId', '')
    print(userId)
    opr = request.POST.get('opr', '')
    if pageSize == "0" or pageSize == "":
        pageSize = "3"
    if currentPage == "0" or currentPage == "":
        currentPage = "1"

    print(type(pageSize))
    params = {
        'userName': userName,
        'userPhone': userPhone,
        'userState': userState,
        'pageSize': int(pageSize),
        'currentPage': int(currentPage)
    }

    if opr == 'delUser':
        result = userDao.removeUser(userId)
        params['result'] = result

    #查询用户的个人信息
    if opr == 'update':
        uUser = userDao.findUserByUserId([userId])
        return render(request, 'admin/sysmgr/updateuser.html', {
            'params': params,
            'uUser': uUser
        })
        pass

    #提交用户的个人信息
    if opr == 'submitUpdate':
        print("修改")
        print(userId)
        userIntro = request.POST.get('userIntro', '')
        # 文件上传
        userPicPath = ""
        if request.POST:
            fileObj = request.FILES.get('userPic', None)
            if fileObj:
                userPicPath = '/static/upload/' + fileObj.name
                filePath = os.path.join(os.getcwd(),
                                        'static/upload/' + fileObj.name)
                with open(filePath, 'wb+') as fp:
                    for chunk in fileObj.chunks():
                        fp.write(chunk)
        result = userDao.updateUser(
            [userPhone, userPicPath, userIntro, userId])
        pass

    counts = userDao.findUserCounts(params)
    totalePage = counts // int(pageSize) if counts % int(
        pageSize) == 0 else counts // int(pageSize) + 1
    params['counts'] = counts
    params['totalPage'] = totalePage
    #计算两个值 startRow
    startRow = (int(currentPage) - 1) * int(pageSize)
    params['startRow'] = startRow
    userList = userDao.findPageUserList(params)
    userDao.commit()
    userDao.close()
    return render(request, 'admin/sysmgr/userinfo.html', {
        'userList': userList,
        'params': params
    })
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
Exemple #22
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
Exemple #23
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
def user_change_password_by_username_put(username) -> Response:
    """
    Change the password of a user with a given username.
    :param username: Username that uniquely identifies a user.
    :return: A response object for the GET API request.
    """
    # Request should use the following pattern: {"forgot_password_code": "...", "new_password": "******"}
    request_dict: dict = request.get_json()
    forgot_password_code: str = request_dict.get('forgot_password_code')
    new_password: str = request_dict.get('new_password')

    if forgot_password_code is None or new_password is None:
        response = jsonify({
            'self':
            f'/v2/users/{username}/change_password',
            'password_updated':
            False,
            'forgot_password_code_deleted':
            False,
            'error':
            "'forgot_password_code' and 'new_password' are required fields."
        })
        response.status_code = 500
        return response

    forgot_password_code_info: ForgotPassword = ForgotPasswordDao.get_forgot_password_code(
        forgot_password_code)

    if not forgot_password_code_info:
        response = jsonify({
            'self': f'/v2/users/{username}/change_password',
            'password_updated': False,
            'forgot_password_code_deleted': False,
            'error': "This forgot password code is invalid."
        })
        response.status_code = 500
        return response

    if forgot_password_code_info.username != username:
        response = jsonify({
            'self':
            f'/v2/users/{username}/change_password',
            'password_updated':
            False,
            'forgot_password_code_deleted':
            False,
            'error':
            "This forgot password code does not belong to the specified user."
        })
        response.status_code = 500
        return response

    hashed_password = flask_bcrypt.generate_password_hash(new_password).decode(
        'utf-8')

    password_updated: bool = UserDao.update_user_password(
        username, hashed_password)

    if password_updated:
        code_deleted: bool = ForgotPasswordDao.delete_forgot_password_code(
            code=forgot_password_code)
        response = jsonify({
            'self': f'/v2/users/{username}/change_password',
            'password_updated': True,
            'forgot_password_code_deleted': code_deleted
        })
        response.status_code = 200
        return response
    else:
        response = jsonify({
            'self':
            f'/v2/users/{username}/change_password',
            'password_updated':
            False,
            'forgot_password_code_deleted':
            False,
            'error':
            'an unexpected error occurred changing passwords'
        })
        response.status_code = 500
        return response