From ba843b3df4d28dd3e7d577c76288fe0363c4f5bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Fri, 27 Sep 2024 09:52:04 +0200 Subject: [PATCH] fixup! --- lnbits/core/crud.py | 18 +++++++++++------- lnbits/core/models.py | 16 ++++++++++++---- lnbits/core/views/generic.py | 16 +++++++++------- lnbits/db.py | 6 +++++- lnbits/decorators.py | 10 +++++++--- lnbits/templates/macros.jinja | 4 ++-- 6 files changed, 46 insertions(+), 24 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index c6f5a5a98..02e6cbc8c 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -311,8 +311,8 @@ async def get_installed_extensions( active: Optional[bool] = None, conn: Optional[Connection] = None, ) -> list[InstallableExtension]: - where = "WHERE active = :active" if active else "" - values = {"active": active} if active else {} + where = "WHERE active = :active" if active is not None else "" + values = {"active": active} if active is not None else {} all_extensions = await (conn or db).fetchall( f"SELECT * FROM installed_extensions {where}", values, @@ -503,8 +503,9 @@ async def get_wallet( ) -> Optional[Wallet]: return await (conn or db).fetchone( """ - SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0) - AS balance_msat FROM wallets WHERE id = :wallet + SELECT *, COALESCE(( + SELECT balance FROM balances WHERE wallet_id = wallets.id + ), 0) AS balance_msat FROM wallets WHERE id = :wallet """, {"wallet": wallet_id}, Wallet, @@ -514,8 +515,9 @@ async def get_wallet( async def get_wallets(user_id: str, conn: Optional[Connection] = None) -> list[Wallet]: return await (conn or db).fetchall( """ - SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0) - AS balance_msat FROM wallets WHERE "user" = :user + SELECT *, COALESCE(( + SELECT balance FROM balances WHERE wallet_id = wallets.id + ), 0) AS balance_msat FROM wallets WHERE "user" = :user """, {"user": user_id}, Wallet, @@ -528,7 +530,9 @@ async def get_wallet_for_key( ) -> Optional[Wallet]: return await (conn or db).fetchone( """ - SELECT *, COALESCE((SELECT balance FROM balances WHERE wallet = wallets.id), 0) + SELECT *, COALESCE(( + SELECT balance FROM balances WHERE wallet_id = wallets.id + ), 0) AS balance_msat FROM wallets WHERE (adminkey = :key OR inkey = :key) AND deleted = false """, diff --git a/lnbits/core/models.py b/lnbits/core/models.py index 451c68d35..0558991b7 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -35,10 +35,15 @@ class BaseWallet(BaseModel): balance_msat: int -class Wallet(BaseWallet): +class Wallet(BaseModel): + id: str user: str + name: str + adminkey: str + inkey: str + balance_msat: int currency: Optional[str] - deleted: bool + deleted: bool = False created_at: Optional[int] = None updated_at: Optional[int] = None @@ -109,8 +114,6 @@ class Account(BaseModel): password_hash: Optional[str] = None email: Optional[str] = None balance_msat: Optional[int] = 0 - transaction_count: Optional[int] = 0 - wallet_count: Optional[int] = 0 last_payment: Optional[datetime] = None extra: Optional[UserExtra] = None created_at: datetime = datetime.now() @@ -138,6 +141,11 @@ class Account(BaseModel): return pwd_context.verify(password, self.password_hash) +class AccountOverview(Account): + transaction_count: Optional[int] = 0 + wallet_count: Optional[int] = 0 + + class AccountFilters(FilterModel): __search_fields__ = ["id", "email", "username"] __sort_fields__ = [ diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py index 321bbc154..d138a3da3 100644 --- a/lnbits/core/views/generic.py +++ b/lnbits/core/views/generic.py @@ -159,7 +159,7 @@ async def extensions(request: Request, user: User = Depends(check_user_exists)): request, "core/extensions.html", { - "user": user.dict(), + "user": user.json(), "extensions": extensions, }, ) @@ -200,8 +200,8 @@ async def wallet( request, "core/wallet.html", { - "user": user.dict(), - "wallet": wallet.dict(), + "user": user.json(), + "wallet": wallet.json(), "currencies": allowed_currencies(), "service_fee": settings.lnbits_service_fee, "service_fee_max": settings.lnbits_service_fee_max, @@ -224,7 +224,9 @@ async def account( return template_renderer().TemplateResponse( request, "core/account.html", - {"user": user.dict()}, + { + "user": user.json(), + }, ) @@ -334,7 +336,7 @@ async def node(request: Request, user: User = Depends(check_admin)): request, "node/index.html", { - "user": user.dict(), + "user": user.json(), "settings": settings.dict(), "balance": balance, "wallets": user.wallets[0].dict(), @@ -372,7 +374,7 @@ async def admin_index(request: Request, user: User = Depends(check_admin)): request, "admin/index.html", { - "user": user.dict(), + "user": user.json(), "settings": settings.dict(), "balance": balance, "currencies": list(currencies.keys()), @@ -389,7 +391,7 @@ async def users_index(request: Request, user: User = Depends(check_admin)): "users/index.html", { "request": request, - "user": user.dict(), + "user": user.json(), "settings": settings.dict(), "currencies": list(currencies.keys()), }, diff --git a/lnbits/db.py b/lnbits/db.py index e6bbf23a7..96e8b2185 100644 --- a/lnbits/db.py +++ b/lnbits/db.py @@ -624,7 +624,11 @@ def dict_to_model(_row: dict, model: type[TModel]) -> TModel: if key not in model.__fields__: logger.warning(f"Converting {key} to model `{model}`.") continue + if not value: + continue type_ = model.__fields__[key].type_ - if issubclass(type_, BaseModel): + if issubclass(type_, BaseModel) and value is not None: _dict[key] = type_.construct(**json.loads(value)) + continue + _dict[key] = value return model.construct(**_dict) diff --git a/lnbits/decorators.py b/lnbits/decorators.py index 4fe4377c6..855e1bf38 100644 --- a/lnbits/decorators.py +++ b/lnbits/decorators.py @@ -20,6 +20,7 @@ from lnbits.core.crud import ( ) from lnbits.core.models import ( AccessTokenPayload, + Account, KeyType, SimpleStatus, User, @@ -144,7 +145,10 @@ async def check_user_exists( else: raise HTTPException(HTTPStatus.UNAUTHORIZED, "Missing user ID or access token.") - if not account or not settings.is_user_allowed(account.id): + if not account: + raise HTTPException(HTTPStatus.UNAUTHORIZED, "User not found.") + + if not settings.is_user_allowed(account.id): raise HTTPException(HTTPStatus.UNAUTHORIZED, "User not allowed.") user = await get_user(account) @@ -258,7 +262,7 @@ async def _check_user_extension_access(user_id: str, current_path: str): ) -async def _get_account_from_token(access_token) -> Optional[User]: +async def _get_account_from_token(access_token) -> Optional[Account]: try: payload: dict = jwt.decode(access_token, settings.auth_secret_key, ["HS256"]) user = await _get_user_from_jwt_payload(payload) @@ -278,7 +282,7 @@ async def _get_account_from_token(access_token) -> Optional[User]: raise HTTPException(HTTPStatus.UNAUTHORIZED, "Invalid access token.") from exc -async def _get_user_from_jwt_payload(payload) -> Optional[User]: +async def _get_user_from_jwt_payload(payload) -> Optional[Account]: if "sub" in payload and payload.get("sub"): return await get_account_by_username(str(payload.get("sub"))) if "usr" in payload and payload.get("usr"): diff --git a/lnbits/templates/macros.jinja b/lnbits/templates/macros.jinja index 5daaed3d2..9049ec1ee 100644 --- a/lnbits/templates/macros.jinja +++ b/lnbits/templates/macros.jinja @@ -5,10 +5,10 @@ window.currencies = {{ currencies | tojson | safe }}; {% endif %} {% if user %} - window.user = {{ user | tojson | safe }}; + window.user = JSON.parse({{ user | tojson | safe }}); {% endif %} {% if wallet %} - window.wallet = {{ wallet | tojson | safe }}; + window.wallet = JSON.parse({{ wallet | tojson | safe }}); {% endif %} {%- endmacro %}