Merge pull request #45 from lnbits/refactor-crud

refactor: do not validate username inside crud
This commit is contained in:
Arc 2024-04-01 07:55:43 +01:00 committed by dni ⚡
commit c43156b86f
No known key found for this signature in database
GPG key ID: 886317704CC4E618
2 changed files with 29 additions and 15 deletions

19
crud.py
View file

@ -5,7 +5,6 @@ from lnbits.helpers import urlsafe_short_hash, insert_query, update_query
from . import db from . import db
from .models import CreatePayLinkData, LnurlpSettings, PayLink from .models import CreatePayLinkData, LnurlpSettings, PayLink
from .nostr.key import PrivateKey from .nostr.key import PrivateKey
from .services import check_lnaddress_format
async def get_or_create_lnurlp_settings() -> LnurlpSettings: async def get_or_create_lnurlp_settings() -> LnurlpSettings:
@ -33,21 +32,14 @@ async def delete_lnurlp_settings() -> None:
await db.execute("DELETE FROM lnurlp.settings") await db.execute("DELETE FROM lnurlp.settings")
async def check_lnaddress_not_exists(username: str) -> bool: async def get_pay_link_by_username(username: str) -> Optional[PayLink]:
# check if lnaddress username exists in the database when creating a new entry row = await db.fetchone(
row = await db.fetchall( "SELECT * FROM lnurlp.pay_links WHERE username = ?", (username,)
"SELECT username FROM lnurlp.pay_links WHERE username = ?", (username,)
) )
if row: return PayLink.from_row(row) if row else None
raise Exception("Username already exists. Try a different one.")
else:
return True
async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink: async def create_pay_link(data: CreatePayLinkData, wallet_id: str) -> PayLink:
if data.username:
await check_lnaddress_format(data.username)
await check_lnaddress_not_exists(data.username)
link_id = urlsafe_short_hash()[:6] link_id = urlsafe_short_hash()[:6]
@ -128,9 +120,6 @@ async def get_pay_links(wallet_ids: Union[str, List[str]]) -> List[PayLink]:
async def update_pay_link(link_id: str, **kwargs) -> Optional[PayLink]: async def update_pay_link(link_id: str, **kwargs) -> Optional[PayLink]:
if "username" in kwargs and len(kwargs["username"] or "") > 0:
await check_lnaddress_format(kwargs["username"])
await check_lnaddress_not_exists(kwargs["username"])
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute( await db.execute(

View file

@ -17,10 +17,12 @@ from .crud import (
get_address_data, get_address_data,
get_or_create_lnurlp_settings, get_or_create_lnurlp_settings,
get_pay_link, get_pay_link,
get_pay_link_by_username,
get_pay_links, get_pay_links,
update_lnurlp_settings, update_lnurlp_settings,
update_pay_link, update_pay_link,
) )
from .services import check_lnaddress_format
from .helpers import parse_nostr_private_key from .helpers import parse_nostr_private_key
from .lnurl import api_lnurl_response from .lnurl import api_lnurl_response
from .models import CreatePayLinkData, LnurlpSettings from .models import CreatePayLinkData, LnurlpSettings
@ -83,6 +85,14 @@ async def api_link_retrieve(
return {**link.dict(), **{"lnurl": link.lnurl(r)}} return {**link.dict(), **{"lnurl": link.lnurl(r)}}
async def check_username_exists(username: str):
prev_link = await get_pay_link_by_username(username)
if prev_link:
raise HTTPException(
detail="Username already taken.",
status_code=HTTPStatus.BAD_REQUEST,
)
@lnurlp_ext.post("/api/v1/links", status_code=HTTPStatus.CREATED) @lnurlp_ext.post("/api/v1/links", status_code=HTTPStatus.CREATED)
@lnurlp_ext.put("/api/v1/links/{link_id}", status_code=HTTPStatus.OK) @lnurlp_ext.put("/api/v1/links/{link_id}", status_code=HTTPStatus.OK)
async def api_link_create_or_update( async def api_link_create_or_update(
@ -133,6 +143,14 @@ async def api_link_create_or_update(
status_code=HTTPStatus.BAD_REQUEST, status_code=HTTPStatus.BAD_REQUEST,
) )
if data.username:
try:
await check_lnaddress_format(data.username)
except AssertionError as ex:
raise HTTPException(
detail=f"Invalid username: {ex}", status_code=HTTPStatus.BAD_REQUEST
)
if link_id: if link_id:
link = await get_pay_link(link_id) link = await get_pay_link(link_id)
@ -146,9 +164,16 @@ async def api_link_create_or_update(
detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN detail="Not your pay link.", status_code=HTTPStatus.FORBIDDEN
) )
if data.username and data.username != link.username:
await check_username_exists(data.username)
link = await update_pay_link(**data.dict(), link_id=link_id) link = await update_pay_link(**data.dict(), link_id=link_id)
else: else:
if data.username:
await check_username_exists(data.username)
link = await create_pay_link(data, wallet_id=wallet.wallet.id) link = await create_pay_link(data, wallet_id=wallet.wallet.id)
assert link assert link
return {**link.dict(), "lnurl": link.lnurl(request)} return {**link.dict(), "lnurl": link.lnurl(request)}