fix(api): валидировать {namespace} во всех эндпоинтах (было только в POST) + регрессионные тесты

This commit is contained in:
Repinoid
2026-10-11 20:26:30 +03:00
parent 4c24c6351c
commit 6b9f397746
4 changed files with 125 additions and 17 deletions
+15 -16
View File
@@ -151,10 +151,9 @@ func validateIdentifier(value, what string, maxLen int) string {
// CreateIoTDevice — POST /v1/namespaces/{ns}/iot/devices.
func (h *Handler) CreateIoTDevice(w http.ResponseWriter, r *http.Request) {
ns := pathVar(r, "namespace")
if ns == "" {
ns = "default"
}
// Порядок важен: сначала разбор тела (400 «invalid JSON»), потом валидация
// идентификаторов — так и было до вынесения общей проверки.
ns := namespaceFromPath(r)
var req iotDeviceCreateRequest
if err := decodeJSON(w, r, &req); err != nil {
@@ -255,9 +254,9 @@ func (h *Handler) CreateIoTDevice(w http.ResponseWriter, r *http.Request) {
// Пагинация: ?limit=N&offset=M. limit — дефолт 100, потолок 1000 (защита от
// безлимитного запроса при ошибке парсинга).
func (h *Handler) ListIoTDevices(w http.ResponseWriter, r *http.Request) {
ns := pathVar(r, "namespace")
if ns == "" {
ns = "default"
ns, ok := requireNamespace(w, r)
if !ok {
return
}
// limit: дефолт 100, потолок 1000 — иначе ошибка парсинга/омиссия = безлимит
@@ -290,9 +289,9 @@ func (h *Handler) ListIoTDevices(w http.ResponseWriter, r *http.Request) {
// GetIoTDevice — GET /v1/namespaces/{ns}/iot/devices/{name} (с паролем).
func (h *Handler) GetIoTDevice(w http.ResponseWriter, r *http.Request) {
ns := pathVar(r, "namespace")
if ns == "" {
ns = "default"
ns, ok := requireNamespace(w, r)
if !ok {
return
}
name := pathVar(r, "name")
@@ -312,9 +311,9 @@ func (h *Handler) GetIoTDevice(w http.ResponseWriter, r *http.Request) {
// DeleteIoTDevice — DELETE /v1/namespaces/{ns}/iot/devices/{name}.
func (h *Handler) DeleteIoTDevice(w http.ResponseWriter, r *http.Request) {
ns := pathVar(r, "namespace")
if ns == "" {
ns = "default"
ns, ok := requireNamespace(w, r)
if !ok {
return
}
name := pathVar(r, "name")
@@ -334,9 +333,9 @@ func (h *Handler) DeleteIoTDevice(w http.ResponseWriter, r *http.Request) {
// UpdateIoTDevice — PATCH /v1/namespaces/{ns}/iot/devices/{name} (enabled).
func (h *Handler) UpdateIoTDevice(w http.ResponseWriter, r *http.Request) {
ns := pathVar(r, "namespace")
if ns == "" {
ns = "default"
ns, ok := requireNamespace(w, r)
if !ok {
return
}
name := pathVar(r, "name")