messagefoundry-webconsole 0.2.15__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- messagefoundry_webconsole/__init__.py +128 -0
- messagefoundry_webconsole/_auth.py +841 -0
- messagefoundry_webconsole/_html.py +539 -0
- messagefoundry_webconsole/_security.py +253 -0
- messagefoundry_webconsole/_service.py +22 -0
- messagefoundry_webconsole/_static.py +78 -0
- messagefoundry_webconsole/mount.py +103 -0
- messagefoundry_webconsole/pages/__init__.py +25 -0
- messagefoundry_webconsole/pages/_common.py +21 -0
- messagefoundry_webconsole/pages/account.py +771 -0
- messagefoundry_webconsole/pages/admin.py +480 -0
- messagefoundry_webconsole/pages/audit.py +66 -0
- messagefoundry_webconsole/pages/config.py +113 -0
- messagefoundry_webconsole/pages/connections.py +519 -0
- messagefoundry_webconsole/pages/messages.py +689 -0
- messagefoundry_webconsole/pages/monitoring.py +853 -0
- messagefoundry_webconsole/pages/uploaded_logs.py +252 -0
- messagefoundry_webconsole/routes/__init__.py +6 -0
- messagefoundry_webconsole/routes/_common.py +45 -0
- messagefoundry_webconsole/routes/account.py +451 -0
- messagefoundry_webconsole/routes/admin.py +505 -0
- messagefoundry_webconsole/routes/audit.py +39 -0
- messagefoundry_webconsole/routes/config.py +67 -0
- messagefoundry_webconsole/routes/connection_writes.py +248 -0
- messagefoundry_webconsole/routes/core.py +1077 -0
- messagefoundry_webconsole/routes/monitoring.py +94 -0
- messagefoundry_webconsole/routes/monitoring_writes.py +205 -0
- messagefoundry_webconsole/routes/oidc.py +172 -0
- messagefoundry_webconsole/routes/search.py +204 -0
- messagefoundry_webconsole/routes/sso.py +88 -0
- messagefoundry_webconsole/routes/status.py +178 -0
- messagefoundry_webconsole/routes/uploaded_logs.py +181 -0
- messagefoundry_webconsole/static/app.css +345 -0
- messagefoundry_webconsole/static/app.js +1506 -0
- messagefoundry_webconsole/static/csp-probe.js +9 -0
- messagefoundry_webconsole-0.2.15.dist-info/METADATA +63 -0
- messagefoundry_webconsole-0.2.15.dist-info/RECORD +40 -0
- messagefoundry_webconsole-0.2.15.dist-info/WHEEL +4 -0
- messagefoundry_webconsole-0.2.15.dist-info/licenses/LICENSE +662 -0
- messagefoundry_webconsole-0.2.15.dist-info/licenses/NOTICE +31 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
# Copyright (C) 2026 MessageFoundry Organization and contributors
|
|
3
|
+
"""MessageFoundry web console — the same-origin browser ops dashboard, mounted onto the engine.
|
|
4
|
+
|
|
5
|
+
A separately-versioned second distribution (``messagefoundry-webconsole``) that the engine MOUNTS
|
|
6
|
+
in-process, same-origin, via one :func:`mount_ui` call from ``create_app``'s ``serve_ui`` tail (Option
|
|
7
|
+
B, ADR 0065). It owns the entire ``/ui`` surface — rendering, the confined ``mf_session`` cookie auth,
|
|
8
|
+
the write-action registry, and every ``/ui`` route — and reaches the reused JSON handlers through the
|
|
9
|
+
typed :class:`~messagefoundry.api._ui_seam.UiDeps` bundle the engine injects. It imports only
|
|
10
|
+
``fastapi``, ``messagefoundry.api.security``/``.models``/``.auth_models``/``._ui_seam``, ``messagefoundry.auth``,
|
|
11
|
+
and the pure ``messagefoundry.parsing`` lib — never ``pipeline``/``store``/``transports``/``config``
|
|
12
|
+
(CLAUDE.md §4).
|
|
13
|
+
|
|
14
|
+
The console pins itself against the engine's :data:`~messagefoundry.api._ui_seam.ENGINE_UI_SEAM` via
|
|
15
|
+
:data:`SUPPORTED_ENGINE_SEAMS` + :func:`assert_engine_seam`, so a NON-MATCHING engine fails LOUD at
|
|
16
|
+
startup (:class:`UiSeamMismatch`) rather than a raw ``TypeError`` from building the deps bundle.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
#: Independent version root (NOT lockstep with the engine — that is the departure from
|
|
24
|
+
#: ``messagefoundry-harness``); its own tag / changelog / PyPI cadence. Starts matched to the engine.
|
|
25
|
+
__version__ = "0.2.15"
|
|
26
|
+
|
|
27
|
+
#: The engine contract versions this console build supports (``api._ui_seam.ENGINE_UI_SEAM``). A pair
|
|
28
|
+
#: outside this set is refused at startup — the runtime backstop behind the PEP 508 compat range.
|
|
29
|
+
# Seam 9 is the S8a console-dashboard lane (#76/#131/#136, ADR 0065 + ADR 0007 amendments): the
|
|
30
|
+
# The console supports EXACTLY the engine seam it was built against — deliberately a single value,
|
|
31
|
+
# not a range (BACKLOG #279, resolved 2026-07-21 in favour of option (b)).
|
|
32
|
+
#
|
|
33
|
+
# It used to accept {2..N}, justified by "every new field has a default, so an older engine still
|
|
34
|
+
# renders on this console". That claim was never tested: CI installs ONE engine (HEAD) and runs the
|
|
35
|
+
# package suite against it, so N-1 of the N accepted seams were exercised by nothing. Worse, the two
|
|
36
|
+
# ways it silently stops being true — a new field WITHOUT a default, or a bare read of a new engine
|
|
37
|
+
# attribute where getattr-with-default was needed — do NOT trip this handshake, because the older
|
|
38
|
+
# engine's seam IS in the accepted set. The failure surfaced as a runtime AttributeError/TypeError on
|
|
39
|
+
# a live console instead of a loud refusal at startup, which is the opposite of what this gate exists
|
|
40
|
+
# for.
|
|
41
|
+
#
|
|
42
|
+
# Narrowing costs no extra per-bump work: a NEW seam was never in the old set either, so a bump has
|
|
43
|
+
# always required editing BOTH constants. It drops only the untested tail.
|
|
44
|
+
#
|
|
45
|
+
# If cross-seam support is ever genuinely wanted, re-widen this set AND add the CI matrix that
|
|
46
|
+
# installs the MIN and MAX supported engine builds — the claim and its test land together, or not
|
|
47
|
+
# at all.
|
|
48
|
+
SUPPORTED_ENGINE_SEAMS: frozenset[int] = frozenset({15})
|
|
49
|
+
|
|
50
|
+
#: The vendored static assets shipped in THIS wheel (mounted at /ui/static by :func:`mount_ui`).
|
|
51
|
+
STATIC_DIR = Path(__file__).parent / "static"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class UiSeamMismatch(RuntimeError):
|
|
55
|
+
"""Raised when the mounted console does not support the engine's ``ENGINE_UI_SEAM``."""
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def assert_engine_seam(engine_seam: int) -> None:
|
|
59
|
+
"""Fail LOUD if the engine's seam is not one this console supports (called BEFORE the engine
|
|
60
|
+
builds :class:`~messagefoundry.api._ui_seam.UiDeps`, so a skew never surfaces as a raw kwargs
|
|
61
|
+
``TypeError``). A second identical assert runs inside :func:`mount_ui` (belt-and-suspenders)."""
|
|
62
|
+
if engine_seam not in SUPPORTED_ENGINE_SEAMS:
|
|
63
|
+
raise UiSeamMismatch(
|
|
64
|
+
f"web console {__version__} supports engine UI seam(s) "
|
|
65
|
+
f"{sorted(SUPPORTED_ENGINE_SEAMS)}, but the engine provides {engine_seam}; install a "
|
|
66
|
+
"matching messagefoundry-webconsole (see the messagefoundry compat range)."
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
# Re-export the security/rendering surface at the package root (the old ``api.webui`` __init__ shape),
|
|
71
|
+
# so callers/tests reach it as ``messagefoundry_webconsole.{is_safe_ui_action, authorize_ui_ws, ...}``
|
|
72
|
+
# and ``messagefoundry_webconsole.pages``. Both are leaf modules (no cycle with :mod:`.mount`).
|
|
73
|
+
from . import pages # noqa: E402
|
|
74
|
+
from ._auth import ( # noqa: E402
|
|
75
|
+
COOKIE_NAME,
|
|
76
|
+
UI_CSP,
|
|
77
|
+
WEBAUTHN_EXTRA_MISSING_NOTICE,
|
|
78
|
+
WEBAUTHN_RP_CHANGED_NOTICE,
|
|
79
|
+
WEBAUTHN_RP_MISSING_NOTICE,
|
|
80
|
+
UiWriteAction,
|
|
81
|
+
assert_not_cross_site,
|
|
82
|
+
assert_same_origin,
|
|
83
|
+
authorize_ui_ws,
|
|
84
|
+
clear_session_cookie,
|
|
85
|
+
is_safe_ui_action,
|
|
86
|
+
is_unlock_action,
|
|
87
|
+
lookup_ui_action,
|
|
88
|
+
register_ui_action,
|
|
89
|
+
require_ui,
|
|
90
|
+
require_ui_reauth_only,
|
|
91
|
+
require_ui_step_up,
|
|
92
|
+
set_session_cookie,
|
|
93
|
+
webauthn_rp,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Bottom import breaks the __init__ <-> mount cycle: STATIC_DIR / assert_engine_seam above are already
|
|
97
|
+
# bound when mount.py imports them, and mount.py's eager route-module imports fire every
|
|
98
|
+
# register_ui_action so the write-action registry is authoritative before serving.
|
|
99
|
+
from .mount import mount_ui # noqa: E402
|
|
100
|
+
|
|
101
|
+
__all__ = [
|
|
102
|
+
"COOKIE_NAME",
|
|
103
|
+
"STATIC_DIR",
|
|
104
|
+
"SUPPORTED_ENGINE_SEAMS",
|
|
105
|
+
"UI_CSP",
|
|
106
|
+
"WEBAUTHN_EXTRA_MISSING_NOTICE",
|
|
107
|
+
"WEBAUTHN_RP_CHANGED_NOTICE",
|
|
108
|
+
"WEBAUTHN_RP_MISSING_NOTICE",
|
|
109
|
+
"UiSeamMismatch",
|
|
110
|
+
"UiWriteAction",
|
|
111
|
+
"__version__",
|
|
112
|
+
"assert_engine_seam",
|
|
113
|
+
"assert_not_cross_site",
|
|
114
|
+
"assert_same_origin",
|
|
115
|
+
"authorize_ui_ws",
|
|
116
|
+
"clear_session_cookie",
|
|
117
|
+
"is_safe_ui_action",
|
|
118
|
+
"is_unlock_action",
|
|
119
|
+
"lookup_ui_action",
|
|
120
|
+
"mount_ui",
|
|
121
|
+
"pages",
|
|
122
|
+
"register_ui_action",
|
|
123
|
+
"require_ui",
|
|
124
|
+
"require_ui_reauth_only",
|
|
125
|
+
"require_ui_step_up",
|
|
126
|
+
"set_session_cookie",
|
|
127
|
+
"webauthn_rp",
|
|
128
|
+
]
|