feat(backend): enforce admin-only ops endpoints and cover destructive cleanup smoke

restrict ops endpoints to admin-only access

block operator and viewer keys from admin maintenance routes
cover destructive pricing cleanup in smoke execution, not only preview

extend orchestration without regressing existing smoke stages
This commit is contained in:
greebo
2026-03-20 16:02:38 +03:00
parent 210981c953
commit 5aa35b1d04
10 changed files with 1090 additions and 13 deletions

View File

@@ -101,6 +101,58 @@ PY
fi
}
request_with_api_key() {
local api_key="$1"
local name="$2"
local method="$3"
local url="$4"
local expected_status="$5"
local body="${6:-}"
local out_file="${TMP_DIR}/${name}.body"
local status_file="${TMP_DIR}/${name}.status"
echo
echo "===== ${name} ====="
if [[ -n "${body}" ]]; then
curl -sS \
-X "${method}" \
-H "X-API-Key: ${api_key}" \
-H "Content-Type: application/json" \
-o "${out_file}" \
-w "%{http_code}" \
"${url}" \
--data "${body}" > "${status_file}"
else
curl -sS \
-X "${method}" \
-H "X-API-Key: ${api_key}" \
-o "${out_file}" \
-w "%{http_code}" \
"${url}" > "${status_file}"
fi
local actual_status
actual_status="$(python3 - "$status_file" <<'PY'
from pathlib import Path
import sys
print(Path(sys.argv[1]).read_text(encoding="utf-8").strip())
PY
)"
echo "[${method}] ${url} -> ${actual_status}"
python3 - "$out_file" <<'PY'
from pathlib import Path
import sys
print(Path(sys.argv[1]).read_text(encoding="utf-8"))
PY
echo
if [[ "${actual_status}" != "${expected_status}" ]]; then
fail "Unexpected HTTP status for ${name}: expected ${expected_status}, got ${actual_status}"
fi
}
upload_svg() {
local name="$1"
local upload_filename="$2"
@@ -141,6 +193,51 @@ PY
fi
}
upload_file_expect_status() {
local name="$1"
local file_path="$2"
local upload_filename="$3"
local content_type="$4"
local expected_status="$5"
local out_file="${TMP_DIR}/${name}.body"
local status_file="${TMP_DIR}/${name}.status"
if [[ ! -f "${file_path}" ]]; then
fail "Upload fixture file not found: ${file_path}"
fi
echo
echo "===== ${name} ====="
curl -sS \
-X POST \
-H "X-API-Key: ${API_KEY}" \
-o "${out_file}" \
-w "%{http_code}" \
-F "file=@${file_path};filename=${upload_filename};type=${content_type}" \
"${API_URL}/api/v1/schemes/upload" > "${status_file}"
local actual_status
actual_status="$(python3 - "$status_file" <<'PY'
from pathlib import Path
import sys
print(Path(sys.argv[1]).read_text(encoding="utf-8").strip())
PY
)"
echo "[POST] ${API_URL}/api/v1/schemes/upload -> ${actual_status}"
python3 - "$out_file" <<'PY'
from pathlib import Path
import sys
print(Path(sys.argv[1]).read_text(encoding="utf-8"))
PY
echo
if [[ "${actual_status}" != "${expected_status}" ]]; then
fail "Upload failed for ${upload_filename}: expected ${expected_status}, got ${actual_status}"
fi
}
json_get() {
local file="$1"
local expr="$2"