From a406b334bd495773491dacbf2a319240e7970382 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Fri, 18 Aug 2023 10:48:39 +0300 Subject: [PATCH] ws-auth.cc: Split apiZoneMetadataKind to GET, PUT and DELETE variants Enables us to specify method routes for this later. --- .../swagger/authoritative-api-swagger.yaml | 2 +- pdns/ws-auth.cc | 116 +++++++++++------- regression-tests.api/test_Zones.py | 4 +- 3 files changed, 75 insertions(+), 47 deletions(-) diff --git a/docs/http-api/swagger/authoritative-api-swagger.yaml b/docs/http-api/swagger/authoritative-api-swagger.yaml index e4f006b3c1..c231b9d1fd 100644 --- a/docs/http-api/swagger/authoritative-api-swagger.yaml +++ b/docs/http-api/swagger/authoritative-api-swagger.yaml @@ -625,7 +625,7 @@ paths: required: true description: The kind of metadata responses: - '200': + '204': description: OK <<: *commonErrors diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index ed36605047..fba63872b2 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1060,68 +1060,96 @@ static void apiZoneMetadata(HttpRequest *req, HttpResponse* resp) throw HttpMethodNotAllowedException(); } -static void apiZoneMetadataKind(HttpRequest* req, HttpResponse* resp) { +static void apiZoneMetadataKindGET(HttpRequest* req, HttpResponse* resp) { zoneFromId(req); string kind = req->parameters["kind"]; - if (req->method == "GET") { - vector metadata; - Json::object document; - Json::array entries; + vector metadata; + Json::object document; + Json::array entries; + + if (!B.getDomainMetadata(zonename, kind, metadata)) { + throw HttpNotFoundException(); + } + if (!isValidMetadataKind(kind, true)) { + throw ApiException("Unsupported metadata kind '" + kind + "'"); + } - if (!B.getDomainMetadata(zonename, kind, metadata)) - throw HttpNotFoundException(); - else if (!isValidMetadataKind(kind, true)) - throw ApiException("Unsupported metadata kind '" + kind + "'"); + document["type"] = "Metadata"; + document["kind"] = kind; - document["type"] = "Metadata"; - document["kind"] = kind; + for (const string& value : metadata) { + entries.push_back(value); + } - for (const string& i : metadata) - entries.push_back(i); + document["metadata"] = entries; + resp->setJsonBody(document); +} - document["metadata"] = entries; - resp->setJsonBody(document); - } else if (req->method == "PUT") { - auto document = req->json(); +static void apiZoneMetadataKindPUT(HttpRequest* req, HttpResponse* resp) { + zoneFromId(req); + + string kind = req->parameters["kind"]; - if (!isValidMetadataKind(kind, false)) - throw ApiException("Unsupported metadata kind '" + kind + "'"); + const auto& document = req->json(); - vector vecMetadata; - auto& metadata = document["metadata"]; - if (!metadata.is_array()) - throw ApiException("metadata is not specified or not an array"); + if (!isValidMetadataKind(kind, false)) { + throw ApiException("Unsupported metadata kind '" + kind + "'"); + } - for (const auto& i : metadata.array_items()) { - if (!i.is_string()) - throw ApiException("metadata must be strings"); - vecMetadata.push_back(i.string_value()); + vector vecMetadata; + const auto& metadata = document["metadata"]; + if (!metadata.is_array()) { + throw ApiException("metadata is not specified or not an array"); + } + for (const auto& value : metadata.array_items()) { + if (!value.is_string()) { + throw ApiException("metadata must be strings"); } + vecMetadata.push_back(value.string_value()); + } - if (!B.setDomainMetadata(zonename, kind, vecMetadata)) - throw ApiException("Could not update metadata entries for domain '" + zonename.toString() + "'"); + if (!B.setDomainMetadata(zonename, kind, vecMetadata)) { + throw ApiException("Could not update metadata entries for domain '" + zonename.toString() + "'"); + } - DNSSECKeeper::clearMetaCache(zonename); + DNSSECKeeper::clearMetaCache(zonename); - Json::object key { - { "type", "Metadata" }, - { "kind", kind }, - { "metadata", metadata } - }; + Json::object key { + { "type", "Metadata" }, + { "kind", kind }, + { "metadata", metadata } + }; - resp->setJsonBody(key); - } else if (req->method == "DELETE") { - if (!isValidMetadataKind(kind, false)) - throw ApiException("Unsupported metadata kind '" + kind + "'"); + resp->setJsonBody(key); +} - vector md; // an empty vector will do it - if (!B.setDomainMetadata(zonename, kind, md)) - throw ApiException("Could not delete metadata for domain '" + zonename.toString() + "' (" + kind + ")"); +static void apiZoneMetadataKindDELETE(HttpRequest* req, HttpResponse* resp) { + zoneFromId(req); + + const string& kind = req->parameters["kind"]; + if (!isValidMetadataKind(kind, false)) { + throw ApiException("Unsupported metadata kind '" + kind + "'"); + } + + vector metadata; // an empty vector will do it + if (!B.setDomainMetadata(zonename, kind, metadata)) { + throw ApiException("Could not delete metadata for domain '" + zonename.toString() + "' (" + kind + ")"); + } - DNSSECKeeper::clearMetaCache(zonename); - } else + DNSSECKeeper::clearMetaCache(zonename); + resp->status = 204; +} + +static void apiZoneMetadataKind(HttpRequest* req, HttpResponse* resp) { + if (req->method == "GET") + apiZoneMetadataKindGET(req, resp); + else if (req->method == "PUT") + apiZoneMetadataKindPUT(req, resp); + else if (req->method == "DELETE") + apiZoneMetadataKindDELETE(req, resp); + else throw HttpMethodNotAllowedException(); } diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 6bd02bfc87..45ec5cee95 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -729,7 +729,7 @@ class AuthZones(ApiTestCase, AuthZonesHelperMixin): def test_delete_zone_metadata(self): r = self.session.delete(self.url("/api/v1/servers/localhost/zones/example.com/metadata/AXFR-SOURCE")) - self.assertEqual(r.status_code, 200) + self.assertEqual(r.status_code, 204) r = self.session.get(self.url("/api/v1/servers/localhost/zones/example.com/metadata/AXFR-SOURCE")) rdata = r.json() self.assertEqual(r.status_code, 200) @@ -2710,4 +2710,4 @@ class AuthZoneKeys(ApiTestCase, AuthZonesHelperMixin): self.assertEqual(len(keydata), 4) r = self.session.delete(self.url("/api/v1/servers/localhost/zones/powerdnssec.org./metadata/PUBLISH-CDS")) - self.assertEqual(r.status_code, 200) + self.assertEqual(r.status_code, 204) -- 2.47.2