Fix api access with public acl routes
Route path in public acl routes should be access without authentication even if authentication is enabled(enable_authentication = True) Closes-Bug: #1549071 Change-Id: Ie0a2684464adfa5ae5dd64f17d8ad399f7202604
This commit is contained in:
parent
39288ea1dd
commit
acd5d30797
@ -25,7 +25,8 @@ app = {
|
|||||||
hooks.NoExceptionTracebackHook(),
|
hooks.NoExceptionTracebackHook(),
|
||||||
],
|
],
|
||||||
'acl_public_routes': [
|
'acl_public_routes': [
|
||||||
'/'
|
'/',
|
||||||
|
'/v1',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class AuthTokenMiddleware(auth_token.AuthProtocol):
|
|||||||
def __init__(self, app, conf, public_api_routes=None):
|
def __init__(self, app, conf, public_api_routes=None):
|
||||||
if public_api_routes is None:
|
if public_api_routes is None:
|
||||||
public_api_routes = []
|
public_api_routes = []
|
||||||
route_pattern_tpl = '%s\.json?$'
|
route_pattern_tpl = '%s(\.json)?$'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.public_api_routes = [re.compile(route_pattern_tpl % route_tpl)
|
self.public_api_routes = [re.compile(route_pattern_tpl % route_tpl)
|
||||||
|
@ -45,6 +45,25 @@ class FunctionalTest(base.DbTestCase):
|
|||||||
group='keystone_authtoken')
|
group='keystone_authtoken')
|
||||||
cfg.CONF.set_override("admin_user", "admin",
|
cfg.CONF.set_override("admin_user", "admin",
|
||||||
group='keystone_authtoken')
|
group='keystone_authtoken')
|
||||||
|
|
||||||
|
# Determine where we are so we can set up paths in the config
|
||||||
|
root_dir = self.get_path()
|
||||||
|
self.config = {
|
||||||
|
'app': {
|
||||||
|
'root': 'magnum.api.controllers.root.RootController',
|
||||||
|
'modules': ['magnum.api'],
|
||||||
|
'static_root': '%s/public' % root_dir,
|
||||||
|
'template_path': '%s/api/templates' % root_dir,
|
||||||
|
'enable_acl': False,
|
||||||
|
'acl_public_routes': ['/', '/v1'],
|
||||||
|
'hooks': [
|
||||||
|
hooks.ContextHook(),
|
||||||
|
hooks.RPCHook(),
|
||||||
|
hooks.NoExceptionTracebackHook(),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
self.app = self._make_app()
|
self.app = self._make_app()
|
||||||
|
|
||||||
def reset_pecan():
|
def reset_pecan():
|
||||||
@ -64,27 +83,13 @@ class FunctionalTest(base.DbTestCase):
|
|||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
verify_method(attr, response)
|
verify_method(attr, response)
|
||||||
|
|
||||||
def _make_app(self, enable_acl=False):
|
def _make_app(self, config=None, enable_acl=False):
|
||||||
# Determine where we are so we can set up paths in the config
|
if not config:
|
||||||
root_dir = self.get_path()
|
config = self.config
|
||||||
|
|
||||||
self.config = {
|
config["app"]["enable_acl"] = enable_acl
|
||||||
'app': {
|
|
||||||
'root': 'magnum.api.controllers.root.RootController',
|
|
||||||
'modules': ['magnum.api'],
|
|
||||||
'static_root': '%s/public' % root_dir,
|
|
||||||
'template_path': '%s/api/templates' % root_dir,
|
|
||||||
'enable_acl': enable_acl,
|
|
||||||
'acl_public_routes': ['/', '/v1'],
|
|
||||||
'hooks': [
|
|
||||||
hooks.ContextHook(),
|
|
||||||
hooks.RPCHook(),
|
|
||||||
hooks.NoExceptionTracebackHook(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return pecan.testing.load_test_app(self.config)
|
return pecan.testing.load_test_app(config)
|
||||||
|
|
||||||
def _request_json(self, path, params, expect_errors=False, headers=None,
|
def _request_json(self, path, params, expect_errors=False, headers=None,
|
||||||
method="post", extra_environ=None, status=None,
|
method="post", extra_environ=None, status=None,
|
||||||
|
@ -10,7 +10,10 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
from oslo_config import cfg
|
||||||
from webob import exc as webob_exc
|
from webob import exc as webob_exc
|
||||||
|
|
||||||
from magnum.api.controllers import v1 as v1_api
|
from magnum.api.controllers import v1 as v1_api
|
||||||
@ -19,23 +22,21 @@ from magnum.tests.unit.api import base as api_base
|
|||||||
|
|
||||||
|
|
||||||
class TestRootController(api_base.FunctionalTest):
|
class TestRootController(api_base.FunctionalTest):
|
||||||
def test_version(self):
|
def setUp(self):
|
||||||
expected = {u'default_version':
|
super(TestRootController, self).setUp()
|
||||||
{u'id': u'v1', u'links':
|
self.root_expected = {
|
||||||
[{u'href': u'http://localhost/v1/', u'rel': u'self'}]},
|
u'default_version':
|
||||||
u'description': u'Magnum is an OpenStack project which '
|
{u'id': u'v1', u'links':
|
||||||
'aims to provide container management.',
|
[{u'href': u'http://localhost/v1/', u'rel': u'self'}]},
|
||||||
u'name': u'OpenStack Magnum API',
|
u'description': u'Magnum is an OpenStack project which '
|
||||||
u'versions': [{u'id': u'v1',
|
'aims to provide container management.',
|
||||||
u'links':
|
u'name': u'OpenStack Magnum API',
|
||||||
[{u'href': u'http://localhost/v1/',
|
u'versions': [{u'id': u'v1',
|
||||||
u'rel': u'self'}]}]}
|
u'links':
|
||||||
|
[{u'href': u'http://localhost/v1/',
|
||||||
|
u'rel': u'self'}]}]}
|
||||||
|
|
||||||
response = self.app.get('/')
|
self.v1_expected = {
|
||||||
self.assertEqual(expected, response.json)
|
|
||||||
|
|
||||||
def test_v1_controller(self):
|
|
||||||
expected = {
|
|
||||||
u'media_types':
|
u'media_types':
|
||||||
[{u'base': u'application/json',
|
[{u'base': u'application/json',
|
||||||
u'type': u'application/vnd.openstack.magnum.v1+json'}],
|
u'type': u'application/vnd.openstack.magnum.v1+json'}],
|
||||||
@ -83,13 +84,73 @@ class TestRootController(api_base.FunctionalTest):
|
|||||||
{u'href': u'http://localhost/mservices/',
|
{u'href': u'http://localhost/mservices/',
|
||||||
u'rel': u'bookmark'}]}
|
u'rel': u'bookmark'}]}
|
||||||
|
|
||||||
|
def test_version(self):
|
||||||
|
response = self.app.get('/')
|
||||||
|
self.assertEqual(self.root_expected, response.json)
|
||||||
|
|
||||||
|
def test_v1_controller(self):
|
||||||
response = self.app.get('/v1/')
|
response = self.app.get('/v1/')
|
||||||
self.assertEqual(expected, response.json)
|
self.assertEqual(self.v1_expected, response.json)
|
||||||
|
|
||||||
def test_get_not_found(self):
|
def test_get_not_found(self):
|
||||||
response = self.app.get('/a/bogus/url', expect_errors=True)
|
response = self.app.get('/a/bogus/url', expect_errors=True)
|
||||||
assert response.status_int == 404
|
assert response.status_int == 404
|
||||||
|
|
||||||
|
def test_acl_access_with_all(self):
|
||||||
|
cfg.CONF.set_override("enable_authentication", True)
|
||||||
|
|
||||||
|
config = copy.deepcopy(self.config)
|
||||||
|
# Both / and /v1 and access without auth
|
||||||
|
config["app"]["acl_public_routes"] = ['/', '/v1']
|
||||||
|
app = self._make_app(config=config)
|
||||||
|
|
||||||
|
response = app.get('/')
|
||||||
|
self.assertEqual(self.root_expected, response.json)
|
||||||
|
|
||||||
|
response = app.get('/v1/')
|
||||||
|
self.assertEqual(self.v1_expected, response.json)
|
||||||
|
|
||||||
|
def test_acl_access_with_root(self):
|
||||||
|
cfg.CONF.set_override("enable_authentication", True)
|
||||||
|
|
||||||
|
config = copy.deepcopy(self.config)
|
||||||
|
# Only / can access without auth
|
||||||
|
config["app"]["acl_public_routes"] = ['/']
|
||||||
|
app = self._make_app(config=config)
|
||||||
|
|
||||||
|
response = app.get('/')
|
||||||
|
self.assertEqual(self.root_expected, response.json)
|
||||||
|
|
||||||
|
response = app.get('/v1/', expect_errors=True)
|
||||||
|
self.assertEqual(401, response.status_int)
|
||||||
|
|
||||||
|
def test_acl_access_with_v1(self):
|
||||||
|
cfg.CONF.set_override("enable_authentication", True)
|
||||||
|
|
||||||
|
config = copy.deepcopy(self.config)
|
||||||
|
# Only /v1 can access without auth
|
||||||
|
config["app"]["acl_public_routes"] = ['/v1']
|
||||||
|
app = self._make_app(config=config)
|
||||||
|
|
||||||
|
response = app.get('/', expect_errors=True)
|
||||||
|
self.assertEqual(401, response.status_int)
|
||||||
|
|
||||||
|
response = app.get('/v1/')
|
||||||
|
self.assertEqual(self.v1_expected, response.json)
|
||||||
|
|
||||||
|
def test_acl_with_neither(self):
|
||||||
|
cfg.CONF.set_override("enable_authentication", True)
|
||||||
|
|
||||||
|
config = copy.deepcopy(self.config)
|
||||||
|
config["app"]["acl_public_routes"] = []
|
||||||
|
app = self._make_app(config=config)
|
||||||
|
|
||||||
|
response = app.get('/', expect_errors=True)
|
||||||
|
self.assertEqual(401, response.status_int)
|
||||||
|
|
||||||
|
response = app.get('/v1/', expect_errors=True)
|
||||||
|
self.assertEqual(401, response.status_int)
|
||||||
|
|
||||||
|
|
||||||
class TestV1Routing(api_base.FunctionalTest):
|
class TestV1Routing(api_base.FunctionalTest):
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user