From e5b22ead0c5ec2debcd1612d3aad9a1c608015d2 Mon Sep 17 00:00:00 2001 From: Tiago vasconcelos Date: Tue, 12 Oct 2021 10:38:09 +0100 Subject: [PATCH] initial work --- lnbits/extensions/usermanager/__init__.py | 19 ++++- lnbits/extensions/usermanager/models.py | 14 +++- lnbits/extensions/usermanager/views.py | 19 +++-- lnbits/extensions/usermanager/views_api.py | 95 ++++++++++------------ 4 files changed, 81 insertions(+), 66 deletions(-) diff --git a/lnbits/extensions/usermanager/__init__.py b/lnbits/extensions/usermanager/__init__.py index 53154812..f421a15c 100644 --- a/lnbits/extensions/usermanager/__init__.py +++ b/lnbits/extensions/usermanager/__init__.py @@ -1,12 +1,25 @@ -from quart import Blueprint +import asyncio + +from fastapi import APIRouter + from lnbits.db import Database +from lnbits.helpers import template_renderer db = Database("ext_usermanager") -usermanager_ext: Blueprint = Blueprint( - "usermanager", __name__, static_folder="static", template_folder="templates" +usermanager_ext: APIRouter = APIRouter( + prefix="/usermanager", + tags=["usermanager"] + #"usermanager", __name__, static_folder="static", template_folder="templates" ) +def usermanager_renderer(): + return template_renderer( + [ + "lnbits/extensions/usermanager/templates", + ] + ) + from .views_api import * # noqa from .views import * # noqa diff --git a/lnbits/extensions/usermanager/models.py b/lnbits/extensions/usermanager/models.py index 97eaaea8..7e6a9595 100644 --- a/lnbits/extensions/usermanager/models.py +++ b/lnbits/extensions/usermanager/models.py @@ -1,8 +1,16 @@ -from typing import NamedTuple +from pydantic import BaseModel +from fastapi.param_functions import Query from sqlite3 import Row +class CreateUserData(BaseModel): + user_name: str = Query(...) + wallet_name: str = Query(...) + admin_id: str = Query(...) + email: str = Query(None) + password: str = Query(None) -class Users(NamedTuple): + +class Users(BaseModel): id: str name: str admin: str @@ -10,7 +18,7 @@ class Users(NamedTuple): password: str -class Wallets(NamedTuple): +class Wallets(BaseModel): id: str admin: str name: str diff --git a/lnbits/extensions/usermanager/views.py b/lnbits/extensions/usermanager/views.py index df6949c6..d58a9826 100644 --- a/lnbits/extensions/usermanager/views.py +++ b/lnbits/extensions/usermanager/views.py @@ -1,12 +1,13 @@ -from quart import g, render_template +from fastapi import FastAPI, Request +from fastapi.params import Depends +from fastapi.templating import Jinja2Templates +from starlette.responses import HTMLResponse -from lnbits.decorators import check_user_exists, validate_uuids +from lnbits.core.models import User +from lnbits.decorators import check_user_exists -from . import usermanager_ext +from . import usermanager_ext, usermanager_renderer - -@usermanager_ext.route("/") -@validate_uuids(["usr"], required=True) -@check_user_exists() -async def index(): - return await render_template("usermanager/index.html", user=g.user) +@usermanager_ext.get("/", response_class=HTMLResponse) +async def index(request: Request, user: User = Depends(check_user_exists)): + return await render_template("usermanager/index.html", user=user.dict()) diff --git a/lnbits/extensions/usermanager/views_api.py b/lnbits/extensions/usermanager/views_api.py index d3bba6ad..4e41c8aa 100644 --- a/lnbits/extensions/usermanager/views_api.py +++ b/lnbits/extensions/usermanager/views_api.py @@ -1,10 +1,15 @@ -from quart import g, jsonify from http import HTTPStatus +from starlette.exceptions import HTTPException + +from fastapi import Query +from fastapi.params import Depends from lnbits.core.crud import get_user from lnbits.decorators import api_check_wallet_key, api_validate_post_request +from lnbits.decorators import WalletTypeInfo, get_key_type from . import usermanager_ext +from .models import CreateUserData from .crud import ( create_usermanager_user, get_usermanager_user, @@ -23,74 +28,62 @@ from lnbits.core import update_user_extension ### Users -@usermanager_ext.route("/api/v1/users", methods=["GET"]) -@api_check_wallet_key(key_type="invoice") -async def api_usermanager_users(): - user_id = g.wallet.user - return ( - jsonify([user._asdict() for user in await get_usermanager_users(user_id)]), - HTTPStatus.OK, - ) +@usermanager_ext.get("/api/v1/users", status_code=HTTPStatus.OK) +async def api_usermanager_users(wallet: WalletTypeInfo = Depends(get_key_type)): + user_id = wallet.wallet.user + return [user.dict() for user in await get_usermanager_users(user_id)] -@usermanager_ext.route("/api/v1/users/", methods=["GET"]) -@api_check_wallet_key(key_type="invoice") -async def api_usermanager_user(user_id): +@usermanager_ext.get("/api/v1/users/{user_id}", status_code=HTTPStatus.OK) +async def api_usermanager_user(user_id, wallet: WalletTypeInfo = Depends(get_key_type)): user = await get_usermanager_user(user_id) - return ( - jsonify(user._asdict()), - HTTPStatus.OK, - ) + return user.dict() -@usermanager_ext.route("/api/v1/users", methods=["POST"]) -@api_check_wallet_key(key_type="invoice") -@api_validate_post_request( - schema={ - "user_name": {"type": "string", "empty": False, "required": True}, - "wallet_name": {"type": "string", "empty": False, "required": True}, - "admin_id": {"type": "string", "empty": False, "required": True}, - "email": {"type": "string", "required": False}, - "password": {"type": "string", "required": False}, - } -) -async def api_usermanager_users_create(): - user = await create_usermanager_user(**g.data) - full = user._asdict() - full["wallets"] = [wallet._asdict() for wallet in await get_usermanager_users_wallets(user.id)] - return jsonify(full), HTTPStatus.CREATED +@usermanager_ext.post("/api/v1/users", status_code=HTTPStatus.CREATED) +# @api_validate_post_request( +# schema={ +# "user_name": {"type": "string", "empty": False, "required": True}, +# "wallet_name": {"type": "string", "empty": False, "required": True}, +# "admin_id": {"type": "string", "empty": False, "required": True}, +# "email": {"type": "string", "required": False}, +# "password": {"type": "string", "required": False}, +# } +# ) +async def api_usermanager_users_create(data: CreateUserData, wallet: WalletTypeInfo = Depends(get_key_type)): + user = await create_usermanager_user(**data) + full = user.dict() + full["wallets"] = [wallet.dict() for wallet in await get_usermanager_users_wallets(user.id)] + return full -@usermanager_ext.route("/api/v1/users/", methods=["DELETE"]) -@api_check_wallet_key(key_type="invoice") -async def api_usermanager_users_delete(user_id): +@usermanager_ext.delete("/api/v1/users/{user_id}") +async def api_usermanager_users_delete(user_id, wallet: WalletTypeInfo = Depends(get_key_type)): user = await get_usermanager_user(user_id) if not user: - return jsonify({"message": "User does not exist."}), HTTPStatus.NOT_FOUND + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, + detail="User does not exist." + ) await delete_usermanager_user(user_id) - return "", HTTPStatus.NO_CONTENT + raise HTTPException(status_code=HTTPStatus.NO_CONTENT) ###Activate Extension -@usermanager_ext.route("/api/v1/extensions", methods=["POST"]) -@api_check_wallet_key(key_type="invoice") -@api_validate_post_request( - schema={ - "extension": {"type": "string", "empty": False, "required": True}, - "userid": {"type": "string", "empty": False, "required": True}, - "active": {"type": "boolean", "required": True}, - } -) -async def api_usermanager_activate_extension(): - user = await get_user(g.data["userid"]) +@usermanager_ext.post("/api/v1/extensions") +async def api_usermanager_activate_extension(extension: str = Query(...), userid: str = Query(...), active: bool = Query(...)): + user = await get_user(userid) if not user: - return jsonify({"message": "no such user"}), HTTPStatus.NOT_FOUND + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, + detail="User does not exist." + ) update_user_extension( - user_id=g.data["userid"], extension=g.data["extension"], active=g.data["active"] + user_id=userid, extension=extension, active=active ) - return jsonify({"extension": "updated"}), HTTPStatus.CREATED + return {"extension": "updated"} ###Wallets