""" Enhanced Dashboard with User Management UI =========================================== Provides a comprehensive web interface for managing users and API keys. Vue 3 compatible. """ import os import time import hashlib from starlette.requests import Request from starlette.responses import HTMLResponse, JSONResponse _STATIC_API_KEY = os.environ.get("GATEWAY_STATIC_API_KEY", "") def _admin_require_auth(request: Request): """Returns None if authorized, or a 401 JSONResponse if not.""" auth_header = request.headers.get("Authorization", "") if not auth_header.startswith("Bearer "): return JSONResponse({"error": "unauthorized"}, status_code=401) token = auth_header[7:] if _STATIC_API_KEY and token == _STATIC_API_KEY: return None try: from gateway_proxy import ACCESS_TOKENS token_hash = hashlib.sha256(token.encode()).hexdigest() info = ACCESS_TOKENS.get(token_hash) if info and info["expires_at"] >= time.time(): return None except ImportError: pass return JSONResponse({"error": "unauthorized"}, status_code=401) USER_DASHBOARD_HTML = """ MCP Gateway Admin

Gateway Status

Healthy Services
{{ servicesHealthy }}/{{ services.length }}
Total Tools Available
{{ totalTools }}

MCP Services

Loading services...
{{ svc.name }}
{{ svc.toolCount }} tools • {{ svc.responseTime }}ms
{{ svc.status }}
Auto-refreshes every 10s

User Management

Create New User

{{ createMsg.text }}

Users ({{ users.length }})

No users yet. Create one above.
{{ user.username }} {{ user.email }}
Created {{ formatDate(user.created_at) }}
{{ user.enabled ? 'ENABLED' : 'DISABLED' }}

API Keys

No API keys yet.
{{ key.key_name || 'Unnamed key' }}
Created {{ formatDate(key.created_at) }} • Expires {{ formatDate(key.expires_at) }}
REVOKED

MCP Access Control

Leave both empty = access to all MCPs. Toggle to explicitly allow or block.

Allowed MCPs (only these are accessible)
Blocked MCPs (these are always denied)

API Documentation

Create User

POST /users
{ "username": "alice", "email": "alice@example.com", "description": "Engineering" }

Generate API Key

POST /users/{username}/keys
{ "key_name": "my-key", "ttl_days": 90 }
=> { "api_key": "mcpgw_..." }  ← save immediately, shown once

Set MCP Access

PUT /users/{username}/mcp-access
{ "allowed_mcps": ["erpnext", "wave"], "blocked_mcps": [] }

Using an API Key with Claude

MCP Server URL: https://mcp.wilddragon.net/mcp
Authorization:  Bearer mcpgw_...
""" async def user_management_dashboard(request: Request): """Serve the user management dashboard. Requires Bearer token auth.""" if (err := _admin_require_auth(request)): return err return HTMLResponse(USER_DASHBOARD_HTML)