Permalink
Browse files

Validated URLs in v2 endpoint creation API

Fixed the 500 response when endpoint is created without specifying
either adminurl, publicurl or internalurl empty.
Added unit test coverage for v2 endpoint create API.

Fixes LP: #1097747

Change-Id: I1875859bd7e197e985a5b5395c8caefff3c83b11
  • Loading branch information...
1 parent cf3a337 commit 3a38ecfc8868c95ad3df43de22b29f08f2c9d4cf @tpatil tpatil committed Jan 10, 2013
Showing with 91 additions and 8 deletions.
  1. +5 −1 keystone/catalog/controllers.py
  2. +6 −7 keystone/common/controller.py
  3. +80 −0 tests/test_catalog.py
@@ -81,9 +81,13 @@ def create_endpoint(self, context, endpoint):
"""Create three v3 endpoint refs based on a legacy ref."""
self.assert_admin(context)
+ # according to the v2 spec publicurl is mandatory
+ self._require_attribute(endpoint, 'publicurl')
+
legacy_endpoint_ref = endpoint.copy()
- urls = dict((i, endpoint.pop('%surl' % i)) for i in INTERFACES)
+ urls = dict((i, endpoint.pop('%surl' % i)) for i in INTERFACES
+ if endpoint.get('%surl' % i) is not None)
legacy_endpoint_id = uuid.uuid4().hex
for interface, url in urls.iteritems():
endpoint_ref = endpoint.copy()
@@ -59,7 +59,12 @@ def wrapper(self, context, **kwargs):
@dependency.requires('identity_api', 'policy_api', 'token_api')
class V2Controller(wsgi.Application):
"""Base controller class for Identity API v2."""
- pass
+
+ def _require_attribute(self, ref, attr):
+ """Ensures the reference contains the specified attribute."""
+ if ref.get(attr) is None or ref.get(attr) == '':
+ msg = '%s field is required and cannot be empty' % attr
+ raise exception.ValidationError(message=msg)
class V3Controller(V2Controller):
@@ -71,12 +76,6 @@ def _paginate(self, context, refs):
per_page = context['query_string'].get('per_page', 30)
return refs[per_page * (page - 1):per_page * page]
- def _require_attribute(self, ref, attr):
- """Ensures the reference contains the specified attribute."""
- if ref.get(attr) is None or ref.get(attr) == '':
- msg = '%s field is required and cannot be empty' % attr
- raise exception.ValidationError(message=msg)
-
def _require_matching_id(self, value, ref):
"""Ensures the value matches the reference's ID, if any."""
if 'id' in ref and ref['id'] != value:
View
@@ -0,0 +1,80 @@
+import uuid
+
+from keystone.common.sql import util as sql_util
+from keystone import test
+
+import test_content_types
+
+
+BASE_URL = 'http://127.0.0.1:35357/v2'
+
+
+class V2CatalogTestCase(test_content_types.RestfulTestCase):
+ def setUp(self):
+ super(V2CatalogTestCase, self).setUp()
+ self.service_id = uuid.uuid4().hex
+ self.service = self.new_service_ref()
+ self.service['id'] = self.service_id
+ self.catalog_api.create_service(
+ self.service_id,
+ self.service.copy())
+
+ def new_ref(self):
+ """Populates a ref with attributes common to all API entities."""
+ return {
+ 'id': uuid.uuid4().hex,
+ 'name': uuid.uuid4().hex,
+ 'description': uuid.uuid4().hex,
+ 'enabled': True}
+
+ def new_service_ref(self):
+ ref = self.new_ref()
+ ref['type'] = uuid.uuid4().hex
+ return ref
+
+ def _get_token_id(self, r):
+ """Applicable only to JSON."""
+ return r.body['access']['token']['id']
+
+ def assertValidErrorResponse(self, response):
+ self.assertEqual(response.status, 400)
+
+ def _endpoint_create(self, expected_status=200, missing_param=None):
+ path = '/v2.0/endpoints'
+ body = {
+ "endpoint": {
+ "adminurl": "http://localhost:8080",
+ "service_id": self.service_id,
+ "region": "regionOne",
+ "internalurl": "http://localhost:8080",
+ "publicurl": "http://localhost:8080"
+ }
+ }
+ if missing_param:
+ body['endpoint'][missing_param] = None
+ r = self.admin_request(method='POST', token=self.get_scoped_token(),
+ path=path, expected_status=expected_status,
+ body=body)
+ return body, r
+
+ def test_endpoint_create(self):
+ req_body, response = self._endpoint_create(expected_status=200)
+ self.assertTrue('endpoint' in response.body)
+ self.assertTrue('id' in response.body['endpoint'])
+ for field, value in req_body['endpoint'].iteritems():
+ self.assertEqual(response.body['endpoint'][field], value)
+
+ def test_endpoint_create_with_missing_adminurl(self):
+ req_body, response = self._endpoint_create(expected_status=200,
+ missing_param='adminurl')
+ self.assertEqual(response.status, 200)
+
+ def test_endpoint_create_with_missing_internalurl(self):
+ req_body, response = self._endpoint_create(expected_status=200,
+ missing_param='internalurl')
+ self.assertEqual(response.status, 200)
+
+ def test_endpoint_create_with_missing_publicurl(self):
+ req_body, response = self._endpoint_create(expected_status=400,
+ missing_param='publicurl')
+ self.assertValidErrorResponse(response)

0 comments on commit 3a38ecf

Please sign in to comment.