init
This commit is contained in:
@@ -152,6 +152,8 @@ async def test_extension_api_install_details_and_release_endpoints(mocker):
|
||||
short_description="Config",
|
||||
min_lnbits_version="0.1.0",
|
||||
max_lnbits_version=None,
|
||||
admin_only=True,
|
||||
super_user_only=True,
|
||||
)
|
||||
mocker.patch.object(
|
||||
ExtensionConfig,
|
||||
@@ -160,6 +162,8 @@ async def test_extension_api_install_details_and_release_endpoints(mocker):
|
||||
)
|
||||
release_info = await get_extension_release("org", ext_id, "v1.0.0")
|
||||
assert release_info["is_version_compatible"] is True
|
||||
assert release_info["admin_only"] is True
|
||||
assert release_info["super_user_only"] is True
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
@@ -258,6 +262,8 @@ async def test_extension_api_pay_to_enable_and_catalog_views(mocker, admin_user)
|
||||
catalog_entry = make_installable_extension(
|
||||
ext_id,
|
||||
pay_to_enable=PayToEnableInfo(required=True, amount=21, wallet=admin_wallet.id),
|
||||
admin_only=True,
|
||||
super_user_only=True,
|
||||
)
|
||||
mocker.patch.object(
|
||||
InstallableExtension,
|
||||
@@ -267,6 +273,8 @@ async def test_extension_api_pay_to_enable_and_catalog_views(mocker, admin_user)
|
||||
catalog = await extensions(AccountId(id=regular_user.id))
|
||||
catalog_item = next(item for item in catalog if item["id"] == ext_id)
|
||||
assert catalog_item["payToEnable"]["wallet"] is None
|
||||
assert catalog_item["isAdminOnly"] is True
|
||||
assert catalog_item["isSuperUserOnly"] is True
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
@@ -428,3 +436,31 @@ async def test_extension_api_review_endpoints(mocker):
|
||||
CreateExtensionReview(tag=ext_id, name="Alice", rating=900, comment="Great")
|
||||
)
|
||||
assert payment_request.payment_hash.startswith("hash_")
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_extension_api_enable_rejects_admin_and_super_only_extensions(
|
||||
admin_user,
|
||||
):
|
||||
regular_user = await create_user_account(
|
||||
Account(
|
||||
id=uuid4().hex,
|
||||
username=f"user_{uuid4().hex[:8]}",
|
||||
email=f"user_{uuid4().hex[:8]}@lnbits.com",
|
||||
)
|
||||
)
|
||||
admin_only_ext = f"admin_{uuid4().hex[:8]}"
|
||||
super_only_ext = f"super_{uuid4().hex[:8]}"
|
||||
|
||||
await create_installed_extension(
|
||||
make_installable_extension(admin_only_ext, admin_only=True)
|
||||
)
|
||||
await create_installed_extension(
|
||||
make_installable_extension(super_only_ext, super_user_only=True)
|
||||
)
|
||||
|
||||
with pytest.raises(HTTPException, match="User not authorized"):
|
||||
await api_enable_extension(admin_only_ext, AccountId(id=regular_user.id))
|
||||
|
||||
with pytest.raises(HTTPException, match="User not authorized"):
|
||||
await api_enable_extension(super_only_ext, AccountId(id=admin_user.id))
|
||||
|
||||
@@ -141,9 +141,13 @@ def make_installable_extension(
|
||||
pay_to_enable: PayToEnableInfo | None = None,
|
||||
dependencies: list[str] | None = None,
|
||||
payments: list[ReleasePaymentInfo] | None = None,
|
||||
admin_only: bool = False,
|
||||
super_user_only: bool = False,
|
||||
) -> InstallableExtension:
|
||||
release = make_extension_release(ext_id, version)
|
||||
release.is_version_compatible = compatible
|
||||
release.admin_only = admin_only
|
||||
release.super_user_only = super_user_only
|
||||
return InstallableExtension(
|
||||
id=ext_id,
|
||||
name=f"Extension {ext_id}",
|
||||
@@ -156,6 +160,8 @@ def make_installable_extension(
|
||||
pay_to_enable=pay_to_enable,
|
||||
dependencies=dependencies or [],
|
||||
payments=payments or [],
|
||||
admin_only=admin_only,
|
||||
super_user_only=super_user_only,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ from fastapi.exceptions import HTTPException
|
||||
from httpx import AsyncClient
|
||||
from pydantic.types import UUID4
|
||||
|
||||
from lnbits.core.crud.extensions import create_installed_extension
|
||||
from lnbits.core.crud.users import delete_account
|
||||
from lnbits.core.models import User
|
||||
from lnbits.core.models.users import AccessTokenPayload
|
||||
@@ -18,10 +19,12 @@ from lnbits.decorators import (
|
||||
check_extension_builder,
|
||||
check_first_install,
|
||||
check_user_exists,
|
||||
check_user_extension_access,
|
||||
optional_user_id,
|
||||
)
|
||||
from lnbits.helpers import create_access_token
|
||||
from lnbits.settings import AuthMethods, Settings, settings
|
||||
from tests.helpers import make_installable_extension
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
@@ -225,3 +228,35 @@ async def test_check_extension_builder_requires_admin_when_disabled_for_users(
|
||||
admin_user = user_alan.copy(deep=True)
|
||||
admin_user.admin = True
|
||||
await check_extension_builder(admin_user)
|
||||
|
||||
|
||||
@pytest.mark.anyio
|
||||
async def test_check_user_extension_access_honors_extension_metadata(
|
||||
settings: Settings, user_alan: User, admin_user: User
|
||||
):
|
||||
admin_only_ext = f"admin_{uuid4().hex[:8]}"
|
||||
super_only_ext = f"super_{uuid4().hex[:8]}"
|
||||
|
||||
await create_installed_extension(
|
||||
make_installable_extension(admin_only_ext, admin_only=True)
|
||||
)
|
||||
await create_installed_extension(
|
||||
make_installable_extension(super_only_ext, super_user_only=True)
|
||||
)
|
||||
|
||||
regular_status = await check_user_extension_access(user_alan.id, admin_only_ext)
|
||||
assert regular_status.success is False
|
||||
|
||||
admin_status = await check_user_extension_access(admin_user.id, admin_only_ext)
|
||||
assert admin_status.success is True
|
||||
|
||||
admin_super_status = await check_user_extension_access(admin_user.id, super_only_ext)
|
||||
assert admin_super_status.success is False
|
||||
|
||||
previous_super_user = settings.super_user
|
||||
settings.super_user = admin_user.id
|
||||
try:
|
||||
super_status = await check_user_extension_access(admin_user.id, super_only_ext)
|
||||
assert super_status.success is True
|
||||
finally:
|
||||
settings.super_user = previous_super_user
|
||||
|
||||
Reference in New Issue
Block a user