# Written by retoor@molodetz.nl

# This code provides middleware functions for an aiohttp server to manage and modify CSP, CORS, and authentication headers.

import secrets
from aiohttp import web


@web.middleware
async def csp_middleware(request, handler):
    nonce = secrets.token_hex(16)
    origin = request.headers.get('Origin')
    csp_policy = (
        "default-src 'self'; "
        f"script-src 'self' {origin} 'nonce-{nonce}'; "
        f"style-src 'self' 'unsafe-inline' {origin} 'nonce-{nonce}'; "
        "img-src *; "
        "connect-src 'self' https://umami.molodetz.nl; "
        "font-src *; "
        "object-src 'none'; "
        "base-uri 'self'; "
        "form-action 'self'; "
        "frame-src 'self'; "
        "worker-src *; "
        "media-src *; "
        "manifest-src 'self';"
    )
    request['csp_nonce'] = nonce
    response = await handler(request)
    #response.headers['Content-Security-Policy'] = csp_policy
    return response


@web.middleware
async def no_cors_middleware(request, handler):
    response = await handler(request)
    response.headers.pop("Access-Control-Allow-Origin", None)
    return response

@web.middleware
async def cors_allow_middleware(request, handler):
    response = await handler(request)
    response.headers["Access-Control-Allow-Origin"] = "*"
    response.headers["Access-Control-Allow-Methods"] = (
        "GET, POST, OPTIONS, PUT, DELETE, MOVE, COPY, HEAD, LOCK, UNLOCK, PATCH, PROPFIND"
    )
    response.headers["Access-Control-Allow-Headers"] = "*"
    response.headers["Access-Control-Allow-Credentials"] = "true"
    return response

@web.middleware
async def auth_middleware(request, handler):
    request["user"] = None
    if request.session.get("uid") and request.session.get("logged_in"):
        request["user"] = await request.app.services.user.get(
            uid=request.app.session.get("uid")
        )
    return await handler(request)

@web.middleware
async def cors_middleware(request, handler):
    if request.headers.get("Allow"):
        return await handler(request)

    response = await handler(request)
    if request.headers.get("Allow"):
        return response
    response.headers["Access-Control-Allow-Origin"] = "*"
    response.headers["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
    response.headers["Access-Control-Allow-Headers"] = "*"
    response.headers["Access-Control-Allow-Credentials"] = "true"
 
    return response
