Files
eveAI/common/utils/cors_utils.py

85 lines
3.0 KiB
Python

from flask import request, current_app, session
from flask_jwt_extended import decode_token, verify_jwt_in_request, get_jwt_identity
from common.models.user import Tenant, TenantDomain
def get_allowed_origins(tenant_id):
session_key = f"allowed_origins_{tenant_id}"
if session_key in session:
return session[session_key]
tenant_domains = TenantDomain.query.filter_by(tenant_id=int(tenant_id)).all()
allowed_origins = [domain.domain for domain in tenant_domains]
# Cache the result in the session
session[session_key] = allowed_origins
return allowed_origins
def cors_after_request(response, prefix):
# Exclude health checks from checks
if request.path.startswith('/healthz') or request.path.startswith('/_healthz'):
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', '*')
response.headers.add('Access-Control-Allow-Methods', '*')
return response
# Handle OPTIONS preflight requests
if request.method == 'OPTIONS':
response.headers.add('Access-Control-Allow-Origin', '*')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization,X-Tenant-ID')
response.headers.add('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS')
response.headers.add('Access-Control-Allow-Credentials', 'true')
return response
tenant_id = None
allowed_origins = []
# Check Socket.IO connection
if 'socket.io' in request.path:
token = request.args.get('token')
if token:
try:
decoded = decode_token(token)
tenant_id = decoded['sub']
except Exception as e:
current_app.logger.error(f'Error decoding token: {e}')
return response
else:
# Regular API requests
try:
if verify_jwt_in_request(optional=True):
tenant_id = get_jwt_identity()
except Exception as e:
current_app.logger.error(f'Error verifying JWT: {e}')
return response
if tenant_id:
origin = request.headers.get('Origin')
allowed_origins = get_allowed_origins(tenant_id)
if origin in allowed_origins:
response.headers.add('Access-Control-Allow-Origin', origin)
response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS')
response.headers.add('Access-Control-Allow-Credentials', 'true')
return response
def create_cors_after_request(prefix):
def wrapped_cors_after_request(response):
return cors_after_request(response, prefix)
return wrapped_cors_after_request
def create_multiple_cors_after_requests(prefixes):
def wrapped_cors_after_requests(response):
for prefix, cors_function in prefixes:
response = cors_function(response)
return response
return wrapped_cors_after_requests