コード例 #1
0
    def update_email_by_token(self, db: Session, response: Response, *,
                              obj_in: schema_user.UserUpdateEmailIn):
        """
        绑定/更换 邮箱
        :param email:           邮箱
        :param email_code:      邮箱验证码
        :return:                用户信息, 提示信息
        """
        # --------- 校验邮箱是否已被使用 --------- #
        email_user = crud_user.get_user_by_email(db, email=obj_in.email)
        if email_user:
            message = f"邮箱 {obj_in.email} 已被使用"
            response.status_code = status.HTTP_400_BAD_REQUEST
            return None, message

        # --------- 校验邮箱验证码 ---------#
        redis_email_code = redis_client.get(obj_in.email)
        if obj_in.email_code != redis_email_code:
            message = "验证码不正确或已过期"
            response.status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
            return None, message

        # --------- 绑定/更换 邮箱 --------- #
        db_user_obj = crud_user.update_email_by_id(db,
                                                   id=token_user.id,
                                                   email=obj_in.email)
        if not db_user_obj:
            message = "邮箱更新失败"
            response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
            logger.error(message)
        else:
            redis_client.set(obj_in.email, "", ex=1)
            message = "邮箱更新成功"
            response.status_code = status.HTTP_200_OK
        return db_user_obj, message
コード例 #2
0
    def get_user_by_account(self, db: Session, response: Response, *,
                            account: str):
        """
        通过账号(手机号/邮箱/用户名)查询用户信息
        :param account:     手机号/邮箱/用户名
        :return:            用户对象信息, 提示信息
        """
        if re.match(RE_PHONE, account):  # 手机号
            db_user = crud_user.get_user_by_phone(db, phone=account)
        elif re.match(RE_EMAIL, account):  # 邮箱
            db_user = crud_user.get_user_by_email(db, email=account)
        else:  # 用户名
            db_user = crud_user.get_user_by_username(db, username=account)

        if not db_user:
            message = f"用户 {account} 未注册"
            response.status_code = status.HTTP_404_NOT_FOUND
            logger.error(message)
            return None, message
        if db_user.status == 1:
            message = f"用户 {account} 已被禁用"
            response.status_code = status.HTTP_403_FORBIDDEN
            logger.error(message)
            return None, message
        message = f"用户 {account} 的信息查询成功"
        response.status_code = status.HTTP_200_OK
        return db_user, message
コード例 #3
0
    def retrieve_password_by_account(
            self, db: Session, response: Response, *, account: str,
            obj_in: schema_user.UserRetrievePasswordIn):
        """
        通过账号(手机号/邮箱)找回密码
        :param account:         手机号/邮箱
        :param verify_code:     验证码
        :param password:        密码
        :return:                用户信息, 提示信息
        """
        # ----------- 判断输入账号是 手机号/邮箱 ---------- #
        if re.match(RE_PHONE, account):  # 手机
            db_user = crud_user.get_user_by_phone(db, phone=account)
        elif re.match(RE_EMAIL, account):  # 邮箱
            db_user = crud_user.get_user_by_email(db, email=account)
        else:
            message = "账号输入有误"
            response.status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
            return None, message

        if not db_user:
            message = f"账号 {account} 未注册"
            response.status_code = status.HTTP_404_NOT_FOUND
            logger.error(message)
            return None, message

        if db_user.status == 1:
            message = f"账号 {account} 已被禁用"
            response.status_code = status.HTTP_403_FORBIDDEN
        else:
            # ----------- 校验验证码 ---------- #
            redis_verify_code = redis_client.get(account)
            if obj_in.verify_code != redis_verify_code:
                message = "验证码不正确或已过期"
                response.status_code = status.HTTP_401_UNAUTHORIZED
                return None, message

            # ---------- 重新设置密码 ---------- #
            hashed_new_password = security.get_password_hash(obj_in.password)
            db_user_obj = crud_user.update_password_by_id(
                db, id=db_user.id, hashed_password=hashed_new_password)
            if not db_user_obj:
                message = "找回密码失败"
                response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
            else:
                redis_client.set(db_user.id, "", ex=1)
                redis_client.set(account, "", ex=1)
                message = "找回密码成功"
                response.status_code = status.HTTP_200_OK
                return db_user_obj, message
        logger.error(message)
        return None, message
コード例 #4
0
    def signup(self, db: Session, request: Request, response: Response, *,
               obj_in: schema_user.UserSignupIn):
        """
        通过 手机号/邮箱 注册
        :param account:             手机号/邮箱
        :param verify_code:         验证码
        :param password:            密码
        :return:                    用户信息, 提示信息
        """
        # --------- 校验验证码 --------- #
        redis_verify_code = redis_client.get(obj_in.account)
        if obj_in.verify_code != redis_verify_code:
            message = "验证码不正确或已过期"
            response.status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
            return None, message

        # --------- 先查询一次,在进行注册 -------- #
        if re.match(RE_PHONE, obj_in.account):  # 手机号
            db_user = crud_user.get_user_by_phone(db, phone=obj_in.account)
            if db_user:
                message = f"账号 {obj_in.account} 已被注册"
                response.status_code = status.HTTP_400_BAD_REQUEST
                return None, message
            else:
                dict_obj_in = {
                    "phone": obj_in.account,
                    "hashed_password":
                    security.get_password_hash(obj_in.password),
                    "ip": request.client.host
                }
                db_create_user = crud_user.create_by_phone(
                    db, obj_in=dict_obj_in)  # 通过手机号进行注册
        elif re.match(RE_EMAIL, obj_in.account):  # 邮箱
            db_user = crud_user.get_user_by_email(db, email=obj_in.account)
            if db_user:
                message = f"账号 {obj_in.account} 已被注册"
                response.status_code = status.HTTP_400_BAD_REQUEST
                return None, message
            else:
                dict_obj_in = {
                    "email": obj_in.account,
                    "hashed_password":
                    security.get_password_hash(obj_in.password),
                    "ip": request.client.host
                }
                db_create_user = crud_user.create_by_email(
                    db, obj_in=dict_obj_in)  # 通过邮箱进行注册
        else:
            message = "账号输入有误"  # 用户名
            response.status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
            logger.error(message)
            return None, message

        if not db_create_user:
            message = f"用户 {obj_in.account} 注册失败"
            response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
            logger.error(message)
        else:
            message = f"用户 {obj_in.account} 注册成功"
            response.status_code = status.HTTP_201_CREATED
            redis_client.set(obj_in.account, "", ex=1)  # 注册成功之后使验证码立即失效
        return db_create_user, message
コード例 #5
0
    def signin_by_verify_code(self, db: Session, request: Request,
                              response: Response, *,
                              obj_in: schema_user.UserVerifyCodeSigninIn):
        """
        通过 短信/邮箱 验证码登录
        :param account:        手机号/邮箱/用户名
        :param verify_code:    验证码
        :return:               token, 提示信息
        """
        # --------- 比较验证码是否匹配 ----------- #
        redis_verify_code = redis_client.get(obj_in.account)
        if obj_in.verify_code != redis_verify_code:
            message = "验证码不正确或已过期"
            response.status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
            logger.error(message)
            return None, message

        if re.match(RE_PHONE, obj_in.account):  # 手机
            db_user = crud_user.get_user_by_phone(db, phone=obj_in.account)
        elif re.match(RE_EMAIL, obj_in.account):  # 邮箱
            db_user = crud_user.get_user_by_email(db, email=obj_in.account)
        else:
            message = "账号输入有误,请重新输入"
            response.status_code = status.HTTP_422_UNPROCESSABLE_ENTITY
            logger.error(message)
            return None, message

        # ----------- 判断账号是否注册过 ----------- #
        userid = None
        authorityid = None
        if not db_user:
            if re.match(RE_PHONE, obj_in.account):  # 手机
                dict_obj_in = {
                    "phone": obj_in.account,
                    "hashed_password": None,
                    "ip": request.client.host
                }
                db_user_obj = crud_user.create_by_phone(db, obj_in=dict_obj_in)
            elif re.match(RE_EMAIL, obj_in.account):  # 邮箱
                dict_obj_in = {
                    "email": obj_in.account,
                    "hashed_password": None,
                    "ip": request.client.host
                }
                db_user_obj = crud_user.create_by_email(db, obj_in=dict_obj_in)

            if not db_user_obj:
                message = "登录失败"
                response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
                logger.error(message)
                return None, message
            userid = db_user_obj.id  # 将新增之后的 用户id 赋值给变量
            authorityid = db_user_obj.authorityid  # 默认权限
        elif db_user.status == 1:
            message = f"账号 {obj_in.account} 已被禁用"
            response.status_code = status.HTTP_403_FORBIDDEN
            logger.error(message)
            return None, message

        if db_user:
            userid = db_user.id
            authorityid = db_user.authorityid

        # -------- # 登录token 存储了userid 和 authorityid ------- #
        access_token_expires = timedelta(
            minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
        token = security.create_access_token(
            userid, authorityid, expires_delta=access_token_expires)
        redis_client.set(userid,
                         token,
                         ex=settings.ACCESS_TOKEN_EXPIRE_MINUTES)

        # --------- 登录成功之后向数据库添加一条登录日志信息 ---------- #
        ip = request.client.host  # 用户ip
        signin_log_id = crud_user.add_signin_log(db, userid=userid, ip=ip)
        if not signin_log_id:
            message = f"用户 {obj_in.account} 登录失败"
            response.status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
            logger.error(message)
            return None, message
        else:
            redis_client.set(obj_in.account, "", ex=1)  # 使验证码失效
            message = f"用户 {obj_in.account} 登录成功"
            response.status_code = status.HTTP_200_OK
            return token, message
コード例 #6
0
    def signin(self, db: Session, request: Request, response: Response, *,
               obj_in: schema_user.UserPasswordSigninIn):
        """
        通过密码登录
        :param account:        手机号/邮箱/用户名
        :param password:       密码
        :return:               token, 提示信息
        """
        # -------- 判断输入账号 手机号/邮箱/用户名 ------- #
        if re.match(RE_PHONE, obj_in.account):  # 手机
            db_user = crud_user.get_user_by_phone(db, phone=obj_in.account)
        elif re.match(RE_EMAIL, obj_in.account):  # 邮箱
            db_user = crud_user.get_user_by_email(db, email=obj_in.account)
        else:  # 用户名
            db_user = crud_user.get_user_by_username(db,
                                                     username=obj_in.account)

        # --------- 判断账号是否注册过 ---------- #
        if not db_user:
            message = f"账号 {obj_in.account} 未注册"
            response.status_code = status.HTTP_404_NOT_FOUND
        elif db_user.status == 1:
            message = f"账号 {obj_in.account} 已被禁用"
            response.status_code = status.HTTP_403_FORBIDDEN
        else:
            # ------ 判断用户是否设置初始密码 ------ #
            if not db_user.hashed_password:
                message = f"账号 {obj_in.account} 还未设置初始密码"
                response.status_code = status.HTTP_401_UNAUTHORIZED
                return None, message

            # --------- 密码进行比对 ----------- #
            if not security.verify_password(obj_in.password,
                                            db_user.hashed_password):
                message = f"用户 {obj_in.account} 密码不正确"
                response.status_code = status.HTTP_401_UNAUTHORIZED
                logger.error(message)
            else:
                # -------- # 登录token 存储了userid 和 authorityid ------- #
                access_token_expires = timedelta(
                    minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
                token = security.create_access_token(
                    db_user.id,
                    db_user.authorityid,
                    expires_delta=access_token_expires)
                redis_client.set(db_user.id,
                                 token,
                                 ex=settings.ACCESS_TOKEN_EXPIRE_MINUTES)

                # -------- 登录成功之后向数据库添加一条登录日志信息 -------- #
                ip = request.client.host  # 用户ip
                db_signin_log = crud_user.add_signin_log(db,
                                                         userid=db_user.id,
                                                         ip=ip)
                if not db_signin_log:
                    message = f"用户 {obj_in.account} 登录失败"
                    response.status_code = status.HTTP_401_UNAUTHORIZED
                else:
                    message = f"用户 {obj_in.account} 登录成功"
                    response.status_code = status.HTTP_200_OK
                    return token, message
        logger.error(message)
        return None, message