From 53255086857a44466ecc7e3f728aa9c2df8bec66 Mon Sep 17 00:00:00 2001 From: Pieter Lexis Date: Tue, 10 Feb 2015 19:09:51 +0100 Subject: [PATCH] JSON-API: Send 401 on bad API-Key * Closes #2179 * We send an HTTP 401 (Unauthorized) when: * The API Key is wrong * The API Key is empty or missing * Authentication failures are logged as Error (was Debug) * Fix the API regression test to accept this 401 as valid --- pdns/webserver.cc | 10 +++++----- pdns/webserver.hh | 9 +++++++-- regression-tests.api/test_Basics.py | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/pdns/webserver.cc b/pdns/webserver.cc index 506c06af9..308da1394 100644 --- a/pdns/webserver.cc +++ b/pdns/webserver.cc @@ -118,14 +118,14 @@ static void apiWrapper(WebServer::HandlerFunction handler, HttpRequest* req, Htt resp->headers["access-control-allow-origin"] = "*"; if (api_key.empty()) { - L<url.path << "\": Authentication failed, API Key missing in config" << endl; - throw HttpUnauthorizedException(); + L<url.path << "\": Authentication failed, API Key missing in config" << endl; + throw HttpUnauthorizedException("X-API-Key"); } bool auth_ok = req->compareHeader("x-api-key", api_key) || req->getvars["api-key"]==api_key; if (!auth_ok) { - L<url.path << "\": Authentication by API Key failed" << endl; - throw HttpBadRequestException(); + L<url.path << "\": Authentication by API Key failed" << endl; + throw HttpUnauthorizedException("X-API-Key"); } resp->headers["Content-Type"] = "application/json"; @@ -174,7 +174,7 @@ static void webWrapper(WebServer::HandlerFunction handler, HttpRequest* req, Htt bool auth_ok = req->compareAuthorization(web_password); if (!auth_ok) { L<url.path << "\": Web Authentication failed" << endl; - throw HttpUnauthorizedException(); + throw HttpUnauthorizedException("Basic"); } } diff --git a/pdns/webserver.hh b/pdns/webserver.hh index cbfdc1f8a..7eee5e266 100644 --- a/pdns/webserver.hh +++ b/pdns/webserver.hh @@ -81,12 +81,17 @@ public: class HttpUnauthorizedException : public HttpException { public: - HttpUnauthorizedException() : HttpException(401) + HttpUnauthorizedException(string const &scheme) : HttpException(401) { - d_response.headers["WWW-Authenticate"] = "Basic realm=\"PowerDNS\""; + d_response.headers["WWW-Authenticate"] = scheme + " realm=\"PowerDNS\""; } }; +class HttpForbiddenException : public HttpException { +public: + HttpForbiddenException() : HttpException(403) { }; +}; + class HttpNotFoundException : public HttpException { public: HttpNotFoundException() : HttpException(404) { }; diff --git a/regression-tests.api/test_Basics.py b/regression-tests.api/test_Basics.py index c275018e5..79c3d9ecf 100644 --- a/regression-tests.api/test_Basics.py +++ b/regression-tests.api/test_Basics.py @@ -8,7 +8,7 @@ class TestBasics(ApiTestCase): def test_unauth(self): r = requests.get(self.url("/servers/localhost")) - self.assertEquals(r.status_code, requests.codes.bad_request) + self.assertEquals(r.status_code, requests.codes.unauthorized) def test_split_request(self): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -- 2.40.0