# ============================================================================== # Formeleon - Multi-tenant Form Generator # Author: Björn Runden # Module: utils/middleware.py # Description: Custom middlewares and context processors for the Flask app. # ============================================================================== from flask import session, request from typing import Optional from models import db, User, UserRole, Tenant def setup_dev_mode_middleware(app): """ Set up development mode middleware for fake authentication. This middleware injects a fake Zitadel user session when DEV_MODE is enabled, bypassing the need for actual OIDC authentication during development. :param app: Flask application instance """ @app.before_request def inject_dev_user(): """Inject dev user into session if DEV_MODE is enabled.""" # Skip for static files, auth routes, and API routes if (request.path.startswith('/static/') or request.path.startswith('/auth/') or request.path.startswith('/api/')): return # Skip if user is already authenticated if 'user_id' in session: return # Inject dev user dev_user = { 'id': 'user_dev_admin_001', 'email': app.config.get('DEV_USER_EMAIL', 'dev@formeleon.local'), 'name': app.config.get('DEV_USER_NAME', 'Dev Admin'), 'role': app.config.get('DEV_USER_ROLE', 'admin'), 'sub': 'dev-admin-sub-123', 'tenant_id': app.config.get('DEV_TENANT_ID', 'tenant_dev_123'), 'dev_mode': True } session['user_id'] = dev_user['id'] session['user'] = dev_user session.permanent = True # Load or create dev user in database user = User.query.get(dev_user['id']) if not user: role = UserRole.ADMIN if dev_user['role'] == 'admin' else UserRole.USER user = User( id=dev_user['id'], email=dev_user['email'], name=dev_user['name'], role=role, sub=dev_user['sub'] ) db.session.add(user) db.session.commit() # Ensure dev tenant exists tenant = Tenant.query.get(dev_user['tenant_id']) if not tenant: tenant = Tenant( id=dev_user['tenant_id'], name='Development Tenant', public_key='dev-public-key-12345', allowed_origins='*' ) db.session.add(tenant) db.session.commit() def get_current_user() -> Optional[User]: """ Get the current authenticated user from the request context. :return: User object if authenticated, None otherwise """ if 'user_id' not in session: return None return User.query.get(session['user_id']) def get_current_tenant() -> Optional[Tenant]: """ Get the current tenant from the request context. :return: Tenant object if available, None otherwise """ if 'tenant_id' in session: return Tenant.query.get(session['tenant_id']) user = get_current_user() if user and user.tenants: return user.tenants[0] return None