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
from typing import Any, Dict, List, Optional
from urllib.parse import urlparse
from uuid import uuid4
from uuid import UUID, uuid4
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(
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,))
new_account = await get_account(user_id=user_id, conn=conn)

View File

@ -1,6 +1,7 @@
import importlib
import re
from typing import Any
from uuid import UUID
import httpx
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}"
except Exception as 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_super_user,
)
from .helpers import to_valid_user_id
from .models import Payment
@ -437,6 +438,9 @@ async def update_wallet_balance(wallet_id: str, amount: int):
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:
settings_db = await get_super_settings()
if not settings_db:
@ -488,8 +492,7 @@ async def init_admin_settings(super_user: Optional[str] = None) -> SuperSettings
if super_user:
account = await get_account(super_user)
if not account:
account = await create_account()
super_user = account.id
account = await create_account(user_id=super_user)
if not account.wallets or len(account.wallets) == 0:
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 lnbits.core import db
from lnbits.core.helpers import to_valid_user_id
from lnbits.core.models import User
from lnbits.decorators import check_admin, check_user_exists
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):
if extension_to_enable and extension_to_disable:
raise HTTPException(