refactor: use decorators for disabled endpoints (#3481)

This commit is contained in:
dni ⚡ 2025-11-10 09:33:16 +01:00 committed by GitHub
parent b54eedee84
commit 6bac34fc6b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 51 additions and 57 deletions

View file

@ -1,9 +1,8 @@
import os
import shutil
from hashlib import sha256
from http import HTTPStatus
from fastapi import APIRouter, Depends, HTTPException
from fastapi import APIRouter, Depends
from fastapi.responses import FileResponse
from lnbits.core.models import (
@ -28,9 +27,9 @@ from lnbits.core.services.extensions_builder import (
)
from lnbits.decorators import (
check_admin,
check_extension_builder,
check_user_exists,
)
from lnbits.settings import settings
from ..crud import (
create_user_extension,
@ -47,19 +46,12 @@ extension_builder_router = APIRouter(
@extension_builder_router.post(
"/zip",
summary="Build and download extension zip.",
dependencies=[Depends(check_extension_builder)],
description="""
This endpoint generates a zip file for the extension based on the provided data.
""",
)
async def api_build_extension(
data: ExtensionData,
user: User = Depends(check_user_exists),
) -> FileResponse:
if not settings.lnbits_extensions_builder_activate_non_admins and not user.admin:
raise HTTPException(
HTTPStatus.FORBIDDEN,
"Extension Builder is disabled for non admin users.",
)
async def api_build_extension(data: ExtensionData) -> FileResponse:
stub_ext_id = "extension_builder_stub" # todo: do not hardcode, fetch from manifest
release, build_dir = await build_extension_from_data(data, stub_ext_id)
@ -132,16 +124,12 @@ async def api_deploy_extension(
@extension_builder_router.post(
"/preview",
summary="Build and preview the extension ui.",
dependencies=[Depends(check_extension_builder)],
)
async def api_preview_extension(
data: ExtensionData,
user: User = Depends(check_user_exists),
) -> SimpleStatus:
if not settings.lnbits_extensions_builder_activate_non_admins and not user.admin:
raise HTTPException(
HTTPStatus.FORBIDDEN,
"Extension Builder is disabled for non admin users.",
)
stub_ext_id = "extension_builder_stub"
working_dir_name = "preview_" + sha256(user.id.encode("utf-8")).hexdigest()
await build_extension_from_data(data, stub_ext_id, working_dir_name)

View file

@ -17,7 +17,12 @@ from lnbits.core.models import User
from lnbits.core.models.extensions import ExtensionMeta, InstallableExtension
from lnbits.core.services import create_invoice, create_user_account
from lnbits.core.services.extensions import get_valid_extensions
from lnbits.decorators import check_admin, check_user_exists
from lnbits.decorators import (
check_admin,
check_admin_ui,
check_extension_builder,
check_user_exists,
)
from lnbits.helpers import check_callback_url, template_renderer
from lnbits.settings import settings
@ -209,14 +214,13 @@ async def extensions(request: Request, user: User = Depends(check_user_exists)):
@generic_router.get(
"/extensions/builder", name="extensions builder", response_class=HTMLResponse
)
async def extensions_builder(request: Request, user: User = Depends(check_user_exists)):
if not settings.lnbits_extensions_builder_activate_non_admins and not user.admin:
raise HTTPException(
HTTPStatus.FORBIDDEN,
"Extension Builder is disabled for non admin users.",
"/extensions/builder",
name="extensions builder",
dependencies=[Depends(check_extension_builder)],
)
async def extensions_builder(
request: Request, user: User = Depends(check_user_exists)
) -> HTMLResponse:
return template_renderer().TemplateResponse(
request,
"core/extensions_builder.html",
@ -230,19 +234,14 @@ async def extensions_builder(request: Request, user: User = Depends(check_user_e
@generic_router.get(
"/extensions/builder/preview/{ext_id}",
name="extensions builder",
response_class=HTMLResponse,
dependencies=[Depends(check_extension_builder)],
)
async def extensions_builder_preview(
request: Request,
ext_id: str,
page_name: str | None = None,
user: User = Depends(check_user_exists),
):
if not settings.lnbits_extensions_builder_activate_non_admins and not user.admin:
raise HTTPException(
HTTPStatus.FORBIDDEN,
"Extension Builder is disabled for non admin users.",
)
) -> HTMLResponse:
working_dir_name = "preview_" + sha256(user.id.encode("utf-8")).hexdigest()
html_file_name = "index.html"
if page_name == "public_page":
@ -383,10 +382,19 @@ async def manifest(request: Request, usr: str):
}
@generic_router.get("/payments", response_class=HTMLResponse)
@generic_router.get("/wallets", response_class=HTMLResponse)
@generic_router.get("/account", response_class=HTMLResponse)
async def index(request: Request, user: User = Depends(check_user_exists)):
admin_ui_checks = [Depends(check_admin), Depends(check_admin_ui)]
@generic_router.get("/payments")
@generic_router.get("/wallets")
@generic_router.get("/account")
@generic_router.get("/users", dependencies=admin_ui_checks)
@generic_router.get("/audit", dependencies=admin_ui_checks)
@generic_router.get("/node", dependencies=admin_ui_checks)
@generic_router.get("/admin", dependencies=admin_ui_checks)
async def index(
request: Request, user: User = Depends(check_user_exists)
) -> HTMLResponse:
return template_renderer().TemplateResponse(
request,
"index.html",
@ -396,27 +404,8 @@ async def index(request: Request, user: User = Depends(check_user_exists)):
)
@generic_router.get("/users", response_class=HTMLResponse)
@generic_router.get("/audit", response_class=HTMLResponse)
@generic_router.get("/node", response_class=HTMLResponse)
@generic_router.get("/admin", response_class=HTMLResponse)
async def index_admin(request: Request, admin: User = Depends(check_admin)):
if not settings.lnbits_admin_ui:
raise HTTPException(
status_code=HTTPStatus.SERVICE_UNAVAILABLE, detail="Admin UI is disabled."
)
return template_renderer().TemplateResponse(
request,
"index.html",
{
"user": admin.json(),
},
)
@generic_router.get("/node/public", response_class=HTMLResponse)
async def index_public(request: Request):
@generic_router.get("/node/public")
async def index_public(request: Request) -> HTMLResponse:
return template_renderer().TemplateResponse(request, "index_public.html")

View file

@ -359,3 +359,20 @@ def url_for_interceptor(original_method):
# Upgraded extensions modify the path.
# This interceptor ensures that the path is normalized.
Request.url_for = url_for_interceptor(Request.url_for) # type: ignore[method-assign]
async def check_admin_ui() -> None:
if not settings.lnbits_admin_ui:
raise HTTPException(
status_code=HTTPStatus.SERVICE_UNAVAILABLE, detail="Admin UI is disabled."
)
async def check_extension_builder(
user: Annotated[User, Depends(check_user_exists)],
) -> None:
if not settings.lnbits_extensions_builder_activate_non_admins and not user.admin:
raise HTTPException(
HTTPStatus.FORBIDDEN,
"Extension Builder is disabled for non admin users.",
)