Browse Source

Merge "Return correct response on HTTP basic failure"

tags/4.3.1^0
Zuul 2 weeks ago
committed by Gerrit Code Review
parent
commit
798c1357ca
4 changed files with 26 additions and 10 deletions
  1. +14
    -6
      ironic_lib/auth_basic.py
  2. +1
    -0
      ironic_lib/exception.py
  3. +10
    -4
      ironic_lib/tests/test_basic_auth.py
  4. +1
    -0
      requirements.txt

+ 14
- 6
ironic_lib/auth_basic.py 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)

+ 1
- 0
ironic_lib/exception.py 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):


+ 10
- 4
ironic_lib/tests/test_basic_auth.py 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()



+ 1
- 0
requirements.txt 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

Loading…
Cancel
Save