From a8baa2aa4939f3b0b6134b7c8ab13b2c072d70ca Mon Sep 17 00:00:00 2001 From: Mikhail Date: Sun, 17 May 2026 00:04:12 +0300 Subject: [PATCH] Add HTML5 object access context --- services/api-server/src/api_server/html5.py | 29 +++++++++++++++++++-- services/api-server/src/api_server/main.py | 3 ++- services/api-server/tests/test_api.py | 5 ++++ 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/services/api-server/src/api_server/html5.py b/services/api-server/src/api_server/html5.py index 6f59f5c..52bc319 100644 --- a/services/api-server/src/api_server/html5.py +++ b/services/api-server/src/api_server/html5.py @@ -316,7 +316,12 @@ def render_html5_review(project_id: str, findings: list[dict] | None) -> str: """ -def render_html5_object_context(project_id: str, schema: object | None, impact: object | None) -> str: +def render_html5_object_context( + project_id: str, + schema: object | None, + impact: object | None, + access: object | None = None, +) -> str: if schema is None or impact is None: return f"""
@@ -333,6 +338,7 @@ def render_html5_object_context(project_id: str, schema: object | None, impact: forms = getattr(impact, "forms", []) or [] roles = getattr(impact, "roles", []) or [] jobs = getattr(impact, "jobs", []) or [] + grants = getattr(access, "grants", []) if access is not None else [] return f"""
Object context
@@ -346,11 +352,12 @@ def render_html5_object_context(project_id: str, schema: object | None, impact: {_metric("Modules", len(modules))} {_metric("Routines", len(routines))} {_metric("Forms", len(forms))} - {_metric("Roles", len(roles))} + {_metric("Roles", len(grants) or len(roles))}
{''.join(_named_node_item("attr", item) for item in attributes[:6]) or '

Реквизиты не найдены

'} {''.join(_tabular_section_item(item) for item in sections[:4])} + {''.join(_role_access_item(item) for item in grants[:6])} {''.join(_named_node_item("routine", item) for item in routines[:6])} {''.join(_named_node_item("job", item) for item in jobs[:4])}
@@ -1366,6 +1373,24 @@ def _tabular_section_item(section: object) -> str: """ +def _role_access_item(grant: object) -> str: + role = getattr(grant, "role", None) + permissions = getattr(grant, "permissions", {}) or {} + role_name = getattr(role, "qualified_name", None) or getattr(role, "name", "role") + enabled = [ + str(key) + for key, value in sorted(permissions.items()) + if str(value).lower() in {"true", "1", "yes", "да"} + ] + permission_text = ", ".join(enabled) if enabled else "permissions unavailable" + return f""" +
+ {escape(str(role_name))} + {escape(permission_text)} +
+ """ + + def _authoring_diff_item(line: object) -> str: kind = str(getattr(line, "kind", "")) text = str(getattr(line, "text", "")) diff --git a/services/api-server/src/api_server/main.py b/services/api-server/src/api_server/main.py index 6fee6b9..6a841f6 100644 --- a/services/api-server/src/api_server/main.py +++ b/services/api-server/src/api_server/main.py @@ -1745,8 +1745,9 @@ async def html5_project_review(project_id: str) -> Response: async def html5_project_object_context(project_id: str, object_name: str) -> Response: schema = await get_object_schema(project_id, object_name) impact = await get_object_impact(project_id, object_name) + access = await get_object_access(project_id, object_name) return Response( - render_html5_object_context(project_id, schema, impact), + render_html5_object_context(project_id, schema, impact, access), media_type="text/html; charset=utf-8", ) diff --git a/services/api-server/tests/test_api.py b/services/api-server/tests/test_api.py index 4664830..df4e3a0 100644 --- a/services/api-server/tests/test_api.py +++ b/services/api-server/tests/test_api.py @@ -238,6 +238,9 @@ def test_html5_object_context_fragment(tmp_path: Path): + + + """, encoding="utf-8", @@ -259,6 +262,8 @@ def test_html5_object_context_fragment(tmp_path: Path): assert "Документ.ЗаказПокупателя" in context.text assert "Контрагент" in context.text assert "Товары" in context.text + assert "Роль.Менеджер" in context.text + assert "read, write, post" in context.text or "post, read, write" in context.text assert "