From 2b3a2afe834f717d70898bc9f1e08beb3869e736 Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 12 Jan 2023 15:16:37 +0000 Subject: [PATCH 01/17] Making universal tinyurl function --- lnbits/core/crud.py | 29 ++++++++++++++++++++++++++++- lnbits/core/migrations.py | 9 +++++++++ lnbits/core/models.py | 9 +++++++++ lnbits/core/views/api.py | 23 +++++++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index a80fadf2..b4a52a74 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -9,7 +9,7 @@ from lnbits.db import COCKROACH, POSTGRES, Connection from lnbits.settings import AdminSettings, EditableSettings, SuperSettings, settings from . import db -from .models import BalanceCheck, Payment, User, Wallet +from .models import BalanceCheck, Payment, TinyURL, User, Wallet # accounts # -------- @@ -620,3 +620,30 @@ async def create_admin_settings(super_user: str, new_settings: dict): sql = f"INSERT INTO settings (super_user, editable_settings) VALUES (?, ?)" await db.execute(sql, (super_user, json.dumps(new_settings))) return await get_super_settings() + + +# tinyurl +# ------- + + +async def create_tinyurl(tiny_url: str): + tinyurl_id = uuid4().hex[:8] + await (conn or db).execute( + """ + INSERT INTO tiny_url (id, url) VALUES (?, ?) + """, + (tinyurl_id, domain), + ) + return await get_tinyurl(tinyurl_id) + + +async def get_tinyurl(tinyurl_id: str) -> Optional[BalanceCheck]: + row = await (conn or db).fetchone( + """ + SELECT * + FROM tiny_url + WHERE id = ? + """, + (tinyurl_id), + ) + return TinyURL.from_row(row) if row else None diff --git a/lnbits/core/migrations.py b/lnbits/core/migrations.py index 66254d11..649b7f32 100644 --- a/lnbits/core/migrations.py +++ b/lnbits/core/migrations.py @@ -269,3 +269,12 @@ async def m008_create_admin_settings_table(db): ); """ ) + + await db.execute( + """ + CREATE TABLE IF NOT EXISTS tinyurl ( + id TEXT PRIMARY KEY, + url TEXT, + ); + """ + ) diff --git a/lnbits/core/models.py b/lnbits/core/models.py index eca1bf50..effd89db 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -213,3 +213,12 @@ class BalanceCheck(BaseModel): @classmethod def from_row(cls, row: Row): return cls(wallet=row["wallet"], service=row["service"], url=row["url"]) + + +class TinyURL(BaseModel): + id: str + url: str + + @classmethod + def from_row(cls, row: Row) -> "TinyURL": + return cls(**dict(row)) diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index d545df9a..6f08fd0f 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -706,3 +706,26 @@ async def websocket_update_get(item_id: str, data: str): return {"sent": True, "data": data} except: return {"sent": False, "data": data} + + +############################TINYURL################################## + + +@core_app.post("/api/v1/tinyurl") +async def api_create_tinyurl(url: str): + return await create_tinyurl(url) + + +@core_app.get("/api/v1/tinyurl/{tinyurl_id}") +async def api_get_tinyurl(tinyurl_id: str): + return await get_tinyurl(tinyurl_id) + + +@core_app.get("/{tinyurl_id}") +async def api_tinyurl(tinyurl_id: str): + tinyurl = await get_tinyurl(tinyurl_id) + if tinyurl: + response = RedirectResponse(url=tinyurl.url) + return response + else: + return From ce701b9506e22725cd8a3a7b0c8ac22945609425 Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 12 Jan 2023 20:25:51 +0000 Subject: [PATCH 02/17] Made specific migration --- lnbits/core/migrations.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lnbits/core/migrations.py b/lnbits/core/migrations.py index 649b7f32..3d64422a 100644 --- a/lnbits/core/migrations.py +++ b/lnbits/core/migrations.py @@ -270,11 +270,12 @@ async def m008_create_admin_settings_table(db): """ ) +async def m009_create_tinyurl_table(db): await db.execute( """ CREATE TABLE IF NOT EXISTS tinyurl ( id TEXT PRIMARY KEY, - url TEXT, + url TEXT ); """ ) From 6d8896c2f6a000d72844382547da9843c543262a Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 12 Jan 2023 20:37:03 +0000 Subject: [PATCH 03/17] works --- lnbits/core/crud.py | 6 +++--- lnbits/core/migrations.py | 3 ++- lnbits/core/views/api.py | 4 +++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index b4a52a74..cc186788 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -626,9 +626,9 @@ async def create_admin_settings(super_user: str, new_settings: dict): # ------- -async def create_tinyurl(tiny_url: str): +async def create_tinyurl(domain: str): tinyurl_id = uuid4().hex[:8] - await (conn or db).execute( + await db.execute( """ INSERT INTO tiny_url (id, url) VALUES (?, ?) """, @@ -638,7 +638,7 @@ async def create_tinyurl(tiny_url: str): async def get_tinyurl(tinyurl_id: str) -> Optional[BalanceCheck]: - row = await (conn or db).fetchone( + row = await db.fetchone( """ SELECT * FROM tiny_url diff --git a/lnbits/core/migrations.py b/lnbits/core/migrations.py index 3d64422a..d7e0e186 100644 --- a/lnbits/core/migrations.py +++ b/lnbits/core/migrations.py @@ -270,10 +270,11 @@ async def m008_create_admin_settings_table(db): """ ) + async def m009_create_tinyurl_table(db): await db.execute( """ - CREATE TABLE IF NOT EXISTS tinyurl ( + CREATE TABLE IF NOT EXISTS tiny_url ( id TEXT PRIMARY KEY, url TEXT ); diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index 6f08fd0f..dd824ee6 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -26,7 +26,7 @@ from loguru import logger from pydantic import BaseModel from pydantic.fields import Field from sse_starlette.sse import EventSourceResponse -from starlette.responses import StreamingResponse +from starlette.responses import RedirectResponse, StreamingResponse from lnbits import bolt11, lnurl from lnbits.core.models import Payment, Wallet @@ -47,8 +47,10 @@ from lnbits.utils.exchange_rates import ( from .. import core_app, db from ..crud import ( + create_tinyurl, get_payments, get_standalone_payment, + get_tinyurl, get_total_balance, get_wallet_for_key, save_balance_check, From 6e33784061cd1cb05b7d79a99fc0d367c911a4bc Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 12 Jan 2023 22:39:20 +0000 Subject: [PATCH 04/17] Removed lnurlp tests --- lnbits/core/crud.py | 12 ++++++++++++ lnbits/core/views/api.py | 7 +++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index cc186788..3979e791 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -647,3 +647,15 @@ async def get_tinyurl(tinyurl_id: str) -> Optional[BalanceCheck]: (tinyurl_id), ) return TinyURL.from_row(row) if row else None + + +async def get_tinyurl_by_url(url: str) -> Optional[BalanceCheck]: + row = await db.fetchone( + """ + SELECT * + FROM tiny_url + WHERE url = ? + """, + (url), + ) + return TinyURL.from_row(row) if row else None \ No newline at end of file diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index dd824ee6..fb05241c 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -51,6 +51,7 @@ from ..crud import ( get_payments, get_standalone_payment, get_tinyurl, + get_tinyurl_by_url, get_total_balance, get_wallet_for_key, save_balance_check, @@ -715,15 +716,17 @@ async def websocket_update_get(item_id: str, data: str): @core_app.post("/api/v1/tinyurl") async def api_create_tinyurl(url: str): + tinyurl = await get_tinyurl_by_url(url) + if tinyurl: + return tinyurl return await create_tinyurl(url) - @core_app.get("/api/v1/tinyurl/{tinyurl_id}") async def api_get_tinyurl(tinyurl_id: str): return await get_tinyurl(tinyurl_id) -@core_app.get("/{tinyurl_id}") +@core_app.get("/t/{tinyurl_id}") async def api_tinyurl(tinyurl_id: str): tinyurl = await get_tinyurl(tinyurl_id) if tinyurl: From f97326bed03fefdb98b37072323eae2ae05d9d25 Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 12 Jan 2023 22:42:49 +0000 Subject: [PATCH 05/17] Adde models --- lnbits/core/crud.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index 3979e791..45f192b9 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -9,7 +9,7 @@ from lnbits.db import COCKROACH, POSTGRES, Connection from lnbits.settings import AdminSettings, EditableSettings, SuperSettings, settings from . import db -from .models import BalanceCheck, Payment, TinyURL, User, Wallet +from .models import BalanceCheck, Payment, TinyURL, User, Wallet, TinyURL # accounts # -------- @@ -637,7 +637,7 @@ async def create_tinyurl(domain: str): return await get_tinyurl(tinyurl_id) -async def get_tinyurl(tinyurl_id: str) -> Optional[BalanceCheck]: +async def get_tinyurl(tinyurl_id: str) -> Optional[TinyURL]: row = await db.fetchone( """ SELECT * @@ -649,7 +649,7 @@ async def get_tinyurl(tinyurl_id: str) -> Optional[BalanceCheck]: return TinyURL.from_row(row) if row else None -async def get_tinyurl_by_url(url: str) -> Optional[BalanceCheck]: +async def get_tinyurl_by_url(url: str) -> Optional[TinyURL]: row = await db.fetchone( """ SELECT * From ca4134eb02c7f21e97d98505f443cfbe66795044 Mon Sep 17 00:00:00 2001 From: ben Date: Thu, 12 Jan 2023 22:52:46 +0000 Subject: [PATCH 06/17] added conn --- lnbits/core/crud.py | 36 +++++++++++++++--------------------- lnbits/core/views/api.py | 1 + 2 files changed, 16 insertions(+), 21 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index 45f192b9..df5345bb 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -9,7 +9,7 @@ from lnbits.db import COCKROACH, POSTGRES, Connection from lnbits.settings import AdminSettings, EditableSettings, SuperSettings, settings from . import db -from .models import BalanceCheck, Payment, TinyURL, User, Wallet, TinyURL +from .models import BalanceCheck, Payment, TinyURL, User, Wallet # accounts # -------- @@ -626,36 +626,30 @@ async def create_admin_settings(super_user: str, new_settings: dict): # ------- -async def create_tinyurl(domain: str): +async def create_tinyurl(domain: str, conn: Optional[Connection] = None): tinyurl_id = uuid4().hex[:8] - await db.execute( - """ - INSERT INTO tiny_url (id, url) VALUES (?, ?) - """, + await (conn or db).execute( + f"INSERT INTO tiny_url (id, url) VALUES (?, ?)", (tinyurl_id, domain), ) return await get_tinyurl(tinyurl_id) -async def get_tinyurl(tinyurl_id: str) -> Optional[TinyURL]: - row = await db.fetchone( - """ - SELECT * - FROM tiny_url - WHERE id = ? - """, +async def get_tinyurl( + tinyurl_id: str, conn: Optional[Connection] = None +) -> Optional[TinyURL]: + row = await (conn or db).fetchone( + f"SELECT * FROM tiny_url WHERE id = ?", (tinyurl_id), ) return TinyURL.from_row(row) if row else None -async def get_tinyurl_by_url(url: str) -> Optional[TinyURL]: - row = await db.fetchone( - """ - SELECT * - FROM tiny_url - WHERE url = ? - """, +async def get_tinyurl_by_url( + url: str, conn: Optional[Connection] = None +) -> Optional[TinyURL]: + row = await (conn or db).fetchone( + f"SELECT * FROM tiny_url WHERE url = ?", (url), ) - return TinyURL.from_row(row) if row else None \ No newline at end of file + return TinyURL.from_row(row) if row else None diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index fb05241c..1a166da0 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -721,6 +721,7 @@ async def api_create_tinyurl(url: str): return tinyurl return await create_tinyurl(url) + @core_app.get("/api/v1/tinyurl/{tinyurl_id}") async def api_get_tinyurl(tinyurl_id: str): return await get_tinyurl(tinyurl_id) From 165e5099c12fcbd8963f6cf4a9c9259164b722e5 Mon Sep 17 00:00:00 2001 From: ben Date: Mon, 23 Jan 2023 19:57:49 +0000 Subject: [PATCH 07/17] trying to fix mypy --- lnbits/core/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lnbits/core/models.py b/lnbits/core/models.py index effd89db..d6f47ff5 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -220,5 +220,5 @@ class TinyURL(BaseModel): url: str @classmethod - def from_row(cls, row: Row) -> "TinyURL": - return cls(**dict(row)) + def from_row(cls, row: Row): + return cls(id=row["id"],url=row["url"]) From f3b1bca5b85843871495fe20a7d19ae78dee3fc6 Mon Sep 17 00:00:00 2001 From: ben Date: Mon, 23 Jan 2023 20:25:47 +0000 Subject: [PATCH 08/17] format --- lnbits/core/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lnbits/core/models.py b/lnbits/core/models.py index d6f47ff5..4b509496 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -221,4 +221,4 @@ class TinyURL(BaseModel): @classmethod def from_row(cls, row: Row): - return cls(id=row["id"],url=row["url"]) + return cls(id=row["id"], url=row["url"]) From 0d0817044c11ec5d9d5b1ed964866528bf4ae321 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 24 Jan 2023 11:03:46 +0000 Subject: [PATCH 09/17] Pissy python and its tuples --- lnbits/core/crud.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index df5345bb..ca4c7ae9 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -640,7 +640,7 @@ async def get_tinyurl( ) -> Optional[TinyURL]: row = await (conn or db).fetchone( f"SELECT * FROM tiny_url WHERE id = ?", - (tinyurl_id), + (tinyurl_id,), ) return TinyURL.from_row(row) if row else None @@ -650,6 +650,6 @@ async def get_tinyurl_by_url( ) -> Optional[TinyURL]: row = await (conn or db).fetchone( f"SELECT * FROM tiny_url WHERE url = ?", - (url), + (url,), ) return TinyURL.from_row(row) if row else None From e53ccb04accc9d53f65e69468b9c84343c45e73c Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 24 Jan 2023 12:45:15 +0000 Subject: [PATCH 10/17] Added timestamp and endless For future culling of links. If endless is not specified, then links older than x could be removed --- lnbits/core/migrations.py | 6 ++++-- lnbits/core/models.py | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lnbits/core/migrations.py b/lnbits/core/migrations.py index d7e0e186..499adad6 100644 --- a/lnbits/core/migrations.py +++ b/lnbits/core/migrations.py @@ -273,10 +273,12 @@ async def m008_create_admin_settings_table(db): async def m009_create_tinyurl_table(db): await db.execute( - """ + f""" CREATE TABLE IF NOT EXISTS tiny_url ( id TEXT PRIMARY KEY, - url TEXT + url TEXT, + endless BOOL NOT NULL DEFAULT false, + time TIMESTAMP NOT NULL DEFAULT {db.timestamp_now}, ); """ ) diff --git a/lnbits/core/models.py b/lnbits/core/models.py index 4b509496..19e59776 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -218,6 +218,8 @@ class BalanceCheck(BaseModel): class TinyURL(BaseModel): id: str url: str + endless: bool + time: float @classmethod def from_row(cls, row: Row): From 274615f0b328ed8ddcc4c7af3d67164d4fd58101 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 24 Jan 2023 13:27:30 +0000 Subject: [PATCH 11/17] Man, broken --- lnbits/core/crud.py | 6 +++--- lnbits/core/migrations.py | 2 +- lnbits/core/models.py | 2 +- lnbits/core/views/api.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index ca4c7ae9..ebae6a81 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -626,11 +626,11 @@ async def create_admin_settings(super_user: str, new_settings: dict): # ------- -async def create_tinyurl(domain: str, conn: Optional[Connection] = None): +async def create_tinyurl(domain: str, endless: bool, conn: Optional[Connection] = None): tinyurl_id = uuid4().hex[:8] await (conn or db).execute( - f"INSERT INTO tiny_url (id, url) VALUES (?, ?)", - (tinyurl_id, domain), + f"INSERT INTO tiny_url (id, url, endless) VALUES (?, ?, ?)", + (tinyurl_id, domain, endless,), ) return await get_tinyurl(tinyurl_id) diff --git a/lnbits/core/migrations.py b/lnbits/core/migrations.py index 499adad6..32764b39 100644 --- a/lnbits/core/migrations.py +++ b/lnbits/core/migrations.py @@ -278,7 +278,7 @@ async def m009_create_tinyurl_table(db): id TEXT PRIMARY KEY, url TEXT, endless BOOL NOT NULL DEFAULT false, - time TIMESTAMP NOT NULL DEFAULT {db.timestamp_now}, + time TIMESTAMP NOT NULL DEFAULT {db.timestamp_now} ); """ ) diff --git a/lnbits/core/models.py b/lnbits/core/models.py index 19e59776..e8de4694 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -223,4 +223,4 @@ class TinyURL(BaseModel): @classmethod def from_row(cls, row: Row): - return cls(id=row["id"], url=row["url"]) + return cls(dict(row)) diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index 1a166da0..b72cc244 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -715,11 +715,11 @@ async def websocket_update_get(item_id: str, data: str): @core_app.post("/api/v1/tinyurl") -async def api_create_tinyurl(url: str): +async def api_create_tinyurl(url: str, endless: Optional[bool] = False): tinyurl = await get_tinyurl_by_url(url) if tinyurl: return tinyurl - return await create_tinyurl(url) + return await create_tinyurl(url, endless) @core_app.get("/api/v1/tinyurl/{tinyurl_id}") From 5392b2cbfe42eed69fe300fde36bbfbca6443214 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 24 Jan 2023 13:30:15 +0000 Subject: [PATCH 12/17] Fixed models --- lnbits/core/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lnbits/core/models.py b/lnbits/core/models.py index e8de4694..a2d05568 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -223,4 +223,4 @@ class TinyURL(BaseModel): @classmethod def from_row(cls, row: Row): - return cls(dict(row)) + return cls(**dict(row)) From caadeb77e227aa5af4b361ac4e1cad39254e9ec1 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 24 Jan 2023 13:32:21 +0000 Subject: [PATCH 13/17] format --- lnbits/core/crud.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index ebae6a81..5c1b3bc7 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -630,7 +630,11 @@ async def create_tinyurl(domain: str, endless: bool, conn: Optional[Connection] tinyurl_id = uuid4().hex[:8] await (conn or db).execute( f"INSERT INTO tiny_url (id, url, endless) VALUES (?, ?, ?)", - (tinyurl_id, domain, endless,), + ( + tinyurl_id, + domain, + endless, + ), ) return await get_tinyurl(tinyurl_id) From 6c9a52c6e1595c8f0c59cd2bf2db7602208a6aa0 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 24 Jan 2023 13:48:04 +0000 Subject: [PATCH 14/17] mypy being thoroughly objectionable --- lnbits/core/views/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index b72cc244..105c240b 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -715,7 +715,7 @@ async def websocket_update_get(item_id: str, data: str): @core_app.post("/api/v1/tinyurl") -async def api_create_tinyurl(url: str, endless: Optional[bool] = False): +async def api_create_tinyurl(url: str, endless: bool = False): tinyurl = await get_tinyurl_by_url(url) if tinyurl: return tinyurl From 7322d27aa38cc310cf1f3d7a07f92b52a242ce88 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 24 Jan 2023 20:27:20 +0000 Subject: [PATCH 15/17] changed to shortuuid as suggested by Vlad --- lnbits/core/crud.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index 5c1b3bc7..a4726d82 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -4,6 +4,8 @@ from typing import Any, Dict, List, Optional from urllib.parse import urlparse from uuid import uuid4 +import shortuuid + from lnbits import bolt11 from lnbits.db import COCKROACH, POSTGRES, Connection from lnbits.settings import AdminSettings, EditableSettings, SuperSettings, settings @@ -627,7 +629,7 @@ async def create_admin_settings(super_user: str, new_settings: dict): async def create_tinyurl(domain: str, endless: bool, conn: Optional[Connection] = None): - tinyurl_id = uuid4().hex[:8] + tinyurl_id = shortuuid.uuid()[:8] await (conn or db).execute( f"INSERT INTO tiny_url (id, url, endless) VALUES (?, ?, ?)", ( From c0c4c8680888f51f4a7a27a1b5237ec880ff23df Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 24 Jan 2023 21:26:18 +0000 Subject: [PATCH 16/17] Added wallet authentication to creat, get and delete tinyurls --- lnbits/core/crud.py | 28 ++++++++------- lnbits/core/migrations.py | 1 + lnbits/core/models.py | 1 + lnbits/core/views/api.py | 71 ++++++++++++++++++++++++++++++++------- 4 files changed, 76 insertions(+), 25 deletions(-) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index a4726d82..e5d4424f 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -628,34 +628,38 @@ async def create_admin_settings(super_user: str, new_settings: dict): # ------- -async def create_tinyurl(domain: str, endless: bool, conn: Optional[Connection] = None): +async def create_tinyurl(domain: str, endless: bool, wallet: str): tinyurl_id = shortuuid.uuid()[:8] - await (conn or db).execute( - f"INSERT INTO tiny_url (id, url, endless) VALUES (?, ?, ?)", + await db.execute( + f"INSERT INTO tiny_url (id, url, endless, wallet) VALUES (?, ?, ?, ?)", ( tinyurl_id, domain, endless, + wallet, ), ) return await get_tinyurl(tinyurl_id) -async def get_tinyurl( - tinyurl_id: str, conn: Optional[Connection] = None -) -> Optional[TinyURL]: - row = await (conn or db).fetchone( +async def get_tinyurl(tinyurl_id: str) -> Optional[TinyURL]: + row = await db.fetchone( f"SELECT * FROM tiny_url WHERE id = ?", (tinyurl_id,), ) return TinyURL.from_row(row) if row else None -async def get_tinyurl_by_url( - url: str, conn: Optional[Connection] = None -) -> Optional[TinyURL]: - row = await (conn or db).fetchone( +async def get_tinyurl_by_url(url: str) -> List[TinyURL]: + rows = await db.fetchall( f"SELECT * FROM tiny_url WHERE url = ?", (url,), ) - return TinyURL.from_row(row) if row else None + return [TinyURL.from_row(row) for row in rows] + + +async def delete_tinyurl(tinyurl_id: str): + row = await db.execute( + f"DELETE FROM tiny_url WHERE id = ?", + (tinyurl_id,), + ) diff --git a/lnbits/core/migrations.py b/lnbits/core/migrations.py index 32764b39..ccbd7871 100644 --- a/lnbits/core/migrations.py +++ b/lnbits/core/migrations.py @@ -278,6 +278,7 @@ async def m009_create_tinyurl_table(db): id TEXT PRIMARY KEY, url TEXT, endless BOOL NOT NULL DEFAULT false, + wallet TEXT, time TIMESTAMP NOT NULL DEFAULT {db.timestamp_now} ); """ diff --git a/lnbits/core/models.py b/lnbits/core/models.py index a2d05568..4def937e 100644 --- a/lnbits/core/models.py +++ b/lnbits/core/models.py @@ -219,6 +219,7 @@ class TinyURL(BaseModel): id: str url: str endless: bool + wallet: str time: float @classmethod diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index 105c240b..485592a7 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -48,6 +48,7 @@ from lnbits.utils.exchange_rates import ( from .. import core_app, db from ..crud import ( create_tinyurl, + delete_tinyurl, get_payments, get_standalone_payment, get_tinyurl, @@ -715,23 +716,67 @@ async def websocket_update_get(item_id: str, data: str): @core_app.post("/api/v1/tinyurl") -async def api_create_tinyurl(url: str, endless: bool = False): - tinyurl = await get_tinyurl_by_url(url) - if tinyurl: - return tinyurl - return await create_tinyurl(url, endless) +async def api_create_tinyurl( + url: str, endless: bool = False, wallet: WalletTypeInfo = Depends(get_key_type) +): + tinyurls = await get_tinyurl_by_url(url) + try: + for tinyurl in tinyurls: + if tinyurl: + if tinyurl.wallet == wallet.wallet.inkey: + return tinyurl + return await create_tinyurl(url, endless, wallet.wallet.inkey) + except: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, detail="Unable to create tinyurl" + ) @core_app.get("/api/v1/tinyurl/{tinyurl_id}") -async def api_get_tinyurl(tinyurl_id: str): - return await get_tinyurl(tinyurl_id) +async def api_get_tinyurl( + tinyurl_id: str, wallet: WalletTypeInfo = Depends(get_key_type) +): + try: + tinyurl = await get_tinyurl(tinyurl_id) + if tinyurl.wallet == wallet.wallet.inkey: + return tinyurl + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, detail="Wrong key provided." + ) + except: + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="Unable to fetch tinyurl" + ) + + +@core_app.delete("/api/v1/tinyurl/{tinyurl_id}") +async def api_delete_tinyurl( + tinyurl_id: str, wallet: WalletTypeInfo = Depends(get_key_type) +): + try: + tinyurl = await get_tinyurl(tinyurl_id) + if tinyurl.wallet == wallet.wallet.inkey: + await delete_tinyurl(tinyurl_id) + return {"deleted": True} + raise HTTPException( + status_code=HTTPStatus.FORBIDDEN, detail="Wrong key provided." + ) + except: + raise HTTPException( + status_code=HTTPStatus.BAD_REQUEST, detail="Unable to delete" + ) @core_app.get("/t/{tinyurl_id}") async def api_tinyurl(tinyurl_id: str): - tinyurl = await get_tinyurl(tinyurl_id) - if tinyurl: - response = RedirectResponse(url=tinyurl.url) - return response - else: - return + try: + tinyurl = await get_tinyurl(tinyurl_id) + if tinyurl: + response = RedirectResponse(url=tinyurl.url) + return response + else: + return + except: + raise HTTPException( + status_code=HTTPStatus.NOT_FOUND, detail="unable to find tinyurl" + ) From dda1d9bb3a9d45a97d9487ebe3959c3b1c5289b4 Mon Sep 17 00:00:00 2001 From: ben Date: Tue, 24 Jan 2023 21:29:52 +0000 Subject: [PATCH 17/17] mypy --- lnbits/core/views/api.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index 485592a7..f614ba02 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -738,8 +738,9 @@ async def api_get_tinyurl( ): try: tinyurl = await get_tinyurl(tinyurl_id) - if tinyurl.wallet == wallet.wallet.inkey: - return tinyurl + if tinyurl: + if tinyurl.wallet == wallet.wallet.inkey: + return tinyurl raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="Wrong key provided." ) @@ -755,9 +756,10 @@ async def api_delete_tinyurl( ): try: tinyurl = await get_tinyurl(tinyurl_id) - if tinyurl.wallet == wallet.wallet.inkey: - await delete_tinyurl(tinyurl_id) - return {"deleted": True} + if tinyurl: + if tinyurl.wallet == wallet.wallet.inkey: + await delete_tinyurl(tinyurl_id) + return {"deleted": True} raise HTTPException( status_code=HTTPStatus.FORBIDDEN, detail="Wrong key provided." )