From d05dcd3443b1f2b5c0332efcbb4696315e6cc9ea Mon Sep 17 00:00:00 2001 From: wlh000 Date: Wed, 5 Aug 2026 11:05:39 +0800 Subject: [PATCH] fix: require identity for task publishing (IK6FV3) --- tms/api/internal/middleware/auth.go | 1 + tms/api/internal/middleware/auth_test.go | 57 ++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 tms/api/internal/middleware/auth_test.go diff --git a/tms/api/internal/middleware/auth.go b/tms/api/internal/middleware/auth.go index 1cf161d..2d48483 100644 --- a/tms/api/internal/middleware/auth.go +++ b/tms/api/internal/middleware/auth.go @@ -21,6 +21,7 @@ var mutatingPrefixes = []string{ "/api/v1/assets/add", "/api/v1/assets/batch_add", "/api/v1/assets/remove", + "/api/v1/ops_tasks/publish", "/api/v1/ops_tasks/cancel", "/api/v1/artifacts/upload", "/api/v1/artifacts/remove", diff --git a/tms/api/internal/middleware/auth_test.go b/tms/api/internal/middleware/auth_test.go new file mode 100644 index 0000000..d59dfc0 --- /dev/null +++ b/tms/api/internal/middleware/auth_test.go @@ -0,0 +1,57 @@ +// Copyright (C) 2024 OpenCloudOS +// License: GPL-3.0-or-later + +package middleware + +import ( + "net/http" + "net/http/httptest" + "testing" + + "gitee.com/OpenCloudOS/ocmanager/tms/api/internal/envelope" +) + +func TestAuthRejectsAnonymousOpsTasksPublish(t *testing.T) { + for _, userName := range []string{"", " "} { + t.Run("user_name_"+userName, func(t *testing.T) { + called := false + next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) { + called = true + }) + req := httptest.NewRequest(http.MethodPost, "/api/v1/ops_tasks/publish", nil) + if userName != "" { + req.Header.Set("X-User-Name", userName) + } + rr := httptest.NewRecorder() + + Auth(next).ServeHTTP(rr, req) + + if rr.Code != http.StatusUnauthorized { + t.Fatalf("status = %d, want %d", rr.Code, http.StatusUnauthorized) + } + if called { + t.Fatal("publish handler must not be called without an authenticated user") + } + }) + } +} + +func TestAuthAllowsIdentifiedOpsTasksPublish(t *testing.T) { + called := false + next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + called = true + if got := envelope.UserNameFromCtx(r.Context()); got != "alice" { + t.Fatalf("user name = %q, want alice", got) + } + w.WriteHeader(http.StatusNoContent) + }) + req := httptest.NewRequest(http.MethodPost, "/api/v1/ops_tasks/publish", nil) + req.Header.Set("X-User-Name", " alice ") + rr := httptest.NewRecorder() + + Auth(next).ServeHTTP(rr, req) + + if rr.Code != http.StatusNoContent || !called { + t.Fatalf("status = %d, called = %v; want 204 and true", rr.Code, called) + } +} -- Gitee