mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-01 04:34:50 -04:00
Validate jwts in the scanner
This commit is contained in:
parent
4a796d2058
commit
d4e5afd514
@ -13,3 +13,13 @@ THEMOVIEDB_API_ACCESS_TOKEN=""
|
|||||||
KYOO_URL="http://api:3567/api"
|
KYOO_URL="http://api:3567/api"
|
||||||
KYOO_APIKEY=""
|
KYOO_APIKEY=""
|
||||||
|
|
||||||
|
JWKS_URL="http://auth:4568/.well-known/jwks.json"
|
||||||
|
JWT_ISSUER=$PUBLIC_URL
|
||||||
|
|
||||||
|
# The behavior of the below variables match what is documented here:
|
||||||
|
# https://www.postgresql.org/docs/current/libpq-envars.html
|
||||||
|
PGUSER=kyoo
|
||||||
|
PGPASSWORD=password
|
||||||
|
PGDATABASE=kyooDB
|
||||||
|
PGHOST=postgres
|
||||||
|
PGPORT=5432
|
||||||
|
@ -5,3 +5,4 @@ aiohttp
|
|||||||
watchfiles
|
watchfiles
|
||||||
langcodes
|
langcodes
|
||||||
asyncpg
|
asyncpg
|
||||||
|
pyjwt[crypto]
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
from typing import Annotated
|
||||||
|
|
||||||
import asyncpg
|
import asyncpg
|
||||||
from fastapi import BackgroundTasks, FastAPI
|
from fastapi import BackgroundTasks, FastAPI, Security
|
||||||
|
|
||||||
from .client import KyooClient
|
from .client import KyooClient
|
||||||
from .fsscan import Scanner
|
from .fsscan import Scanner
|
||||||
|
from .jwt import validate_bearer
|
||||||
from .providers.composite import CompositeProvider
|
from .providers.composite import CompositeProvider
|
||||||
from .providers.themoviedatabase import TheMovieDatabase
|
from .providers.themoviedatabase import TheMovieDatabase
|
||||||
from .requests import RequestCreator, RequestProcessor
|
from .requests import RequestCreator, RequestProcessor
|
||||||
@ -71,8 +73,13 @@ app = FastAPI(
|
|||||||
@app.put(
|
@app.put(
|
||||||
"/scan",
|
"/scan",
|
||||||
status_code=204,
|
status_code=204,
|
||||||
description="Trigger a full scan of the filesystem, trying to find new videos & deleting old ones.",
|
|
||||||
response_description="Scan started.",
|
response_description="Scan started.",
|
||||||
)
|
)
|
||||||
async def trigger_scan(tasks: BackgroundTasks):
|
async def trigger_scan(
|
||||||
|
tasks: BackgroundTasks,
|
||||||
|
_: Annotated[None, Security(validate_bearer, scopes=["scanner."])],
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Trigger a full scan of the filesystem, trying to find new videos & deleting old ones.
|
||||||
|
"""
|
||||||
tasks.add_task(scanner.scan)
|
tasks.add_task(scanner.scan)
|
||||||
|
41
scanner/scanner/jwt.py
Normal file
41
scanner/scanner/jwt.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import os
|
||||||
|
from typing import Annotated
|
||||||
|
|
||||||
|
import jwt
|
||||||
|
from fastapi import Depends, HTTPException
|
||||||
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer, SecurityScopes
|
||||||
|
from jwt import PyJWKClient
|
||||||
|
|
||||||
|
jwks_client = PyJWKClient(
|
||||||
|
os.environ.get("JWKS_URL", "http://auth:4568/.well-known/jwks.json")
|
||||||
|
)
|
||||||
|
|
||||||
|
security = HTTPBearer(scheme_name="Bearer")
|
||||||
|
|
||||||
|
|
||||||
|
def validate_bearer(
|
||||||
|
token: Annotated[HTTPAuthorizationCredentials, Depends(security)],
|
||||||
|
perms: SecurityScopes,
|
||||||
|
):
|
||||||
|
try:
|
||||||
|
payload = jwt.decode(
|
||||||
|
token.credentials,
|
||||||
|
jwks_client.get_signing_key_from_jwt(token.credentials).key,
|
||||||
|
issuer=os.environ.get("JWT_ISSUER"),
|
||||||
|
)
|
||||||
|
for scope in perms.scopes:
|
||||||
|
if scope not in payload["permissions"]:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=403,
|
||||||
|
detail=f"Missing permissions {', '.join(perms.scopes)}",
|
||||||
|
headers={
|
||||||
|
"WWW-Authenticate": f'Bearer permissions="{",".join(perms.scopes)}"'
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return payload
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=403,
|
||||||
|
detail="Could not validate credentials",
|
||||||
|
headers={"WWW-Authenticate": "Bearer"},
|
||||||
|
) from e
|
@ -8,6 +8,7 @@
|
|||||||
watchfiles
|
watchfiles
|
||||||
langcodes
|
langcodes
|
||||||
asyncpg
|
asyncpg
|
||||||
|
pyjwt
|
||||||
]);
|
]);
|
||||||
in
|
in
|
||||||
pkgs.mkShell {
|
pkgs.mkShell {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user