fix: read API key for posting tracks, fixes upload from OBS

This commit is contained in:
Paul Bienkowski 2021-12-02 21:00:21 +01:00
parent 6e19411314
commit 5309527c3e
2 changed files with 40 additions and 1 deletions

View file

@ -173,6 +173,44 @@ def require_auth(fn):
return wrapper return wrapper
def read_api_key(fn):
"""
A middleware decorator to read the API Key of a user. It is an opt-in to
allow usage with API Keys on certain urls. Combine with require_auth to
actually check whether a user was authenticated through this. If a login
session exists, the api key is ignored.
"""
@wraps(fn)
async def wrapper(req, *args, **kwargs):
# try to parse a token if one exists, unless a user is already authenticated
if (
not req.ctx.user
and isinstance(req.token, str)
and req.token.lower().startswith("obsuserid ")
):
try:
api_key = req.token.split()[1]
except LookupError:
api_key = None
if api_key:
user = (
await req.ctx.db.execute(
select(User).where(User.api_key == api_key.strip())
)
).scalar()
if not user:
raise Unauthorized("invalid OBSUserId token")
req.ctx.user = user
return await fn(req, *args, **kwargs)
return wrapper
class CustomJsonEncoder(JSONEncoder): class CustomJsonEncoder(JSONEncoder):
def default(self, obj): def default(self, obj):
if isinstance(obj, (datetime, date)): if isinstance(obj, (datetime, date)):

View file

@ -7,7 +7,7 @@ from sqlalchemy import select, func
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from obs.api.db import Track, User, Comment from obs.api.db import Track, User, Comment
from obs.api.app import api, require_auth, json from obs.api.app import api, require_auth, read_api_key, json
from sanic.response import file_stream, empty from sanic.response import file_stream, empty
from sanic.exceptions import InvalidUsage, NotFound, Forbidden from sanic.exceptions import InvalidUsage, NotFound, Forbidden
@ -85,6 +85,7 @@ async def get_feed(req, limit: int = 20, offset: int = 0):
@api.post("/tracks") @api.post("/tracks")
@read_api_key
@require_auth @require_auth
async def post_track(req): async def post_track(req):
try: try: