Create super user account if it does not exist (#1688)

* fix: temp create account for `super_user_id` if missing

* chore: remove dumb import

* refactor: move logic outside `crud`

* feat: add uuid4 conversion

* fix: require valid string in .env file

* fix: update the `settings.super_user` value in case or normalisation for UUID4

* fix: allow long super_user

* chore: code format

* fix: add UI redirect with the normalized user

* fix: normalize `super_user` up one level

* fix: should normalize user in non-ui mode also
This commit is contained in:
Vlad Stan 2023-05-09 11:22:19 +03:00 committed by GitHub
parent 132d8a9320
commit 67d8b67ee5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 5 deletions

View File

@ -2,7 +2,7 @@ import datetime
import json import json
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from urllib.parse import urlparse from urllib.parse import urlparse
from uuid import uuid4 from uuid import UUID, uuid4
import shortuuid import shortuuid
@ -18,8 +18,15 @@ from .models import BalanceCheck, Payment, PaymentFilters, TinyURL, User, Wallet
# -------- # --------
async def create_account(conn: Optional[Connection] = None) -> User: async def create_account(
user_id = uuid4().hex conn: Optional[Connection] = None, user_id: Optional[str] = None
) -> User:
if user_id:
user_uuid4 = UUID(hex=user_id, version=4)
assert user_uuid4.hex == user_id, "User ID is not valid UUID4 hex string"
else:
user_id = uuid4().hex
await (conn or db).execute("INSERT INTO accounts (id) VALUES (?)", (user_id,)) await (conn or db).execute("INSERT INTO accounts (id) VALUES (?)", (user_id,))
new_account = await get_account(user_id=user_id, conn=conn) new_account = await get_account(user_id=user_id, conn=conn)

View File

@ -1,6 +1,7 @@
import importlib import importlib
import re import re
from typing import Any from typing import Any
from uuid import UUID
import httpx import httpx
from loguru import logger from loguru import logger
@ -63,3 +64,14 @@ async def stop_extension_background_work(ext_id: str, user: str):
url = f"https://{settings.host}:{settings.port}/{ext_id}/api/v1?usr={user}" url = f"https://{settings.host}:{settings.port}/{ext_id}/api/v1?usr={user}"
except Exception as ex: except Exception as ex:
logger.warning(ex) logger.warning(ex)
def to_valid_user_id(user_id: str) -> UUID:
if len(user_id) < 32:
raise ValueError("User ID must have at least 128 bits")
try:
int(user_id, 16)
except:
raise ValueError("Invalid hex string for User ID.")
return UUID(hex=user_id[:32], version=4)

View File

@ -43,6 +43,7 @@ from .crud import (
update_payment_status, update_payment_status,
update_super_user, update_super_user,
) )
from .helpers import to_valid_user_id
from .models import Payment from .models import Payment
@ -437,6 +438,9 @@ async def update_wallet_balance(wallet_id: str, amount: int):
async def check_admin_settings(): async def check_admin_settings():
if settings.super_user:
settings.super_user = to_valid_user_id(settings.super_user).hex
if settings.lnbits_admin_ui: if settings.lnbits_admin_ui:
settings_db = await get_super_settings() settings_db = await get_super_settings()
if not settings_db: if not settings_db:
@ -488,8 +492,7 @@ async def init_admin_settings(super_user: Optional[str] = None) -> SuperSettings
if super_user: if super_user:
account = await get_account(super_user) account = await get_account(super_user)
if not account: if not account:
account = await create_account() account = await create_account(user_id=super_user)
super_user = account.id
if not account.wallets or len(account.wallets) == 0: if not account.wallets or len(account.wallets) == 0:
await create_wallet(user_id=account.id) await create_wallet(user_id=account.id)

View File

@ -11,6 +11,7 @@ from pydantic.types import UUID4
from starlette.responses import HTMLResponse, JSONResponse from starlette.responses import HTMLResponse, JSONResponse
from lnbits.core import db from lnbits.core import db
from lnbits.core.helpers import to_valid_user_id
from lnbits.core.models import User from lnbits.core.models import User
from lnbits.decorators import check_admin, check_user_exists from lnbits.decorators import check_admin, check_user_exists
from lnbits.helpers import template_renderer, url_for from lnbits.helpers import template_renderer, url_for
@ -414,6 +415,15 @@ async def index(request: Request, user: User = Depends(check_admin)):
) )
@core_html_routes.get("/uuidv4/{hex_value}")
async def hex_to_uuid4(hex_value: str):
try:
user_id = to_valid_user_id(hex_value).hex
return RedirectResponse(url=f"/wallet?usr={user_id}")
except Exception as e:
raise HTTPException(status_code=HTTPStatus.BAD_REQUEST, detail=str(e))
async def toggle_extension(extension_to_enable, extension_to_disable, user_id): async def toggle_extension(extension_to_enable, extension_to_disable, user_id):
if extension_to_enable and extension_to_disable: if extension_to_enable and extension_to_disable:
raise HTTPException( raise HTTPException(