Merge "Return correct response on HTTP basic failure"

This commit is contained in:
Zuul 2020-07-24 15:06:18 +00:00 committed by Gerrit Code Review
commit 798c1357ca
4 changed files with 26 additions and 10 deletions

View File

@ -18,6 +18,7 @@ import binascii
import bcrypt
from oslo_log import log
import webob
from ironic_lib.common.i18n import _
from ironic_lib import exception
@ -34,6 +35,16 @@ class BasicAuthMiddleware(object):
self.auth_file = auth_file
validate_auth_file(auth_file)
def format_exception(self, e):
result = {'error': {'message': str(e), 'code': e.code}}
headers = list(e.headers.items()) + [
('Content-Type', 'application/json')
]
return webob.Response(content_type='application/json',
status_code=e.code,
json_body=result,
headerlist=headers)
def __call__(self, env, start_response):
try:
@ -44,9 +55,8 @@ class BasicAuthMiddleware(object):
return self.app(env, start_response)
except exception.IronicException as e:
status = '%s %s' % (int(e.code), str(e))
headers = [(k, v) for k, v in e.headers.items()]
start_response(status, headers)
response = self.format_exception(e)
return response(env, start_response)
def authenticate(auth_file, username, password):
@ -182,6 +192,4 @@ def unauthorized(message=None):
"""
if not message:
message = _('Incorrect username or password')
e = exception.Unauthorized(message)
e.headers['WWW-Authenticate'] = 'Basic realm="Baremetal API"'
raise e
raise exception.Unauthorized(message)

View File

@ -176,6 +176,7 @@ class BadRequest(IronicException):
class Unauthorized(IronicException):
code = http_client.UNAUTHORIZED
headers = {'WWW-Authenticate': 'Basic realm="Baremetal API"'}
class ConfigInvalid(IronicException):

View File

@ -14,6 +14,7 @@
# under the License.
import base64
import json
import os
import tempfile
from unittest import mock
@ -55,13 +56,18 @@ class TestAuthBasic(base.IronicLibTestCase):
app = mock.Mock()
start_response = mock.Mock()
middleware = auth_basic.BasicAuthMiddleware(app, auth_file)
env = {}
env = {'REQUEST_METHOD': 'GET'}
middleware(env, start_response)
body = middleware(env, start_response)
decoded = json.loads(body[0].decode())
self.assertEqual({'error': {'message': 'Authorization required',
'code': 401}}, decoded)
start_response.assert_called_once_with(
'401 Authorization required',
[('WWW-Authenticate', 'Basic realm="Baremetal API"')]
'401 Unauthorized',
[('WWW-Authenticate', 'Basic realm="Baremetal API"'),
('Content-Type', 'application/json'),
('Content-Length', str(len(body[0])))]
)
app.assert_not_called()

View File

@ -13,3 +13,4 @@ requests>=2.14.2 # Apache-2.0
oslo.log>=3.36.0 # Apache-2.0
zeroconf>=0.24.0 # LGPL
bcrypt>=3.1.3 # Apache-2.0
WebOb>=1.7.1 # MIT