2020-04-26 13:28:19 +02:00
|
|
|
from cerberus import Validator # type: ignore
|
2020-09-14 02:31:05 +02:00
|
|
|
from quart import g, abort, jsonify, request
|
2020-03-04 23:11:15 +01:00
|
|
|
from functools import wraps
|
2020-05-03 15:57:05 +02:00
|
|
|
from http import HTTPStatus
|
2020-03-04 23:11:15 +01:00
|
|
|
from typing import List, Union
|
|
|
|
from uuid import UUID
|
|
|
|
|
|
|
|
from lnbits.core.crud import get_user, get_wallet_for_key
|
2020-09-05 08:00:44 +02:00
|
|
|
from lnbits.settings import LNBITS_ALLOWED_USERS
|
2020-03-04 23:11:15 +01:00
|
|
|
|
|
|
|
|
2020-10-15 05:18:56 +02:00
|
|
|
def api_check_wallet_key(key_type: str = "invoice", accept_querystring=False):
|
2020-03-04 23:11:15 +01:00
|
|
|
def wrap(view):
|
|
|
|
@wraps(view)
|
2020-09-14 02:31:05 +02:00
|
|
|
async def wrapped_view(**kwargs):
|
2020-03-04 23:11:15 +01:00
|
|
|
try:
|
2020-10-15 05:18:56 +02:00
|
|
|
key_value = request.headers.get("X-Api-Key") or request.args["api-key"]
|
2020-11-21 22:04:39 +01:00
|
|
|
g.wallet = await get_wallet_for_key(key_value, key_type)
|
2020-03-04 23:11:15 +01:00
|
|
|
except KeyError:
|
2020-09-03 23:02:15 +02:00
|
|
|
return (
|
|
|
|
jsonify({"message": "`X-Api-Key` header missing."}),
|
|
|
|
HTTPStatus.BAD_REQUEST,
|
|
|
|
)
|
2020-03-04 23:11:15 +01:00
|
|
|
|
|
|
|
if not g.wallet:
|
2020-05-03 15:57:05 +02:00
|
|
|
return jsonify({"message": "Wrong keys."}), HTTPStatus.UNAUTHORIZED
|
2020-03-04 23:11:15 +01:00
|
|
|
|
2020-09-14 02:31:05 +02:00
|
|
|
return await view(**kwargs)
|
2020-03-04 23:11:15 +01:00
|
|
|
|
|
|
|
return wrapped_view
|
|
|
|
|
|
|
|
return wrap
|
|
|
|
|
|
|
|
|
2020-04-11 19:47:25 +02:00
|
|
|
def api_validate_post_request(*, schema: dict):
|
2020-03-04 23:11:15 +01:00
|
|
|
def wrap(view):
|
|
|
|
@wraps(view)
|
2020-09-14 02:31:05 +02:00
|
|
|
async def wrapped_view(**kwargs):
|
2020-03-04 23:11:15 +01:00
|
|
|
if "application/json" not in request.headers["Content-Type"]:
|
2020-09-03 23:02:15 +02:00
|
|
|
return (
|
|
|
|
jsonify({"message": "Content-Type must be `application/json`."}),
|
|
|
|
HTTPStatus.BAD_REQUEST,
|
|
|
|
)
|
2020-03-04 23:11:15 +01:00
|
|
|
|
2020-04-11 19:47:25 +02:00
|
|
|
v = Validator(schema)
|
2020-09-14 02:31:05 +02:00
|
|
|
data = await request.get_json()
|
|
|
|
g.data = {key: data[key] for key in schema.keys() if key in data}
|
2020-03-04 23:11:15 +01:00
|
|
|
|
2020-04-11 19:47:25 +02:00
|
|
|
if not v.validate(g.data):
|
2020-09-03 23:02:15 +02:00
|
|
|
return (
|
|
|
|
jsonify({"message": f"Errors in request data: {v.errors}"}),
|
|
|
|
HTTPStatus.BAD_REQUEST,
|
|
|
|
)
|
2020-03-04 23:11:15 +01:00
|
|
|
|
2020-09-14 02:31:05 +02:00
|
|
|
return await view(**kwargs)
|
2020-03-04 23:11:15 +01:00
|
|
|
|
|
|
|
return wrapped_view
|
|
|
|
|
|
|
|
return wrap
|
|
|
|
|
|
|
|
|
|
|
|
def check_user_exists(param: str = "usr"):
|
|
|
|
def wrap(view):
|
|
|
|
@wraps(view)
|
2020-09-14 02:31:05 +02:00
|
|
|
async def wrapped_view(**kwargs):
|
2020-11-21 22:04:39 +01:00
|
|
|
g.user = await get_user(request.args.get(param, type=str)) or abort(
|
|
|
|
HTTPStatus.NOT_FOUND, "User does not exist."
|
|
|
|
)
|
2020-05-09 22:30:33 +02:00
|
|
|
|
2020-09-05 08:00:44 +02:00
|
|
|
if LNBITS_ALLOWED_USERS and g.user.id not in LNBITS_ALLOWED_USERS:
|
2020-06-13 03:46:40 +02:00
|
|
|
abort(HTTPStatus.UNAUTHORIZED, "User not authorized.")
|
2020-05-09 22:30:33 +02:00
|
|
|
|
2020-09-14 02:31:05 +02:00
|
|
|
return await view(**kwargs)
|
2020-03-04 23:11:15 +01:00
|
|
|
|
|
|
|
return wrapped_view
|
|
|
|
|
|
|
|
return wrap
|
|
|
|
|
|
|
|
|
|
|
|
def validate_uuids(params: List[str], *, required: Union[bool, List[str]] = False, version: int = 4):
|
|
|
|
def wrap(view):
|
|
|
|
@wraps(view)
|
2020-09-14 02:31:05 +02:00
|
|
|
async def wrapped_view(**kwargs):
|
2020-03-04 23:11:15 +01:00
|
|
|
query_params = {param: request.args.get(param, type=str) for param in params}
|
|
|
|
|
|
|
|
for param, value in query_params.items():
|
|
|
|
if not value and (required is True or (required and param in required)):
|
2020-05-03 15:57:05 +02:00
|
|
|
abort(HTTPStatus.BAD_REQUEST, f"`{param}` is required.")
|
2020-03-04 23:11:15 +01:00
|
|
|
|
|
|
|
if value:
|
|
|
|
try:
|
|
|
|
UUID(value, version=version)
|
|
|
|
except ValueError:
|
2020-05-03 15:57:05 +02:00
|
|
|
abort(HTTPStatus.BAD_REQUEST, f"`{param}` is not a valid UUID.")
|
2020-03-04 23:11:15 +01:00
|
|
|
|
2020-09-14 02:31:05 +02:00
|
|
|
return await view(**kwargs)
|
2020-03-04 23:11:15 +01:00
|
|
|
|
|
|
|
return wrapped_view
|
|
|
|
|
|
|
|
return wrap
|