v0.5.6: fix аудит Соннета — apply_effect стенд, mock_services, XSS, paramId валидация, serviceId=0 test

This commit is contained in:
2026-08-02 09:56:19 +04:00
parent b5ecf1dff3
commit 6f4ad7db32
7 changed files with 12 additions and 8 deletions
+1 -1
View File
@@ -80,7 +80,7 @@ SERVICES = _DF["SERVICES"]
OPS_INDEX = _DF["OPS_INDEX"]
DELAY = float(os.getenv("MOCK_OP_DELAY", "0.1"))
VERSION = "0.5.5"
VERSION = "0.5.6"
def get_services(stand_id):
+1 -1
View File
@@ -97,7 +97,7 @@ def mock_services():
не дёргая реальный /api/v1/svc/services.
"""
result = {}
for svc_id, svc_def in _cfg.SERVICES.items():
for svc_id, svc_def in SERVICES.items():
result[str(svc_id)] = {
"name": svc_def.get("name", ""),
"displayName": svc_def.get("service_display_name", ""),
+1 -1
View File
@@ -429,7 +429,7 @@ def _build_paths():
"content": {
"application/json": {
"schema": {"$ref": "#/components/schemas/CreateInstanceRequest"},
"example": {"serviceId": 38, "displayName": "my-test-instance"},
"example": {"serviceId": 1, "displayName": "my-test-instance"},
},
},
},
+4
View File
@@ -237,6 +237,10 @@ def set_operation_param():
if not op_uid or param_id is None:
return jsonify({"error": "instanceOperationUid and svcOperationCfsParamId required"}), 400
# Валидация: svcOperationCfsParamId должен быть целым числом
if not isinstance(param_id, int) or isinstance(param_id, bool):
return jsonify({"error": "svcOperationCfsParamId must be an integer"}), 400
# Проверка что операция существует
if not state.get_operation(op_uid):
return jsonify({"error": "operation not found"}), 404
+1 -1
View File
@@ -72,7 +72,7 @@ def run_operation(uid):
# Применить эффект операции к состоянию инстанса
# (create → running+params, delete → удалить, modify → мерж params, ...)
state_machine.apply_effect(uid, st, _cfg.SERVICES)
state_machine.apply_effect(uid, st, SERVICES)
# Фиксируем время завершения — операция выполнена успешно
op["dtFinish"] = _now()
+3 -3
View File
@@ -92,15 +92,15 @@
showCommonExtensions: true,
// Предзаполняем токен для _mock/*
onComplete: function () {
const authToken = "{{ auth_token }}";
const authToken = {{ auth_token | tojson }};
if (authToken) {
ui.preauthorizeApiKey("mockAuth", authToken);
}
},
requestInterceptor: function (req) {
// Добавляем X-Mock-Auth только для _mock/* эндпоинтов
if (req.url.indexOf("/_mock/") !== -1 && "{{ auth_token }}") {
req.headers["X-Mock-Auth"] = "{{ auth_token }}";
if (req.url.indexOf("/_mock/") !== -1 && {{ auth_token | tojson }}) {
req.headers["X-Mock-Auth"] = {{ auth_token | tojson }};
}
return req;
},
+1 -1
View File
@@ -86,7 +86,7 @@ for sid in stands:
json={"serviceId": -1, "displayName": "x"}, headers=H), 400))
t("serviceId=0", lambda: st(client.post(f"{base}/api/v1/svc/instances",
json={"serviceId": 0, "displayName": "x"}, headers=H), 404))
json={"serviceId": 0, "displayName": "x"}, headers=H), 400))
t("displayName=число", lambda: st(client.post(f"{base}/api/v1/svc/instances",
json={"serviceId": 1, "displayName": 12345}, headers=H), 201))