fix: lndhub auth handling

This commit is contained in:
Stefan Stammberger 2021-10-15 19:55:24 +02:00
parent 6dea1f7271
commit 570e8d28dd
No known key found for this signature in database
GPG key ID: 645FA807E935D9D5
3 changed files with 29 additions and 42 deletions

View file

@ -15,6 +15,7 @@ from fastapi.params import Security
from fastapi.security.api_key import APIKeyHeader, APIKeyQuery from fastapi.security.api_key import APIKeyHeader, APIKeyQuery
from fastapi.security import OAuth2PasswordBearer from fastapi.security import OAuth2PasswordBearer
from fastapi.security.base import SecurityBase from fastapi.security.base import SecurityBase
from fastapi import status
from starlette.requests import Request from starlette.requests import Request
from lnbits.core.crud import get_user, get_wallet_for_key from lnbits.core.crud import get_user, get_wallet_for_key
@ -84,24 +85,19 @@ class WalletTypeInfo():
self.wallet_type = wallet_type self.wallet_type = wallet_type
self.wallet = wallet self.wallet = wallet
api_key_header_xapi = APIKeyHeader(name="X-API-KEY", auto_error=False, description="Admin or Invoice key for wallet API's") api_key_header = APIKeyHeader(name="X-API-KEY", auto_error=False, description="Admin or Invoice key for wallet API's")
api_key_header_auth = APIKeyHeader(name="AUTHORIZATION", auto_error=False, description="Admin or Invoice key for wallet API's")
api_key_query = APIKeyQuery(name="api-key", auto_error=False, description="Admin or Invoice key for wallet API's") api_key_query = APIKeyQuery(name="api-key", auto_error=False, description="Admin or Invoice key for wallet API's")
async def get_key_type(r: Request, async def get_key_type(r: Request,
api_key_header_auth: str = Security(api_key_header_auth), api_key_header: str = Security(api_key_header),
api_key_header: str = Security(api_key_header_auth),
api_key_query: str = Security(api_key_query)) -> WalletTypeInfo: api_key_query: str = Security(api_key_query)) -> WalletTypeInfo:
# 0: admin # 0: admin
# 1: invoice # 1: invoice
# 2: invalid # 2: invalid
# print("TOKEN", b64decode(token).decode("utf-8").split(":"))
if api_key_header_xapi: if not api_key_header and not api_key_query:
token = api_key_header_xapi raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
elif api_key_header_auth:
_, token = b64decode(api_key_header_auth).decode("utf-8").split(":") token = api_key_header if api_key_header else api_key_query
elif api_key_query:
token = api_key_query
try: try:
checker = WalletAdminKeyChecker(api_key=token) checker = WalletAdminKeyChecker(api_key=token)

View file

@ -1,33 +1,24 @@
from base64 import b64decode from base64 import b64decode
from functools import wraps from functools import wraps
from fastapi.param_functions import Security
from fastapi.security.api_key import APIKeyHeader
from lnbits.core.crud import get_wallet_for_key from lnbits.core.crud import get_wallet_for_key
from fastapi import Request from fastapi import Request, status
from http import HTTPStatus
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse, JSONResponse # type: ignore from starlette.responses import HTMLResponse, JSONResponse
from lnbits.decorators import WalletTypeInfo, get_key_type # type: ignore
def check_wallet(requires_admin=False): api_key_header_auth = APIKeyHeader(name="AUTHORIZATION", auto_error=False, description="Admin or Invoice key for LNDHub API's")
def wrap(view): async def check_wallet(r: Request, api_key_header_auth: str = Security(api_key_header_auth)) -> WalletTypeInfo:
@wraps(view) if not api_key_header_auth:
async def wrapped_view(request: Request, **kwargs): raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
token = request.headers["Authorization"].split("Bearer ")[1]
key_type, key = b64decode(token).decode("utf-8").split(":")
if requires_admin and key_type != "admin": t = api_key_header_auth.split(" ")[1]
raise HTTPException( _, token = b64decode(t).decode("utf-8").split(":")
status_code=HTTPStatus.FORBIDDEN,
detail="insufficient permissions",
)
g.wallet = await get_wallet_for_key(key, key_type)
if not g.wallet:
raise HTTPException(
status_code=HTTPStatus.FORBIDDEN,
detail="insufficient permissions",
)
return await view(**kwargs)
return wrapped_view return await get_key_type(r, api_key_header=token)
return wrap

View file

@ -4,7 +4,7 @@ from pydantic import BaseModel
from lnbits.core.services import pay_invoice, create_invoice from lnbits.core.services import pay_invoice, create_invoice
from lnbits.core.crud import get_payments, delete_expired_invoices from lnbits.core.crud import get_payments, delete_expired_invoices
from lnbits.decorators import api_validate_post_request, WalletTypeInfo, get_key_type from lnbits.decorators import WalletTypeInfo
from lnbits.settings import WALLET from lnbits.settings import WALLET
from lnbits import bolt11 from lnbits import bolt11
@ -52,7 +52,7 @@ class AddInvoice(BaseModel):
@lndhub_ext.post("/ext/addinvoice") @lndhub_ext.post("/ext/addinvoice")
async def lndhub_addinvoice( async def lndhub_addinvoice(
data: AddInvoice, data: AddInvoice,
wallet: WalletTypeInfo = Depends(get_key_type) wallet: WalletTypeInfo = Depends(check_wallet)
): ):
try: try:
_, pr = await create_invoice( _, pr = await create_invoice(
@ -79,7 +79,7 @@ async def lndhub_addinvoice(
@lndhub_ext.post("/ext/payinvoice") @lndhub_ext.post("/ext/payinvoice")
async def lndhub_payinvoice( async def lndhub_payinvoice(
wallet: WalletTypeInfo = Depends(get_key_type), invoice: str = Query(None) wallet: WalletTypeInfo = Depends(check_wallet), invoice: str = Query(None)
): ):
try: try:
await pay_invoice( await pay_invoice(
@ -112,7 +112,7 @@ async def lndhub_payinvoice(
@lndhub_ext.get("/ext/balance") @lndhub_ext.get("/ext/balance")
# @check_wallet() # @check_wallet()
async def lndhub_balance( async def lndhub_balance(
wallet: WalletTypeInfo = Depends(get_key_type), wallet: WalletTypeInfo = Depends(check_wallet),
): ):
return {"BTC": {"AvailableBalance": wallet.wallet.balance}} return {"BTC": {"AvailableBalance": wallet.wallet.balance}}
@ -120,7 +120,7 @@ async def lndhub_balance(
@lndhub_ext.get("/ext/gettxs") @lndhub_ext.get("/ext/gettxs")
# @check_wallet() # @check_wallet()
async def lndhub_gettxs( async def lndhub_gettxs(
wallet: WalletTypeInfo = Depends(get_key_type), limit: int = Query(0, ge=0, lt=200) wallet: WalletTypeInfo = Depends(check_wallet), limit: int = Query(0, ge=0, lt=200)
): ):
print("WALLET", wallet) print("WALLET", wallet)
for payment in await get_payments( for payment in await get_payments(
@ -161,7 +161,7 @@ async def lndhub_gettxs(
@lndhub_ext.get("/ext/getuserinvoices") @lndhub_ext.get("/ext/getuserinvoices")
async def lndhub_getuserinvoices( async def lndhub_getuserinvoices(
wallet: WalletTypeInfo = Depends(get_key_type), limit: int = Query(0, ge=0, lt=200) wallet: WalletTypeInfo = Depends(check_wallet), limit: int = Query(0, ge=0, lt=200)
): ):
await delete_expired_invoices() await delete_expired_invoices()
for invoice in await get_payments( for invoice in await get_payments(
@ -203,7 +203,7 @@ async def lndhub_getuserinvoices(
@lndhub_ext.get("/ext/getbtc") @lndhub_ext.get("/ext/getbtc")
async def lndhub_getbtc(wallet: WalletTypeInfo = Depends(get_key_type)): async def lndhub_getbtc(wallet: WalletTypeInfo = Depends(check_wallet)):
"load an address for incoming onchain btc" "load an address for incoming onchain btc"
return [] return []