From 38a132604b324881e97aed15cb51835de0c734c3 Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 11 Jan 2023 19:06:58 +0200 Subject: [PATCH] feat: used dedicated table for installed extensions --- lnbits/commands.py | 4 +-- lnbits/core/crud.py | 65 ++++++++++++++++++++++++++++++++---- lnbits/core/migrations.py | 14 ++++++++ lnbits/core/views/api.py | 13 ++++++-- lnbits/core/views/generic.py | 11 ++++-- lnbits/extension_manger.py | 3 +- 6 files changed, 94 insertions(+), 16 deletions(-) diff --git a/lnbits/commands.py b/lnbits/commands.py index f80a2761b..0d7fd2c5c 100644 --- a/lnbits/commands.py +++ b/lnbits/commands.py @@ -11,7 +11,7 @@ from lnbits.settings import settings from .core import db as core_db from .core import migrations as core_migrations -from .core.crud import USER_ID_ALL, get_dbversions, get_inactive_extensions +from .core.crud import get_dbversions, get_inactive_extensions from .core.helpers import migrate_extension_database, run_migration from .db import COCKROACH, POSTGRES, SQLITE from .extension_manger import get_valid_extensions @@ -83,5 +83,5 @@ async def migrate_databases(): async def load_disabled_extension_list() -> None: """Update list of extensions that have been explicitly disabled""" - inactive_extensions = await get_inactive_extensions(user_id=USER_ID_ALL) + inactive_extensions = await get_inactive_extensions() settings.lnbits_disabled_extensions += inactive_extensions diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index 1289c33af..374f9e544 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -11,8 +11,6 @@ from lnbits.settings import AdminSettings, EditableSettings, SuperSettings, sett from . import db from .models import BalanceCheck, Payment, User, Wallet -USER_ID_ALL = "all" - # accounts # -------- @@ -68,6 +66,61 @@ async def get_user(user_id: str, conn: Optional[Connection] = None) -> Optional[ ) +# extensions +# ------- + + +async def add_installed_extension( + *, + ext_id: str, + version, + active: bool, + hash: str, + meta: dict, + conn: Optional[Connection] = None, +) -> None: + await (conn or db).execute( + """ + INSERT INTO installed_extensions (id, version, active, hash, meta) VALUES (?, ?, ?, ?, ?) + ON CONFLICT (id) DO + UPDATE SET (version, active, hash, meta) = (?, ?, ?, ?) + """, + ( + ext_id, + version, + active, + hash, + json.dumps(meta), + version, + active, + hash, + json.dumps(meta), + ), + ) + + +async def update_installed_extension_state( + *, ext_id: str, active: bool, conn: Optional[Connection] = None +) -> None: + await (conn or db).execute( + """ + UPDATE installed_extensions SET active = ? WHERE id = ? + """, + (active, ext_id), + ) + + +async def delete_installed_extension( + *, ext_id: str, conn: Optional[Connection] = None +) -> None: + await (conn or db).execute( + """ + DELETE from installed_extensions WHERE id = ? + """, + (ext_id,), + ) + + async def update_user_extension( *, user_id: str, extension: str, active: bool, conn: Optional[Connection] = None ) -> None: @@ -80,12 +133,10 @@ async def update_user_extension( ) -async def get_inactive_extensions( - *, user_id: str, conn: Optional[Connection] = None -) -> List[str]: +async def get_inactive_extensions(*, conn: Optional[Connection] = None) -> List[str]: inactive_extensions = await (conn or db).fetchall( - """SELECT extension FROM extensions WHERE "user" = ? AND NOT active""", - (user_id,), + """SELECT id FROM installed_extensions WHERE NOT active""", + (), ) return ( [ext[0] for ext in inactive_extensions] if len(inactive_extensions) != 0 else [] diff --git a/lnbits/core/migrations.py b/lnbits/core/migrations.py index 66254d11d..ae24a9481 100644 --- a/lnbits/core/migrations.py +++ b/lnbits/core/migrations.py @@ -269,3 +269,17 @@ async def m008_create_admin_settings_table(db): ); """ ) + + +async def m009_create_installed_extensions_table(db): + await db.execute( + """ + CREATE TABLE IF NOT EXISTS installed_extensions ( + id TEXT PRIMARY KEY, + version INT NOT NULL, + active BOOLEAN DEFAULT false, + hash TEXT NOT NULL, + meta TEXT NOT NULL DEFAULT '{}' + ); + """ + ) diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index f063b2f57..f0efc08d9 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -59,14 +59,14 @@ from lnbits.utils.exchange_rates import ( from .. import core_app, core_app_extra, db from ..crud import ( - USER_ID_ALL, + add_installed_extension, + delete_installed_extension, get_dbversions, get_payments, get_standalone_payment, get_total_balance, get_wallet_for_key, save_balance_check, - update_user_extension, update_wallet, ) from ..services import ( @@ -741,7 +741,13 @@ async def api_install_extension( await migrate_extension_database(extension, db_version) # disable by default - await update_user_extension(user_id=USER_ID_ALL, extension=ext_id, active=False) + await add_installed_extension( + ext_id=ext_id, + version=ext_info.version, + active=False, + hash=hash, + meta=dict(ext_info), + ) settings.lnbits_disabled_extensions += [ext_id] # mount routes for the new version @@ -788,6 +794,7 @@ async def api_uninstall_extension(ext_id: str, user: User = Depends(check_admin) for ext_info in extensions: ext_info.clean_extension_files() + await delete_installed_extension(ext_id=ext_info.id) except Exception as ex: raise HTTPException( diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py index d0987379d..e2c365f73 100644 --- a/lnbits/core/views/generic.py +++ b/lnbits/core/views/generic.py @@ -18,7 +18,6 @@ from lnbits.settings import get_wallet_class, settings from ...extension_manger import InstallableExtension, get_valid_extensions from ..crud import ( - USER_ID_ALL, create_account, create_wallet, delete_wallet, @@ -26,6 +25,7 @@ from ..crud import ( get_inactive_extensions, get_user, save_balance_notify, + update_installed_extension_state, update_user_extension, ) from ..services import pay_invoice, redeem_lnurl_withdraw @@ -89,10 +89,15 @@ async def extensions_install( settings.lnbits_disabled_extensions = list( filter(lambda e: e != activate, settings.lnbits_disabled_extensions) ) - await toggle_extension(activate, deactivate, USER_ID_ALL) + + ext_id = activate or deactivate + if ext_id: + await update_installed_extension_state( + ext_id=ext_id, active=activate != None + ) installed_extensions = list(map(lambda e: e.code, get_valid_extensions(True))) - inactive_extensions = await get_inactive_extensions(user_id=USER_ID_ALL) + inactive_extensions = await get_inactive_extensions() extensions = list( map( lambda ext: { diff --git a/lnbits/extension_manger.py b/lnbits/extension_manger.py index ceecffc5e..9debda701 100644 --- a/lnbits/extension_manger.py +++ b/lnbits/extension_manger.py @@ -12,6 +12,7 @@ import httpx from fastapi.exceptions import HTTPException from fastapi.responses import JSONResponse from loguru import logger +from pydantic import BaseModel from starlette.types import ASGIApp, Receive, Scope, Send from lnbits.settings import settings @@ -101,7 +102,7 @@ class ExtensionManager: return output -class InstallableExtension(NamedTuple): +class InstallableExtension(BaseModel): id: str name: str archive: str