コード例 #1
0
    async def decorator(*args: Any, **kwargs: Any) -> Callable:
        request = __get_request(args)
        jwt_token = request.cookies.get("jwt_token", "")

        if not jwt_token:
            return RedirectResponse(request.url_for("home"))

        try:
            jwt_decode(jwt_token)
        except InvalidTokenError:
            try:
                UsersSessions.get(jwt_token=jwt_token).delete_instance()
            except UsersSessions.DoesNotExist:
                pass

            response = RedirectResponse(request.url_for("home"))
            response.delete_cookie("jwt_token")

            return response

        try:
            UsersSessions.get(jwt_token=jwt_token)
        except UsersSessions.DoesNotExist:
            response = RedirectResponse(request.url)
            response.delete_cookie("jwt_token")

            return response

        return await func(*args, **kwargs)
コード例 #2
0
ファイル: security.py プロジェクト: Nearata/kami
    async def post(
            self,
            request: Request) -> Union[_TemplateResponse, RedirectResponse]:
        data = await request.form()

        current_password = data.get("password", "")
        new_password = data.get("new_password", "")
        confirm_password = data.get("confirm_password", "")

        errors = []

        if not current_password:
            errors.append("The field password is mandatory.")

        if not new_password:
            errors.append("The field new password is mandatory.")

        if not confirm_password:
            errors.append("The field confirm password is mandatory.")

        if errors:
            return self.__response(request, {"errors": errors})

        jwt = request.cookies.get("jwt_token", "")
        jwt_decoded = jwt_decode(jwt)
        username = jwt_decoded.get("username")
        user = Users.get(username=username)
        hashed_password = user.password

        if verify_password(
                current_password,
                hashed_password) and current_password == new_password:
            errors.append("The new password is equal to the current one.")
        else:
            errors.append("The current password is wrong.")

        if new_password != confirm_password:
            errors.append("New password and confirm password are not equal.")

        psw_req_errors = password_requirements(new_password)
        for i in psw_req_errors:
            errors.append(i)

        new_hashed_password = hash_password(new_password)
        if new_hashed_password is None:
            errors.append(
                "Unable to change password. Please contact an administrator.")

        if errors:
            return self.__response(request, {"errors": errors})

        setattr(user, "password", new_hashed_password)
        user.save()

        return self.__response(request, {"success": "Password changed."})
コード例 #3
0
ファイル: jwt.py プロジェクト: Nearata/kami
    async def dispatch(self, request: Request,
                       call_next: RequestResponseEndpoint) -> Response:
        jwt_token = request.cookies.get("jwt_token", "")
        request.state.is_admin = False

        if jwt_token:
            try:
                jwt_decoded = jwt_decode(jwt_token)
                request.state.is_admin = jwt_decoded.get("is_admin", False)
            except Exception:
                pass

        return await call_next(request)
コード例 #4
0
ファイル: twofactor.py プロジェクト: Nearata/kami
    async def get(self, request: Request) -> _TemplateResponse:
        token = request.cookies.get("jwt_token", "")
        token_decoded = jwt_decode(token)

        username = token_decoded.get("username")
        user = Users.get(username=username)
        is_twofa = user.is_twofa

        context = {"is_twofa": is_twofa}

        secret = user.twofa_secret or otp_random_base32()
        totp = TOTP(secret).provisioning_uri(username, SITE_NAME)

        if not is_twofa:
            context.update({"qrcode": totp, "secret": secret})

        return self.__response(request, context)
コード例 #5
0
ファイル: twofactor.py プロジェクト: Nearata/kami
    async def post(self, request: Request) -> _TemplateResponse:
        data = await request.form()

        password = data.get("password", "")
        code = data.get("code", "")

        token = request.cookies.get("jwt_token", "")
        token_decoded = jwt_decode(token)

        username = token_decoded.get("username")
        user = Users.get(username=username)
        is_twofa = user.is_twofa

        secret = data.get("secret", user.twofa_secret)

        context = {"is_twofa": is_twofa}
        errors = []

        if not secret:
            errors.append("Invalid request. Please try again.")
            context.update({"errors": errors})
            return self.__response(request, context, 400)

        if not password:
            errors.append("The password field is mandatory.")

        if not code:
            errors.append("The code field is mandatory.")

        if not verify_password(password, user.password):
            errors.append("The password is not valid.")

        totp = TOTP(secret).provisioning_uri(username, SITE_NAME)

        if not is_twofa:
            context.update({"qrcode": totp, "secret": secret})

        if errors:
            context.update({"errors": errors})
            return self.__response(request, context, 401)

        if is_twofa:
            user.is_twofa = False
            user.twofa_secret = ""

            new_secret = otp_random_base32()
            new_totp = TOTP(new_secret).provisioning_uri(username, SITE_NAME)
            context.update({"qrcode": new_totp, "secret": new_secret})
        else:
            user.is_twofa = True
            user.twofa_secret = secret
            del context["qrcode"]
            del context["secret"]

        user.save()

        context.update({
            "success": f"2Factor {'enabled' if user.is_twofa else 'disabled'}",
            "is_twofa": user.is_twofa
        })

        return self.__response(request, context)