From d02e0cd0aaef6d864442e9e72eafe94bb4bd3f4d Mon Sep 17 00:00:00 2001 From: Kirill Izotov Date: Fri, 25 Sep 2026 16:27:44 +0200 Subject: [PATCH] Use query parameters for schema and SBOM selectors --- limacharlie/sdk/cloudsec.py | 6 +----- limacharlie/sdk/organization.py | 2 +- tests/unit/test_sdk_cloudsec.py | 18 ++++++------------ tests/unit/test_sdk_organization.py | 2 +- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/limacharlie/sdk/cloudsec.py b/limacharlie/sdk/cloudsec.py index a660a0b9..dcd406bf 100644 --- a/limacharlie/sdk/cloudsec.py +++ b/limacharlie/sdk/cloudsec.py @@ -2334,12 +2334,8 @@ def get_code_sbom( leaves this API's auth boundary. It is deliberately short-lived; fetch it promptly and do not store it. """ - # The key contains a '/', so it is percent-encoded into ONE path - # segment. The gateway accepts either spelling, but encoding is what - # keeps the request unambiguous for anything in between. - quoted = _quote(repo, safe="") return self._get( - f"code/repos/{quoted}/sbom", _query_pairs(provider=provider)) + "code/sbom", _query_pairs(repo=repo, provider=provider)) def download_code_sbom( self, repo: str, *, provider: str | None = None, diff --git a/limacharlie/sdk/organization.py b/limacharlie/sdk/organization.py index 73a0266d..27991ea3 100644 --- a/limacharlie/sdk/organization.py +++ b/limacharlie/sdk/organization.py @@ -144,7 +144,7 @@ def get_schema(self, name: str) -> dict[str, Any]: Returns: dict: Schema definition. """ - return self._client.request("GET", f"orgs/{self.oid}/schema/{urlescape(name, safe='')}") + return self._client.request("GET", f"orgs/{self.oid}/schema", query_params={"name": name}) def reset_schemas(self) -> dict[str, Any]: """Reset (rebuild) all event schemas for the organization. diff --git a/tests/unit/test_sdk_cloudsec.py b/tests/unit/test_sdk_cloudsec.py index 3285eaa2..73817466 100644 --- a/tests/unit/test_sdk_cloudsec.py +++ b/tests/unit/test_sdk_cloudsec.py @@ -981,25 +981,19 @@ def test_get_code_status(self, cs, mock_org): assert url == f"cloudsec/{OID}/code/status" assert qp is None - def test_get_code_sbom_percent_encodes_the_key(self, cs, mock_org): - """The repository key holds a '/', which must not become a path split. - - Left unencoded it would add a path segment and the route would not - match at all — a 404 with nothing on the client side to explain it. - """ + def test_get_code_sbom_uses_query_selector(self, cs, mock_org): mock_org.client.request.return_value = {"sbom": None} - cs.get_code_sbom("refractionPOINT/lc-appsec-fixtures") + repo = "org/group/repo+name" + cs.get_code_sbom(repo) url, qp = _get_call(mock_org) - assert url == ( - f"cloudsec/{OID}/code/repos/" - "refractionPOINT%2Flc-appsec-fixtures/sbom") - assert qp is None + assert url == f"cloudsec/{OID}/code/sbom" + assert qp == [("repo", repo)] def test_get_code_sbom_provider(self, cs, mock_org): mock_org.client.request.return_value = {"sbom": None} cs.get_code_sbom("acme/api", provider="github") _, qp = _get_call(mock_org) - assert qp == [("provider", "github")] + assert qp == [("repo", "acme/api"), ("provider", "github")] def test_rescan_code_repo_posts_the_trigger(self, cs, mock_org): mock_org.client.request.return_value = {"accepted": True} diff --git a/tests/unit/test_sdk_organization.py b/tests/unit/test_sdk_organization.py index 50547b50..7409e4e7 100644 --- a/tests/unit/test_sdk_organization.py +++ b/tests/unit/test_sdk_organization.py @@ -100,7 +100,7 @@ def test_get_schemas_with_platform(self, org, mock_client): def test_get_schema(self, org, mock_client): org.get_schema("NEW_PROCESS") - mock_client.request.assert_called_once_with("GET", "orgs/test-oid-123/schema/NEW_PROCESS") + mock_client.request.assert_called_once_with("GET", "orgs/test-oid-123/schema", query_params={"name": "NEW_PROCESS"}) def test_reset_schemas(self, org, mock_client): org.reset_schemas()