""" Portal SSO middleware for DigiServer v2. When the umbrella nginx verifies the portal JWT it sets two headers: X-Auth-Username — the portal username X-Auth-Role — 'admin' or 'user' This before_request handler reads those headers and auto-logs in the corresponding local DigiServer user, creating them on first access if needed. The local session is then maintained normally by Flask-Login. """ import secrets from flask import request from flask_login import login_user, current_user def init_portal_sso(app): """Register the SSO before_request handler on the given Flask app.""" @app.before_request def _portal_sso(): if current_user.is_authenticated: return username = request.headers.get('X-Auth-Username', '').strip() if not username: return role = request.headers.get('X-Auth-Role', 'user').strip() user = _get_or_create_user(username, role) if user: login_user(user, remember=False) def _get_or_create_user(username, role): from app.models.user import User from app.extensions import db, bcrypt try: target_role = 'admin' if role == 'admin' else 'user' user = User.query.filter_by(username=username).first() if not user: hashed_pw = bcrypt.generate_password_hash(secrets.token_hex(32)).decode('utf-8') user = User( username=username, password=hashed_pw, role=target_role, ) db.session.add(user) db.session.commit() elif user.role != target_role: # Role changed in portal → sync it here immediately user.role = target_role db.session.commit() return user except Exception: return None