fix(formulas): рассылка WS не несёт формулу клиента при отказе в доступе (AURORA-1896, I-1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-11-11 21:06:53 +04:00
parent 683e12c52f
commit ecef6eb247
2 changed files with 33 additions and 2 deletions

View File

@ -538,6 +538,9 @@ class FormEventProcess:
"value": any,
}
"""
client_formula = event_data.get("formula")
# Формула клиента не должна уйти в рассылку, даже если запись не состоится.
_apply_saved_formula(event_data, None)
if not await self._check_form_access(form_id=form_id, user=user):
return None
@ -549,7 +552,7 @@ class FormEventProcess:
line_id=event_data["line_id"],
column=event_data["column"],
value=event_data["value"],
formula=event_data.get("formula"),
formula=client_formula,
user=user,
)
_apply_saved_formula(event_data, formula)
@ -774,6 +777,9 @@ class ProjectEventProcess:
"value": any,
}
"""
client_formula = event_data.get("formula")
# Формула клиента не должна уйти в рассылку, даже если запись не состоится.
_apply_saved_formula(event_data, None)
project = await self.project_service.get(project_id=project_id, user=user)
if not project:
return None
@ -785,7 +791,7 @@ class ProjectEventProcess:
line_id=event_data["line_id"],
column=event_data["column"],
value=event_data["value"],
formula=event_data.get("formula"),
formula=client_formula,
user=user,
)
_apply_saved_formula(event_data, formula)

View File

@ -188,3 +188,28 @@ def test_ws_project_report_cell_updated_carries_saved_formula(client, admin_toke
"DELETE FROM v3.rf_project_report_quarter WHERE rf_project_report_line_id = :l",
commit=True, l=line_id)
_db_scalar("DELETE FROM v3.rf_project_report_line WHERE id = :l", commit=True, l=line_id)
def test_ws_no_access_user_forged_formula_is_not_echoed(client, isp_tokens):
"""I-1: пользователь без доступа к форме 1 (isp1) шлёт cell_updated с подделанной формулой:
в ответе/рассылке formula и formula_meta обнулены, строки cell_formula не появляется."""
count_sql = (
"SELECT count(*) FROM v3.cell_formula WHERE budget_form_id = 1 "
"AND line_id = 1 AND column_key = 'plan.q1'"
)
before = _db_scalar(count_sql)
prior = _db_scalar(PLAN_Q1_SQL)
try:
with client.websocket_connect(WS_URL) as ws:
ws.send_json({"event": "user_login", "data": {"token": isp_tokens["access_token"]}})
forged_meta = {"updated_by": {"id": 1, "full_name": "Forged"}, "updated_at": "2020-01-01T00:00:00"}
updated = _edit(ws, {"value": 777, "formula": "7*111", "formula_meta": forged_meta})
assert not updated.get("error"), updated
data = updated.get("data", {})
assert data.get("formula") is None, updated
assert data.get("formula_meta") is None, updated
assert _db_scalar(count_sql) == before
assert _db_scalar(PLAN_Q1_SQL) == prior
finally:
_cleanup_formula()
_restore_cell(prior)