fix: make check_user_exists() work with FastAPI

This commit is contained in:
Stefan Stammberger 2021-09-11 15:18:09 +02:00
parent c2551bd765
commit 7b69852acc
No known key found for this signature in database
GPG Key ID: 645FA807E935D9D5
2 changed files with 66 additions and 25 deletions

View File

@ -1,3 +1,21 @@
## Check if a user exists and access user object
**old:**
```python
# decorators
@check_user_exists()
async def do_routing_stuff():
pass
```
**new:**
If user doesn't exist, `Depends(check_user_exists)` will raise an exception.
If user exists, `user` will be the user object
```python
# depends calls
@core_html_routes.get("/my_route")
async def extensions(user: User = Depends(check_user_exists)):
pass
```
## Returning data from API calls ## Returning data from API calls
**old:** **old:**
```python ```python
@ -48,6 +66,39 @@ raise HTTPException(
detail=f"Failed to connect to {domain}." detail=f"Failed to connect to {domain}."
) )
``` ```
## Extensions
**old:**
```python
from quart import Blueprint
amilk_ext: Blueprint = Blueprint(
"amilk", __name__, static_folder="static", template_folder="templates"
)
```
**new:**
```python
from fastapi import APIRouter
from lnbits.jinja2_templating import Jinja2Templates
from lnbits.helpers import template_renderer
from fastapi.staticfiles import StaticFiles
offlineshop_ext: APIRouter = APIRouter(
prefix="/Extension",
tags=["Offlineshop"]
)
offlineshop_ext.mount(
"lnbits/extensions/offlineshop/static",
StaticFiles("lnbits/extensions/offlineshop/static")
)
offlineshop_rndr = template_renderer([
"lnbits/extensions/offlineshop/templates",
])
```
## Possible optimizations ## Possible optimizations
### Use Redis as a cache server ### Use Redis as a cache server
Instead of hitting the database over and over again, we can store a short lived object in [Redis](https://redis.io) for an arbitrary key. Instead of hitting the database over and over again, we can store a short lived object in [Redis](https://redis.io) for an arbitrary key.

View File

@ -2,7 +2,8 @@ from functools import wraps
from http import HTTPStatus from http import HTTPStatus
from fastapi.security import api_key from fastapi.security import api_key
from lnbits.core.models import Wallet from pydantic.types import UUID4
from lnbits.core.models import User, Wallet
from typing import List, Union from typing import List, Union
from uuid import UUID from uuid import UUID
@ -138,29 +139,18 @@ def api_validate_post_request(*, schema: dict):
return wrap return wrap
def check_user_exists(param: str = "usr"): async def check_user_exists(usr: UUID4) -> User:
def wrap(view): g().user = await get_user(usr.hex)
@wraps(view) if not g().user:
async def wrapped_view(**kwargs): raise HTTPException(
g().user = await get_user(request.args.get(param, type=str)) status_code=HTTPStatus.NOT_FOUND,
if not g().user: detail="User does not exist."
raise HTTPException( )
status_code=HTTPStatus.NOT_FOUND,
detail="User does not exist."
)
if LNBITS_ALLOWED_USERS and g().user.id not in LNBITS_ALLOWED_USERS:
raise HTTPException(
status_code=HTTPStatus.UNAUTHORIZED,
detail="User not authorized."
)
return await view(**kwargs)
return wrapped_view
return wrap
if LNBITS_ALLOWED_USERS and g().user.id not in LNBITS_ALLOWED_USERS:
raise HTTPException(
status_code=HTTPStatus.UNAUTHORIZED,
detail="User not authorized."
)
return g().user