From f6c8a308dc30e2362be55d361a90dd21b4e6fced Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Wed, 9 Apr 2025 15:01:34 +0300 Subject: [PATCH] feat: create new user from the command line (#3098) --- lnbits/commands.py | 51 +++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/lnbits/commands.py b/lnbits/commands.py index 439b61641..d6373fd0b 100644 --- a/lnbits/commands.py +++ b/lnbits/commands.py @@ -5,6 +5,7 @@ import time from functools import wraps from pathlib import Path from typing import Optional +from uuid import uuid4 import click import httpx @@ -27,13 +28,13 @@ from lnbits.core.crud import ( update_payment, ) from lnbits.core.helpers import is_valid_url, migrate_databases -from lnbits.core.models import Payment, PaymentState +from lnbits.core.models import Account, Payment, PaymentState from lnbits.core.models.extensions import ( CreateExtension, ExtensionRelease, InstallableExtension, ) -from lnbits.core.services import check_admin_settings +from lnbits.core.services import check_admin_settings, create_user_account_no_ckeck from lnbits.core.views.extension_api import ( api_install_extension, api_uninstall_extension, @@ -64,6 +65,13 @@ def db(): """ +@lnbits_cli.group() +def users(): + """ + Users related commands + """ + + @lnbits_cli.group() def extensions(): """ @@ -109,7 +117,7 @@ async def delete_settings(): """Deletes the settings""" async with core_db.connect() as conn: - await conn.execute("DELETE from settings") + await conn.execute("DELETE from system_settings") @db.command("migrate") @@ -180,17 +188,6 @@ async def database_revert_payment(checking_id: str): click.echo(f"Payment '{checking_id}' marked as pending.") -@db.command("cleanup-accounts") -@click.argument("days", type=int, required=False) -@coro -async def database_cleanup_accounts(days: Optional[int] = None): - """Delete all accounts that have no wallets""" - async with core_db.connect() as conn: - delta = days or settings.cleanup_wallets_days - delta = delta * 24 * 60 * 60 - await delete_accounts_no_wallets(delta, conn) - - @db.command("check-payments") @click.option("-d", "--days", help="Maximum age of payments in days.") @click.option("-l", "--limit", help="Maximum number of payments to be checked.") @@ -271,6 +268,32 @@ async def check_invalid_payments( click.echo(" ".join([w, str(data[0]), str(data[1] / 1000).ljust(10)])) +@users.command("new") +@click.option("-u", "--username", required=True, help="Username.") +@click.option("-p", "--password", required=True, help="Password.") +@coro +async def create_user(username: str, password: str): + """Create a new user bypassing the system 'new_accounts_allowed' rules""" + account = Account( + id=uuid4().hex, + username=username, + ) + account.hash_password(password) + user = await create_user_account_no_ckeck(account) + click.echo(f"User '{user.username}' created. Id: '{user.id}'") + + +@users.command("cleanup-accounts") +@click.argument("days", type=int, required=False) +@coro +async def database_cleanup_accounts(days: Optional[int] = None): + """Delete all accounts that have no wallets""" + async with core_db.connect() as conn: + delta = days or settings.cleanup_wallets_days + delta = delta * 24 * 60 * 60 + await delete_accounts_no_wallets(delta, conn) + + @extensions.command("list") @coro async def extensions_list():