feat: allow creating/update user with nostr npub1 pubkey (#3298)
This commit is contained in:
parent
5ba06d42d0
commit
ef371e303c
2 changed files with 94 additions and 2 deletions
|
|
@ -47,6 +47,7 @@ from lnbits.helpers import (
|
||||||
)
|
)
|
||||||
from lnbits.settings import EditableSettings, settings
|
from lnbits.settings import EditableSettings, settings
|
||||||
from lnbits.utils.exchange_rates import allowed_currencies
|
from lnbits.utils.exchange_rates import allowed_currencies
|
||||||
|
from lnbits.utils.nostr import normalize_public_key
|
||||||
|
|
||||||
users_router = APIRouter(
|
users_router = APIRouter(
|
||||||
prefix="/users/api/v1", dependencies=[Depends(check_admin)], tags=["Users"]
|
prefix="/users/api/v1", dependencies=[Depends(check_admin)], tags=["Users"]
|
||||||
|
|
@ -94,6 +95,9 @@ async def api_create_user(data: CreateUser) -> CreateUser:
|
||||||
data.extra = data.extra or UserExtra()
|
data.extra = data.extra or UserExtra()
|
||||||
data.extra.provider = data.extra.provider or "lnbits"
|
data.extra.provider = data.extra.provider or "lnbits"
|
||||||
|
|
||||||
|
if data.pubkey:
|
||||||
|
data.pubkey = normalize_public_key(data.pubkey)
|
||||||
|
|
||||||
account = Account(
|
account = Account(
|
||||||
id=uuid4().hex,
|
id=uuid4().hex,
|
||||||
username=data.username,
|
username=data.username,
|
||||||
|
|
@ -127,6 +131,9 @@ async def api_update_user(
|
||||||
HTTPStatus.BAD_REQUEST, "Use 'reset password' functionality."
|
HTTPStatus.BAD_REQUEST, "Use 'reset password' functionality."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if data.pubkey:
|
||||||
|
data.pubkey = normalize_public_key(data.pubkey)
|
||||||
|
|
||||||
account = Account(
|
account = Account(
|
||||||
id=user_id,
|
id=user_id,
|
||||||
username=data.username,
|
username=data.username,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ from httpx import AsyncClient
|
||||||
|
|
||||||
from lnbits.core.models.users import User
|
from lnbits.core.models.users import User
|
||||||
from lnbits.settings import Settings
|
from lnbits.settings import Settings
|
||||||
from lnbits.utils.nostr import generate_keypair
|
from lnbits.utils.nostr import generate_keypair, hex_to_npub
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.anyio
|
@pytest.mark.anyio
|
||||||
|
|
@ -234,7 +234,6 @@ async def test_update_user_success(http_client: AsyncClient, superuser_token):
|
||||||
async def test_update_bad_external_id(
|
async def test_update_bad_external_id(
|
||||||
http_client: AsyncClient, user_alan: User, superuser_token
|
http_client: AsyncClient, user_alan: User, superuser_token
|
||||||
):
|
):
|
||||||
|
|
||||||
update_data = {"id": user_alan.id, "external_id": "external 1234"}
|
update_data = {"id": user_alan.id, "external_id": "external 1234"}
|
||||||
resp = await http_client.put(
|
resp = await http_client.put(
|
||||||
f"/users/api/v1/user/{user_alan.id}",
|
f"/users/api/v1/user/{user_alan.id}",
|
||||||
|
|
@ -380,3 +379,89 @@ async def test_update_superuser_only_allowed_by_superuser(
|
||||||
)
|
)
|
||||||
|
|
||||||
assert resp.json()["detail"] == "Action only allowed for super user."
|
assert resp.json()["detail"] == "Action only allowed for super user."
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.anyio
|
||||||
|
async def test_create_user_with_npub(http_client: AsyncClient, superuser_token):
|
||||||
|
tiny_id = shortuuid.uuid()[:8]
|
||||||
|
_, pubkey = generate_keypair()
|
||||||
|
data = {
|
||||||
|
"username": f"user_{tiny_id}",
|
||||||
|
"password": "secret1234",
|
||||||
|
"password_repeat": "secret1234",
|
||||||
|
"email": f"user_{tiny_id}@lnbits.com",
|
||||||
|
"pubkey": hex_to_npub(pubkey),
|
||||||
|
}
|
||||||
|
create_resp = await http_client.post(
|
||||||
|
"/users/api/v1/user",
|
||||||
|
json=data,
|
||||||
|
headers={"Authorization": f"Bearer {superuser_token}"},
|
||||||
|
)
|
||||||
|
assert create_resp.status_code == 200
|
||||||
|
assert create_resp.json()["pubkey"] == pubkey
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.anyio
|
||||||
|
async def test_update_user_npub_success(http_client: AsyncClient, superuser_token):
|
||||||
|
# Create a user first
|
||||||
|
tiny_id = shortuuid.uuid()[:8]
|
||||||
|
data = {
|
||||||
|
"username": f"update_{tiny_id}",
|
||||||
|
"password": "secret1234",
|
||||||
|
"password_repeat": "secret1234",
|
||||||
|
"email": f"update_{tiny_id}@lnbits.com",
|
||||||
|
}
|
||||||
|
create_resp = await http_client.post(
|
||||||
|
"/users/api/v1/user",
|
||||||
|
json=data,
|
||||||
|
headers={"Authorization": f"Bearer {superuser_token}"},
|
||||||
|
)
|
||||||
|
assert create_resp.status_code == 200
|
||||||
|
user_id = create_resp.json()["id"]
|
||||||
|
|
||||||
|
# Update the user
|
||||||
|
_, pubkey = generate_keypair()
|
||||||
|
update_data = {
|
||||||
|
"id": user_id,
|
||||||
|
"username": f"updated_{tiny_id}",
|
||||||
|
"email": f"updated_{tiny_id}@lnbits.com",
|
||||||
|
"pubkey": hex_to_npub(pubkey),
|
||||||
|
"extra": {"provider": "lnbits"},
|
||||||
|
"extensions": [],
|
||||||
|
}
|
||||||
|
resp = await http_client.put(
|
||||||
|
f"/users/api/v1/user/{user_id}",
|
||||||
|
json=update_data,
|
||||||
|
headers={"Authorization": f"Bearer {superuser_token}"},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert resp.json()["username"] == update_data["username"]
|
||||||
|
assert resp.json()["email"] == update_data["email"]
|
||||||
|
assert resp.json()["pubkey"] == pubkey
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.anyio
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"invalid_pubkey",
|
||||||
|
[
|
||||||
|
"npub1flrz7qu87n8y04jwy6r74z44pczcwaesumth08uxrusv4sm7efs83zq8z",
|
||||||
|
"4fc62f0387f4ce47d64e2687ea89f5a8702c3bb98736bbbcf30f906561bf653",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_create_user_invalid_npub(
|
||||||
|
http_client: AsyncClient, superuser_token, invalid_pubkey
|
||||||
|
):
|
||||||
|
tiny_id = shortuuid.uuid()[:8]
|
||||||
|
data = {
|
||||||
|
"username": f"user_{tiny_id}",
|
||||||
|
"password": "secret1234",
|
||||||
|
"password_repeat": "secret1234",
|
||||||
|
"email": f"user_{tiny_id}@lnbits.com",
|
||||||
|
"pubkey": invalid_pubkey,
|
||||||
|
}
|
||||||
|
create_resp = await http_client.post(
|
||||||
|
"/users/api/v1/user",
|
||||||
|
json=data,
|
||||||
|
headers={"Authorization": f"Bearer {superuser_token}"},
|
||||||
|
)
|
||||||
|
assert create_resp.status_code == 400
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue