mirror of
https://github.com/aljazceru/nutshell.git
synced 2025-12-20 10:34:20 +01:00
Blind authentication (#675)
* auth server * cleaning up * auth ledger class * class variables -> instance variables * annotations * add models and api route * custom amount and api prefix * add auth db * blind auth token working * jwt working * clean up * JWT works * using openid connect server * use oauth server with password flow * new realm * add keycloak docker * hopefully not garbage * auth works * auth kinda working * fix cli * auth works for send and receive * pass auth_db to Wallet * auth in info * refactor * fix supported * cache mint info * fix settings and endpoints * add description to .env.example * track changes for openid connect client * store mint in db * store credentials * clean up v1_api.py * load mint info into auth wallet * fix first login * authenticate if refresh token fails * clear auth also middleware * use regex * add cli command * pw works * persist keyset amounts * add errors.py * do not start auth server if disabled in config * upadte poetry * disvoery url * fix test * support device code flow * adopt latest spec changes * fix code flow * mint max bat dynamic * mypy ignore * fix test * do not serialize amount in authproof * all auth flows working * fix tests * submodule * refactor * test * dont sleep * test * add wallet auth tests * test differently * test only keycloak for now * fix creds * daemon * fix test * install everything * install jinja * delete wallet for every test * auth: use global rate limiter * test auth rate limit * keycloak hostname * move keycloak test data * reactivate all tests * add readme * load proofs * remove unused code * remove unused code * implement change suggestions by ok300 * add error codes * test errors
This commit is contained in:
@@ -10,7 +10,10 @@ from fastapi.exception_handlers import (
|
||||
from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import JSONResponse
|
||||
from loguru import logger
|
||||
from starlette.middleware.base import BaseHTTPMiddleware
|
||||
from starlette.middleware.base import (
|
||||
BaseHTTPMiddleware,
|
||||
RequestResponseEndpoint,
|
||||
)
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
|
||||
from ..core.settings import settings
|
||||
@@ -22,6 +25,8 @@ if settings.debug_profiling:
|
||||
from slowapi.errors import RateLimitExceeded
|
||||
from slowapi.middleware import SlowAPIMiddleware
|
||||
|
||||
from .startup import auth_ledger
|
||||
|
||||
|
||||
def add_middlewares(app: FastAPI):
|
||||
app.add_middleware(
|
||||
@@ -42,6 +47,52 @@ def add_middlewares(app: FastAPI):
|
||||
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
|
||||
app.add_middleware(SlowAPIMiddleware)
|
||||
|
||||
if settings.mint_require_auth:
|
||||
app.add_middleware(BlindAuthMiddleware)
|
||||
app.add_middleware(ClearAuthMiddleware)
|
||||
|
||||
|
||||
class ClearAuthMiddleware(BaseHTTPMiddleware):
|
||||
async def dispatch(
|
||||
self, request: Request, call_next: RequestResponseEndpoint
|
||||
) -> Response:
|
||||
if (
|
||||
settings.mint_require_auth
|
||||
and auth_ledger.mint_info.requires_clear_auth_path(
|
||||
method=request.method, path=request.url.path
|
||||
)
|
||||
):
|
||||
clear_auth_token = request.headers.get("clear-auth")
|
||||
if not clear_auth_token:
|
||||
raise Exception("Missing clear auth token.")
|
||||
try:
|
||||
user = await auth_ledger.verify_clear_auth(
|
||||
clear_auth_token=clear_auth_token
|
||||
)
|
||||
request.state.user = user
|
||||
except Exception as e:
|
||||
raise e
|
||||
return await call_next(request)
|
||||
|
||||
|
||||
class BlindAuthMiddleware(BaseHTTPMiddleware):
|
||||
async def dispatch(
|
||||
self, request: Request, call_next: RequestResponseEndpoint
|
||||
) -> Response:
|
||||
if (
|
||||
settings.mint_require_auth
|
||||
and auth_ledger.mint_info.requires_blind_auth_path(
|
||||
method=request.method, path=request.url.path
|
||||
)
|
||||
):
|
||||
blind_auth_token = request.headers.get("blind-auth")
|
||||
if not blind_auth_token:
|
||||
raise Exception("Missing blind auth token.")
|
||||
async with auth_ledger.verify_blind_auth(blind_auth_token):
|
||||
return await call_next(request)
|
||||
else:
|
||||
return await call_next(request)
|
||||
|
||||
|
||||
async def request_validation_exception_handler(
|
||||
request: Request, exc: RequestValidationError
|
||||
@@ -66,11 +117,11 @@ class CompressionMiddleware(BaseHTTPMiddleware):
|
||||
response = await call_next(request)
|
||||
|
||||
# Handle streaming responses differently
|
||||
if response.__class__.__name__ == 'StreamingResponse':
|
||||
if response.__class__.__name__ == "StreamingResponse":
|
||||
return response
|
||||
|
||||
response_body = b''
|
||||
async for chunk in response.body_iterator:
|
||||
response_body = b""
|
||||
async for chunk in response.body_iterator: # type: ignore
|
||||
response_body += chunk
|
||||
|
||||
accept_encoding = request.headers.get("Accept-Encoding", "")
|
||||
@@ -97,5 +148,5 @@ class CompressionMiddleware(BaseHTTPMiddleware):
|
||||
content=content,
|
||||
status_code=response.status_code,
|
||||
headers=dict(response.headers),
|
||||
media_type=response.media_type
|
||||
media_type=response.media_type,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user