[CHORE] update dependencies, unsafe pip packages, fastapi (#1609)

* d

* middleware needs to be initialised before startup

runs on python3.11

update secp256k1

update psycopg

* update fastapi to v0.103

* fix webpush

* bump dependencies

* ruff issue

* lock versions

* bump versions

---------

Co-authored-by: jacksn <jkranawetter05@gmail.com>
This commit is contained in:
dni ⚡ 2023-09-25 11:54:02 +02:00 committed by GitHub
parent d3d1010360
commit a8082f798f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 971 additions and 837 deletions

View File

@ -71,6 +71,10 @@ def create_app() -> FastAPI:
}, },
) )
# Allow registering new extensions routes without direct access to the `app` object
setattr(core_app_extra, "register_new_ext_routes", register_new_ext_routes(app))
setattr(core_app_extra, "register_new_ratelimiter", register_new_ratelimiter(app))
app.mount("/static", StaticFiles(packages=[("lnbits", "static")]), name="static") app.mount("/static", StaticFiles(packages=[("lnbits", "static")]), name="static")
app.mount( app.mount(
"/core/static", "/core/static",
@ -92,16 +96,16 @@ def create_app() -> FastAPI:
app.add_middleware(InstalledExtensionMiddleware) app.add_middleware(InstalledExtensionMiddleware)
app.add_middleware(ExtensionsRedirectMiddleware) app.add_middleware(ExtensionsRedirectMiddleware)
# adds security middleware
add_ip_block_middleware(app)
add_ratelimit_middleware(app)
register_startup(app) register_startup(app)
register_routes(app) register_routes(app)
register_async_tasks(app) register_async_tasks(app)
register_exception_handlers(app) register_exception_handlers(app)
register_shutdown(app) register_shutdown(app)
# Allow registering new extensions routes without direct access to the `app` object
setattr(core_app_extra, "register_new_ext_routes", register_new_ext_routes(app))
setattr(core_app_extra, "register_new_ratelimiter", register_new_ratelimiter(app))
return app return app
@ -329,10 +333,6 @@ def register_startup(app: FastAPI):
log_server_info() log_server_info()
# adds security middleware
add_ratelimit_middleware(app)
add_ip_block_middleware(app)
# initialize WALLET # initialize WALLET
try: try:
set_wallet_class() set_wallet_class()

View File

@ -571,7 +571,7 @@ async def create_payment(
fee, fee,
( (
json.dumps(extra) json.dumps(extra)
if extra and extra != {} and type(extra) is dict if extra and extra != {} and isinstance(extra, dict)
else None else None
), ),
webhook, webhook,

View File

@ -1013,6 +1013,6 @@ async def api_delete_webpush_subscription(
wallet: WalletTypeInfo = Depends(require_admin_key), wallet: WalletTypeInfo = Depends(require_admin_key),
): ):
endpoint = unquote( endpoint = unquote(
base64.b64decode(request.query_params.get("endpoint")).decode("utf-8") base64.b64decode(str(request.query_params.get("endpoint"))).decode("utf-8")
) )
await delete_webpush_subscription(endpoint, wallet.wallet.user) await delete_webpush_subscription(endpoint, wallet.wallet.user)

View File

@ -5,11 +5,10 @@ from urllib.parse import urlparse
from fastapi import Depends, Query, Request, status from fastapi import Depends, Query, Request, status
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
from fastapi.responses import FileResponse, RedirectResponse from fastapi.responses import FileResponse, HTMLResponse, JSONResponse, RedirectResponse
from fastapi.routing import APIRouter from fastapi.routing import APIRouter
from loguru import logger from loguru import logger
from pydantic.types import UUID4 from pydantic.types import UUID4
from starlette.responses import HTMLResponse, JSONResponse
from lnbits.core.db import db from lnbits.core.db import db
from lnbits.core.helpers import to_valid_user_id from lnbits.core.helpers import to_valid_user_id
@ -173,7 +172,7 @@ nothing: create everything
""", """,
) )
async def wallet( async def wallet(
request: Request = Query(None), request: Request,
nme: Optional[str] = Query(None), nme: Optional[str] = Query(None),
usr: Optional[UUID4] = Query(None), usr: Optional[UUID4] = Query(None),
wal: Optional[UUID4] = Query(None), wal: Optional[UUID4] = Query(None),
@ -247,11 +246,19 @@ async def wallet(
@generic_router.get("/withdraw", response_class=JSONResponse) @generic_router.get("/withdraw", response_class=JSONResponse)
async def lnurl_full_withdraw(request: Request): async def lnurl_full_withdraw(request: Request):
user = await get_user(request.query_params.get("usr")) usr_param = request.query_params.get("usr")
if not usr_param:
return {"status": "ERROR", "reason": "usr parameter not provided."}
user = await get_user(usr_param)
if not user: if not user:
return {"status": "ERROR", "reason": "User does not exist."} return {"status": "ERROR", "reason": "User does not exist."}
wallet = user.get_wallet(request.query_params.get("wal")) wal_param = request.query_params.get("wal")
if not wal_param:
return {"status": "ERROR", "reason": "wal parameter not provided."}
wallet = user.get_wallet(wal_param)
if not wallet: if not wallet:
return {"status": "ERROR", "reason": "Wallet does not exist."} return {"status": "ERROR", "reason": "Wallet does not exist."}
@ -270,15 +277,25 @@ async def lnurl_full_withdraw(request: Request):
@generic_router.get("/withdraw/cb", response_class=JSONResponse) @generic_router.get("/withdraw/cb", response_class=JSONResponse)
async def lnurl_full_withdraw_callback(request: Request): async def lnurl_full_withdraw_callback(request: Request):
user = await get_user(request.query_params.get("usr")) usr_param = request.query_params.get("usr")
if not usr_param:
return {"status": "ERROR", "reason": "usr parameter not provided."}
user = await get_user(usr_param)
if not user: if not user:
return {"status": "ERROR", "reason": "User does not exist."} return {"status": "ERROR", "reason": "User does not exist."}
wallet = user.get_wallet(request.query_params.get("wal")) wal_param = request.query_params.get("wal")
if not wal_param:
return {"status": "ERROR", "reason": "wal parameter not provided."}
wallet = user.get_wallet(wal_param)
if not wallet: if not wallet:
return {"status": "ERROR", "reason": "Wallet does not exist."} return {"status": "ERROR", "reason": "Wallet does not exist."}
pr = request.query_params.get("pr") pr = request.query_params.get("pr")
if not pr:
return {"status": "ERROR", "reason": "payment_request not provided."}
async def pay(): async def pay():
try: try:
@ -323,7 +340,11 @@ async def deletewallet(wal: str = Query(...), usr: str = Query(...)):
@generic_router.get("/withdraw/notify/{service}") @generic_router.get("/withdraw/notify/{service}")
async def lnurl_balance_notify(request: Request, service: str): async def lnurl_balance_notify(request: Request, service: str):
bc = await get_balance_check(request.query_params.get("wal"), service) wal_param = request.query_params.get("wal")
if not wal_param:
return {"status": "ERROR", "reason": "wal parameter not provided."}
bc = await get_balance_check(wal_param, service)
if bc: if bc:
await redeem_lnurl_withdraw(bc.wallet, bc.url) await redeem_lnurl_withdraw(bc.wallet, bc.url)
@ -338,10 +359,14 @@ async def lnurlwallet(request: Request):
assert user, "Newly created user not found." assert user, "Newly created user not found."
wallet = await create_wallet(user_id=user.id, conn=conn) wallet = await create_wallet(user_id=user.id, conn=conn)
lightning_param = request.query_params.get("lightning")
if not lightning_param:
return {"status": "ERROR", "reason": "lightning parameter not provided."}
asyncio.create_task( asyncio.create_task(
redeem_lnurl_withdraw( redeem_lnurl_withdraw(
wallet.id, wallet.id,
request.query_params.get("lightning"), lightning_param,
"LNbits initial funding: voucher redeem.", "LNbits initial funding: voucher redeem.",
{"tag": "lnurlwallet"}, {"tag": "lnurlwallet"},
5, # wait 5 seconds before sending the invoice to the service 5, # wait 5 seconds before sending the invoice to the service

View File

@ -1,4 +1,7 @@
from typing import Union
from bech32 import bech32_decode, bech32_encode, convertbits from bech32 import bech32_decode, bech32_encode, convertbits
from fastapi.datastructures import URL
def decode(lnurl: str) -> str: def decode(lnurl: str) -> str:
@ -10,8 +13,8 @@ def decode(lnurl: str) -> str:
return bytes(bech32_data).decode() return bytes(bech32_data).decode()
def encode(url: str) -> str: def encode(url: Union[str, URL]) -> str:
bech32_data = convertbits(url.encode(), 8, 5, True) bech32_data = convertbits(str(url).encode(), 8, 5, True)
assert bech32_data assert bech32_data
lnurl = bech32_encode("lnurl", bech32_data) lnurl = bech32_encode("lnurl", bech32_data)
return lnurl.upper() return lnurl.upper()

1687
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -8,45 +8,48 @@ authors = ["Alan Bits <alan@lnbits.com>"]
python = "^3.10 | ^3.9" python = "^3.10 | ^3.9"
bech32 = "1.2.0" bech32 = "1.2.0"
bitstring = "3.1.9" bitstring = "3.1.9"
click = "8.0.4" click = "8.1.7"
ecdsa = "0.18.0" ecdsa = "0.18.0"
embit = "^0.7.0" embit = "0.7.0"
fastapi = "0.83.0" fastapi = "0.103.1"
httpx = "0.23.0" httpx = "0.25.0"
jinja2 = "3.0.1" jinja2 = "3.0.1"
lnurl = "0.3.6" lnurl = "0.3.6"
psycopg2-binary = "2.9.1" psycopg2-binary = "2.9.7"
pydantic = "1.10.4" pydantic = "1.10.9"
pyqrcode = "1.2.1" pyqrcode = "1.2.1"
shortuuid = "1.0.11" shortuuid = "1.0.11"
sqlalchemy = "1.3.24" sqlalchemy = "1.3.24"
sqlalchemy-aio = "0.17.0" sqlalchemy-aio = "0.17.0"
sse-starlette = "0.6.2" sse-starlette = "1.6.5"
typing-extensions = "4.4.0" typing-extensions = "4.8.0"
uvicorn = "0.18.3" uvicorn = "0.23.2"
uvloop = "0.16.0" uvloop = "0.17.0"
websockets = "10.0" websockets = "11.0.3"
loguru = "0.6.0" loguru = "0.7.2"
grpcio = "1.51.1" grpcio = "1.58.0"
protobuf = "4.21.12" protobuf = "4.24.3"
Cerberus = "1.3.4" Cerberus = "1.3.4"
async-timeout = "4.0.2" async-timeout = "4.0.3"
pyln-client = "23.8" pyln-client = "23.8"
cashu = "0.9.0" pywebpush = "1.14.0"
slowapi = "^0.1.7" slowapi = "0.1.8"
pywebpush = "^1.14.0" python-dotenv = "1.0.0"
websocket-client = "1.6.3"
secp256k1 = "0.14.0"
pycryptodomex = "3.19.0"
packaging = "23.1"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
pytest = "^7.1.2"
black = "^23.7.0" black = "^23.7.0"
pytest-asyncio = "^0.19.0" pytest-asyncio = "^0.21.0"
pytest = "^7.3.2"
pytest-cov = "^4.1.0" pytest-cov = "^4.1.0"
mypy = "^1.5.1" mypy = "^1.5.1"
types-protobuf = "^3.19.22" types-protobuf = "^4.24.0.2"
pre-commit = "^3.2.2" pre-commit = "^3.2.2"
types-mock = "^5.0.0.6" openapi-spec-validator = "^0.6.0"
openapi-spec-validator = "^0.5.5" ruff = "^0.0.291"
ruff = "^0.0.284"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]