chore: code format

This commit is contained in:
Vlad Stan 2023-02-15 10:49:36 +02:00
parent 366dae2082
commit 58723a387f
6 changed files with 52 additions and 42 deletions

View file

@ -106,8 +106,6 @@ class NostrClientConnection:
] = None ] = None
self.get_client_config: Optional[Callable[[], RelaySpec]] = None self.get_client_config: Optional[Callable[[], RelaySpec]] = None
async def start(self): async def start(self):
await self.websocket.accept() await self.websocket.accept()
while True: while True:
@ -177,14 +175,15 @@ class NostrClientConnection:
self.authenticated = True self.authenticated = True
return None return None
if not self.authenticated and self.client_config.event_requires_auth(e.kind): if not self.authenticated and self.client_config.event_requires_auth(e.kind):
await self._send_msg(["AUTH", self._current_auth_challenge()]) await self._send_msg(["AUTH", self._current_auth_challenge()])
resp_nip20 += [False, f"restricted: Relay requires authentication for events of kind '{e.kind}'"] resp_nip20 += [
False,
f"restricted: Relay requires authentication for events of kind '{e.kind}'",
]
await self._send_msg(resp_nip20) await self._send_msg(resp_nip20)
return None return None
valid, message = await self._validate_write(e) valid, message = await self._validate_write(e)
if not valid: if not valid:
resp_nip20 += [valid, message] resp_nip20 += [valid, message]
@ -259,7 +258,7 @@ class NostrClientConnection:
self._remove_filter(subscription_id) self._remove_filter(subscription_id)
def _handle_auth(self): def _handle_auth(self):
raise ValueError('Not supported') raise ValueError("Not supported")
def _can_add_filter(self) -> bool: def _can_add_filter(self) -> bool:
return ( return (
@ -276,7 +275,7 @@ class NostrClientConnection:
challenge_tag = e.tag_values("challenge") challenge_tag = e.tag_values("challenge")
if len(relay_tag) == 0 or len(challenge_tag) == 0: if len(relay_tag) == 0 or len(challenge_tag) == 0:
return False, "error: NIP42 tags are missing for auth event" return False, "error: NIP42 tags are missing for auth event"
if self.client_config.domain != extract_domain(relay_tag[0]): if self.client_config.domain != extract_domain(relay_tag[0]):
return False, "error: wrong relay domain for auth event" return False, "error: wrong relay domain for auth event"
@ -317,10 +316,12 @@ class NostrClientConnection:
return True, "" return True, ""
async def _validate_storage(self, pubkey: str, event_size_bytes: int) -> Tuple[bool, str]: async def _validate_storage(
self, pubkey: str, event_size_bytes: int
) -> Tuple[bool, str]:
if self.client_config.is_read_only_relay: if self.client_config.is_read_only_relay:
return False, "Cannot write event, relay is read-only" return False, "Cannot write event, relay is read-only"
account = await get_account(self.relay_id, pubkey) account = await get_account(self.relay_id, pubkey)
if not account: if not account:
account = NostrAccount.null_account() account = NostrAccount.null_account()
@ -329,7 +330,9 @@ class NostrClientConnection:
return False, f"This is a paid relay: '{self.relay_id}'" return False, f"This is a paid relay: '{self.relay_id}'"
stored_bytes = await get_storage_for_public_key(self.relay_id, pubkey) stored_bytes = await get_storage_for_public_key(self.relay_id, pubkey)
total_available_storage = account.storage + self.client_config.free_storage_bytes_value total_available_storage = (
account.storage + self.client_config.free_storage_bytes_value
)
if (stored_bytes + event_size_bytes) <= total_available_storage: if (stored_bytes + event_size_bytes) <= total_available_storage:
return True, "" return True, ""
@ -375,11 +378,13 @@ class NostrClientConnection:
if self._auth_challenge_created_at == 0: if self._auth_challenge_created_at == 0:
return True return True
current_time_seconds = round(time.time()) current_time_seconds = round(time.time())
chanllenge_max_age_seconds = 300 # 5 min chanllenge_max_age_seconds = 300 # 5 min
return (current_time_seconds - self._auth_challenge_created_at) >= chanllenge_max_age_seconds return (
current_time_seconds - self._auth_challenge_created_at
) >= chanllenge_max_age_seconds
def _current_auth_challenge(self): def _current_auth_challenge(self):
if self._auth_challenge_expired(): if self._auth_challenge_expired():
self._auth_challenge = self.relay_id + ":" + urlsafe_short_hash() self._auth_challenge = self.relay_id + ":" + urlsafe_short_hash()
self._auth_challenge_created_at = round(time.time()) self._auth_challenge_created_at = round(time.time())
return self._auth_challenge return self._auth_challenge

19
crud.py
View file

@ -13,6 +13,7 @@ from .models import (
########################## RELAYS #################### ########################## RELAYS ####################
async def create_relay(user_id: str, r: NostrRelay) -> NostrRelay: async def create_relay(user_id: str, r: NostrRelay) -> NostrRelay:
await db.execute( await db.execute(
""" """
@ -326,9 +327,9 @@ def build_select_events_query(relay_id: str, filter: NostrFilter):
return query, values return query, values
########################## ACCOUNTS #################### ########################## ACCOUNTS ####################
async def create_account(relay_id: str, a: NostrAccount) -> NostrAccount: async def create_account(relay_id: str, a: NostrAccount) -> NostrAccount:
await db.execute( await db.execute(
""" """
@ -357,25 +358,19 @@ async def update_account(relay_id: str, a: NostrAccount) -> NostrAccount:
SET (sats, storage, paid_to_join, allowed, blocked) = (?, ?, ?, ?, ?) SET (sats, storage, paid_to_join, allowed, blocked) = (?, ?, ?, ?, ?)
WHERE relay_id = ? AND pubkey = ? WHERE relay_id = ? AND pubkey = ?
""", """,
( (a.sats, a.storage, a.paid_to_join, a.allowed, a.blocked, relay_id, a.pubkey),
a.sats,
a.storage,
a.paid_to_join,
a.allowed,
a.blocked,
relay_id,
a.pubkey
),
) )
return a return a
async def get_account(relay_id: str, pubkey: str,) -> Optional[NostrAccount]: async def get_account(
relay_id: str,
pubkey: str,
) -> Optional[NostrAccount]:
row = await db.fetchone( row = await db.fetchone(
"SELECT * FROM nostrrelay.accounts WHERE relay_id = ? AND pubkey = ?", "SELECT * FROM nostrrelay.accounts WHERE relay_id = ? AND pubkey = ?",
(relay_id, pubkey), (relay_id, pubkey),
) )
return NostrAccount.from_row(row) if row else None return NostrAccount.from_row(row) if row else None

View file

@ -20,5 +20,6 @@ def normalize_public_key(pubkey: str) -> str:
int(pubkey, 16) int(pubkey, 16)
return pubkey return pubkey
def extract_domain(url: str) -> str: def extract_domain(url: str) -> str:
return urlparse(url).netloc return urlparse(url).netloc

View file

@ -73,6 +73,7 @@ class AuthSpec(BaseModel):
return False return False
return kind not in self.skiped_auth_events return kind not in self.skiped_auth_events
class PaymentSpec(BaseModel): class PaymentSpec(BaseModel):
is_paid_relay = Field(False, alias="isPaidRelay") is_paid_relay = Field(False, alias="isPaidRelay")
cost_to_join = Field(0, alias="costToJoin") cost_to_join = Field(0, alias="costToJoin")
@ -93,23 +94,23 @@ class AuthorSpec(Spec):
# todo: check payment # todo: check payment
return p in self.allowed_public_keys return p in self.allowed_public_keys
class WalletSpec(Spec): class WalletSpec(Spec):
wallet = Field("") wallet = Field("")
class RelayPublicSpec(FilterSpec, EventSpec, StorageSpec, PaymentSpec): class RelayPublicSpec(FilterSpec, EventSpec, StorageSpec, PaymentSpec):
domain: str = '' domain: str = ""
@property @property
def is_read_only_relay(self): def is_read_only_relay(self):
self.free_storage_value == 0 and not self.is_paid_relay self.free_storage_value == 0 and not self.is_paid_relay
class RelaySpec(RelayPublicSpec, AuthorSpec, WalletSpec, AuthSpec): class RelaySpec(RelayPublicSpec, AuthorSpec, WalletSpec, AuthSpec):
pass pass
class NostrRelay(BaseModel): class NostrRelay(BaseModel):
id: str id: str
name: str name: str
@ -183,7 +184,7 @@ class NostrEvent(BaseModel):
@property @property
def is_auth_response_event(self) -> bool: def is_auth_response_event(self) -> bool:
return self.kind == 22242 return self.kind == 22242
@property @property
def is_delete_event(self) -> bool: def is_delete_event(self) -> bool:
return self.kind == 5 return self.kind == 5
@ -340,7 +341,8 @@ class BuyOrder(BaseModel):
units_to_buy = 0 units_to_buy = 0
def is_valid_action(self): def is_valid_action(self):
return self.action in ['join', 'storage'] return self.action in ["join", "storage"]
class NostrAccount(BaseModel): class NostrAccount(BaseModel):
pubkey: str pubkey: str
@ -356,4 +358,4 @@ class NostrAccount(BaseModel):
@classmethod @classmethod
def from_row(cls, row: Row) -> "NostrAccount": def from_row(cls, row: Row) -> "NostrAccount":
return cls(**dict(row)) return cls(**dict(row))

View file

@ -35,13 +35,16 @@ async def on_invoice_paid(payment: Payment):
await invoice_paid_for_storage(relay_id, pubkey, storage_to_buy) await invoice_paid_for_storage(relay_id, pubkey, storage_to_buy)
return return
async def invoice_paid_to_join(relay_id: str, pubkey: str): async def invoice_paid_to_join(relay_id: str, pubkey: str):
try: try:
account = await get_account(relay_id, pubkey) account = await get_account(relay_id, pubkey)
if not account: if not account:
await create_account(relay_id, NostrAccount(pubkey=pubkey, paid_to_join=True)) await create_account(
relay_id, NostrAccount(pubkey=pubkey, paid_to_join=True)
)
return return
if account.blocked or account.paid_to_join: if account.blocked or account.paid_to_join:
return return
@ -56,9 +59,11 @@ async def invoice_paid_for_storage(relay_id: str, pubkey: str, storage_to_buy: i
try: try:
account = await get_account(relay_id, pubkey) account = await get_account(relay_id, pubkey)
if not account: if not account:
await create_account(relay_id, NostrAccount(pubkey=pubkey, storage=storage_to_buy)) await create_account(
relay_id, NostrAccount(pubkey=pubkey, storage=storage_to_buy)
)
return return
if account.blocked: if account.blocked:
return return
@ -66,4 +71,4 @@ async def invoice_paid_for_storage(relay_id: str, pubkey: str, storage_to_buy: i
await update_account(relay_id, account) await update_account(relay_id, account)
except Exception as ex: except Exception as ex:
logger.warning(ex) logger.warning(ex)

View file

@ -48,7 +48,9 @@ async def websocket_endpoint(relay_id: str, websocket: WebSocket):
@nostrrelay_ext.post("/api/v1/relay") @nostrrelay_ext.post("/api/v1/relay")
async def api_create_relay( async def api_create_relay(
data: NostrRelay, request: Request, wallet: WalletTypeInfo = Depends(require_admin_key) data: NostrRelay,
request: Request,
wallet: WalletTypeInfo = Depends(require_admin_key),
) -> NostrRelay: ) -> NostrRelay:
if len(data.id): if len(data.id):
await check_admin(UUID4(wallet.wallet.user)) await check_admin(UUID4(wallet.wallet.user))
@ -166,11 +168,11 @@ async def api_pay_to_join(data: BuyOrder):
detail="Relay not found", detail="Relay not found",
) )
if data.action == 'join' and relay.is_free_to_join: if data.action == "join" and relay.is_free_to_join:
raise ValueError("Relay is free to join") raise ValueError("Relay is free to join")
storage_to_buy = 0 storage_to_buy = 0
if data.action == 'storage': if data.action == "storage":
if relay.config.storage_cost_value == 0: if relay.config.storage_cost_value == 0:
raise ValueError("Relay storage cost is zero. Cannot buy!") raise ValueError("Relay storage cost is zero. Cannot buy!")
if data.units_to_buy == 0: if data.units_to_buy == 0:
@ -188,7 +190,7 @@ async def api_pay_to_join(data: BuyOrder):
"action": data.action, "action": data.action,
"relay_id": relay.id, "relay_id": relay.id,
"pubkey": pubkey, "pubkey": pubkey,
"storage_to_buy": storage_to_buy "storage_to_buy": storage_to_buy,
}, },
) )
print("### payment_request", payment_request) print("### payment_request", payment_request)