lnbits-legend/lnbits/extensions/boltcards/crud.py

173 lines
4.2 KiB
Python
Raw Normal View History

2022-08-14 23:52:55 +02:00
import secrets
2022-06-13 21:08:06 +02:00
from typing import List, Optional, Union
2022-07-15 16:43:06 +02:00
2022-06-13 21:08:06 +02:00
from lnbits.helpers import urlsafe_short_hash
from . import db
2022-06-21 18:03:20 +02:00
from .models import Card, CreateCardData, Hit
2022-06-13 21:08:06 +02:00
2022-07-15 16:43:06 +02:00
async def create_card(data: CreateCardData, wallet_id: str) -> Card:
2022-06-13 21:08:06 +02:00
card_id = urlsafe_short_hash()
await db.execute(
"""
INSERT INTO boltcards.cards (
id,
wallet,
card_name,
uid,
counter,
withdraw,
2022-08-14 23:52:55 +02:00
k0,
k1,
k2,
otp
2022-06-13 21:08:06 +02:00
)
2022-08-14 23:52:55 +02:00
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2022-06-13 21:08:06 +02:00
""",
(
card_id,
wallet_id,
data.card_name,
2022-08-21 09:46:18 -06:00
data.uid.upper(),
2022-06-13 21:08:06 +02:00
data.counter,
data.withdraw,
2022-08-14 23:52:55 +02:00
data.k0,
data.k1,
data.k2,
secrets.token_hex(16),
2022-06-13 21:08:06 +02:00
),
)
2022-08-14 23:52:55 +02:00
card = await get_card(card_id)
2022-06-21 18:03:20 +02:00
assert card, "Newly created card couldn't be retrieved"
return card
2022-06-13 21:08:06 +02:00
2022-07-15 16:43:06 +02:00
2022-06-13 21:08:06 +02:00
async def update_card(card_id: str, **kwargs) -> Optional[Card]:
if "is_unique" in kwargs:
kwargs["is_unique"] = int(kwargs["is_unique"])
2022-08-21 09:46:18 -06:00
if "uid" in kwargs:
kwargs["uid"] = kwargs["uid"].upper()
2022-06-13 21:08:06 +02:00
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
await db.execute(
f"UPDATE boltcards.cards SET {q} WHERE id = ?",
(*kwargs.values(), card_id),
)
2022-07-15 16:43:06 +02:00
row = await db.fetchone("SELECT * FROM boltcards.cards WHERE id = ?", (card_id,))
2022-06-13 21:08:06 +02:00
return Card(**row) if row else None
2022-07-15 16:43:06 +02:00
2022-06-13 21:08:06 +02:00
async def get_cards(wallet_ids: Union[str, List[str]]) -> List[Card]:
if isinstance(wallet_ids, str):
wallet_ids = [wallet_ids]
q = ",".join(["?"] * len(wallet_ids))
rows = await db.fetchall(
f"SELECT * FROM boltcards.cards WHERE wallet IN ({q})", (*wallet_ids,)
)
return [Card(**row) for row in rows]
2022-07-15 16:43:06 +02:00
2022-06-13 21:08:06 +02:00
async def get_all_cards() -> List[Card]:
2022-07-15 16:43:06 +02:00
rows = await db.fetchall(f"SELECT * FROM boltcards.cards")
2022-06-13 21:08:06 +02:00
return [Card(**row) for row in rows]
2022-07-15 16:43:06 +02:00
2022-08-14 23:52:55 +02:00
async def get_card(card_id: str) -> Optional[Card]:
row = await db.fetchone("SELECT * FROM boltcards.cards WHERE id = ?", (card_id,))
if not row:
return None
card = dict(**row)
return Card.parse_obj(card)
2022-08-21 09:02:20 -06:00
async def get_card_by_uid(card_uid: str) -> Optional[Card]:
row = await db.fetchone(
"SELECT * FROM boltcards.cards WHERE uid = ?", (card_uid.upper(),)
)
if not row:
return None
card = dict(**row)
return Card.parse_obj(card)
2022-08-14 23:52:55 +02:00
async def get_card_by_otp(otp: str) -> Optional[Card]:
row = await db.fetchone("SELECT * FROM boltcards.cards WHERE otp = ?", (otp,))
2022-06-13 21:08:06 +02:00
if not row:
return None
card = dict(**row)
return Card.parse_obj(card)
2022-07-15 16:43:06 +02:00
2022-06-13 21:08:06 +02:00
async def delete_card(card_id: str) -> None:
await db.execute("DELETE FROM boltcards.cards WHERE id = ?", (card_id,))
2022-07-15 16:43:06 +02:00
2022-06-13 21:08:06 +02:00
async def update_card_counter(counter: int, id: str):
await db.execute(
"UPDATE boltcards.cards SET counter = ? WHERE id = ?",
(counter, id),
2022-06-21 18:03:20 +02:00
)
2022-07-15 16:43:06 +02:00
2022-08-14 23:52:55 +02:00
async def update_card_otp(otp: str, id: str):
await db.execute(
"UPDATE boltcards.cards SET otp = ? WHERE id = ?",
(otp, id),
)
2022-06-21 18:03:20 +02:00
async def get_hit(hit_id: str) -> Optional[Hit]:
2022-07-15 16:43:06 +02:00
row = await db.fetchone(f"SELECT * FROM boltcards.hits WHERE id = ?", (hit_id))
2022-06-21 18:03:20 +02:00
if not row:
return None
hit = dict(**row)
return Hit.parse_obj(hit)
2022-07-15 16:43:06 +02:00
2022-06-21 22:04:43 +02:00
async def get_hits(cards_ids: Union[str, List[str]]) -> List[Hit]:
q = ",".join(["?"] * len(cards_ids))
2022-06-21 18:03:20 +02:00
rows = await db.fetchall(
2022-06-21 22:04:43 +02:00
f"SELECT * FROM boltcards.hits WHERE card_id IN ({q})", (*cards_ids,)
2022-06-21 18:03:20 +02:00
)
2022-06-21 22:04:43 +02:00
return [Hit(**row) for row in rows]
2022-06-21 18:03:20 +02:00
2022-07-15 16:43:06 +02:00
async def create_hit(card_id, ip, useragent, old_ctr, new_ctr) -> Hit:
2022-06-21 18:03:20 +02:00
hit_id = urlsafe_short_hash()
await db.execute(
"""
INSERT INTO boltcards.hits (
id,
card_id,
ip,
useragent,
old_ctr,
new_ctr
)
VALUES (?, ?, ?, ?, ?, ?)
""",
(
hit_id,
card_id,
ip,
useragent,
old_ctr,
new_ctr,
),
)
hit = await get_hit(hit_id)
assert hit, "Newly recorded hit couldn't be retrieved"
return hit