|
39 | 39 |
|
40 | 40 | from iris.cluster.controller.actor_proxy import PROXY_ROUTE, ActorProxy |
41 | 41 | from iris.cluster.controller.service import ControllerServiceImpl |
42 | | -from iris.cluster.dashboard_common import html_shell, on_shutdown, static_files_mount |
| 42 | +from iris.cluster.dashboard_common import ( |
| 43 | + _AUTH_POLICY_ATTR, |
| 44 | + favicon_route, |
| 45 | + html_shell, |
| 46 | + on_shutdown, |
| 47 | + public, |
| 48 | + requires_auth, |
| 49 | + static_files_mount, |
| 50 | +) |
43 | 51 | from iris.log_server.client import LogServiceProxy |
44 | 52 | from iris.log_server.server import LogServiceImpl |
45 | 53 | from iris.rpc.auth import SESSION_COOKIE, NullAuthInterceptor, TokenVerifier, extract_bearer_token, resolve_auth |
|
52 | 60 |
|
53 | 61 | logger = logging.getLogger(__name__) |
54 | 62 |
|
55 | | -# --------------------------------------------------------------------------- |
56 | | -# Route auth policy annotations |
57 | | -# --------------------------------------------------------------------------- |
58 | | - |
59 | | -_AUTH_POLICY_ATTR = "_auth_policy" |
60 | | - |
61 | | - |
62 | | -def public(fn: Callable) -> Callable: |
63 | | - """Mark a route handler as publicly accessible (no auth required).""" |
64 | | - setattr(fn, _AUTH_POLICY_ATTR, "public") |
65 | | - return fn |
66 | | - |
67 | | - |
68 | | -def requires_auth(fn: Callable) -> Callable: |
69 | | - """Mark a route handler as requiring authentication via session cookie or Bearer token.""" |
70 | | - setattr(fn, _AUTH_POLICY_ATTR, "requires_auth") |
71 | | - return fn |
72 | | - |
73 | | - |
74 | 63 | def _extract_token_from_scope(scope: Scope) -> str | None: |
75 | 64 | """Extract auth token from ASGI scope (cookie or Authorization header).""" |
76 | 65 | headers: dict[str, str] = {k.decode(): v.decode() for k, v in scope.get("headers", [])} |
@@ -318,6 +307,7 @@ async def _proxy_actor_rpc(request: Request) -> Response: |
318 | 307 |
|
319 | 308 | routes = [ |
320 | 309 | Route("/", self._dashboard), |
| 310 | + favicon_route(), |
321 | 311 | Route("/auth/session_bootstrap", self._session_bootstrap), |
322 | 312 | Route("/auth/config", self._auth_config), |
323 | 313 | Route("/auth/session", self._auth_session, methods=["POST"]), |
@@ -484,6 +474,7 @@ def app(self) -> Starlette: |
484 | 474 | def _create_app(self) -> Starlette: |
485 | 475 | routes = [ |
486 | 476 | Route("/", self._dashboard), |
| 477 | + favicon_route(), |
487 | 478 | Route("/job/{job_id:path}", self._job_detail_page), |
488 | 479 | Route("/worker/{worker_id:path}", self._worker_detail_page), |
489 | 480 | Route("/bundles/{bundle_id:str}.zip", self._proxy_bundle), |
|
0 commit comments