From 8a5af7304cdc22b788ef3134d3bba0064ba5d876 Mon Sep 17 00:00:00 2001 From: Jason Song Date: Sun, 20 Sep 2026 18:15:02 +0800 Subject: [PATCH] fix: allow user-token deletion of encoded item keys --- CHANGELOG.md | 6 ++++++ apollo-openapi.yaml | 6 +++--- tests/test_user_token_contract.py | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f543719..3499e82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.3.12] - 2026-09-20 + +### Fixed + +- Make `operator` optional for encoded-key item deletion so user tokens can use the token owner, matching ordinary-key deletion. Consumer tokens still require an explicit operator. + ## [0.3.11] - 2026-08-28 ### Added diff --git a/apollo-openapi.yaml b/apollo-openapi.yaml index 45f420b..90a7757 100644 --- a/apollo-openapi.yaml +++ b/apollo-openapi.yaml @@ -18,7 +18,7 @@ info:
curl -X GET "http://localhost:8070/openapi/v1/apps" \
     -H "Authorization: your_token_here"
- version: 0.3.11 + version: 0.3.12 security: - ApiKeyAuth: [] tags: @@ -1336,8 +1336,8 @@ paths: type: string - name: operator in: query - description: '' - required: true + description: 操作人用户名;user-token 模式使用 token 所属用户,consumer-token 模式必须提供 + required: false schema: type: string responses: diff --git a/tests/test_user_token_contract.py b/tests/test_user_token_contract.py index 9805471..9f67690 100644 --- a/tests/test_user_token_contract.py +++ b/tests/test_user_token_contract.py @@ -17,6 +17,20 @@ def setUp(self): def _load_spec(self, spec_file): return yaml.safe_load((self.repo_root / spec_file).read_text(encoding="utf-8")) + def test_plain_and_encoded_item_delete_allow_token_owner_as_operator(self): + for spec_file in SPEC_FILES: + spec = self._load_spec(spec_file) + for resource in ("items", "encodedItems"): + path = ("/openapi/v1/envs/{env}/apps/{appId}/clusters/{clusterName}" + "/namespaces/{namespaceName}/" + resource + "/{key}") + with self.subTest(spec=spec_file, resource=resource): + operation = spec["paths"][path]["delete"] + operator = next(parameter for parameter in operation["parameters"] + if parameter["name"] == "operator") + self.assertEqual("query", operator["in"]) + self.assertFalse(operator.get("required", False)) + self.assertEqual("string", operator["schema"]["type"]) + def test_user_token_management_paths_use_generated_contract(self): for spec_file in SPEC_FILES: spec = self._load_spec(spec_file)