Merge "feat(validation): verify project id length"

This commit is contained in:
Jenkins 2013-12-02 22:46:51 +00:00 committed by Gerrit Code Review
commit 194a1bbf1e
4 changed files with 40 additions and 22 deletions

View File

@ -16,7 +16,6 @@
"""wsgi transport helpers."""
import falcon
import six
import marconi.openstack.common.log as logging
from marconi.queues.transport import validation
@ -46,11 +45,11 @@ X-PROJECT-ID cannot be an empty string. Specify the right header X-PROJECT-ID
and retry.'''))
def validate_queue_name(validate, req, resp, params):
"""Hook for validating the queue name specified in a request.
def validate_queue_identification(validate, req, resp, params):
"""Hook for validating the queue name and project id in requests.
Validation is short-circuited if 'queue_name' does not
exist in `params`.
The queue name validation is short-circuited if 'queue_name' does
not exist in `params`.
This hook depends on the `get_project` hook, which must be
installed upstream.
@ -67,11 +66,12 @@ def validate_queue_name(validate, req, resp, params):
"""
try:
validate(params['queue_name'])
validate(params['queue_name'],
params['project_id'])
except KeyError:
# NOTE(kgriffs): queue_name not in params, so nothing to do
pass
except validation.ValidationFailed as ex:
except validation.ValidationFailed:
project = params['project_id']
queue = params['queue_name'].decode('utf-8', 'replace')
@ -79,10 +79,9 @@ def validate_queue_name(validate, req, resp, params):
u'project: %(project)s'),
{'queue': queue, 'project': project})
info = six.text_type(ex) or _(u'The format of the submitted '
u'queue name is not valid.')
raise falcon.HTTPBadRequest(_(u'Invalid queue name'), info)
raise falcon.HTTPBadRequest(_(u'Invalid queue identification'),
_(u'The format of the submitted queue '
u'name or project id is not valid.'))
def require_accepts_json(req, resp, params):

View File

@ -35,6 +35,7 @@ _TRANSPORT_LIMITS_GROUP = 'limits:transport'
# only ASCII characters.
QUEUE_NAME_REGEX = re.compile('^[a-zA-Z0-9_\-]+$')
QUEUE_NAME_MAX_LEN = 64
PROJECT_ID_MAX_LEN = 256
class ValidationFailed(ValueError):
@ -48,20 +49,28 @@ class Validator(object):
group=_TRANSPORT_LIMITS_GROUP)
self._limits_conf = self._conf[_TRANSPORT_LIMITS_GROUP]
def queue_name(self, name):
"""Restrictions on a queue name.
def queue_identification(self, queue, project):
"""Restrictions on a project id & queue name pair.
:param name: The queue name
:raises: ValidationFailed if the name is longer than 64 bytes or
contains anything other than ASCII digits and letters,
underscores, and dashes.
:param queue: Name of the queue
:param project: Project id
:raises: ValidationFailed if the `name` is longer than 64
characters or contains anything other than ASCII digits and
letters, underscores, and dashes. Also raises if `project`
is not None but longer than 256 characters.
"""
if len(name) > QUEUE_NAME_MAX_LEN:
if project is not None and len(project) > PROJECT_ID_MAX_LEN:
raise ValidationFailed(
'Queue names may not be more than 64 characters long.')
'Project ids may not be more than %d characters long.'
% PROJECT_ID_MAX_LEN)
if not QUEUE_NAME_REGEX.match(name):
if len(queue) > QUEUE_NAME_MAX_LEN:
raise ValidationFailed(
'Queue names may not be more than %d characters long.'
% QUEUE_NAME_MAX_LEN)
if not QUEUE_NAME_REGEX.match(queue):
raise ValidationFailed(
'Queue names may only contain ASCII letters, digits, '
'underscores, and dashes.')

View File

@ -66,8 +66,8 @@ class DriverBase(transport.DriverBase):
helpers.extract_project_id,
# NOTE(kgriffs): Depends on project_id being extracted, above
functools.partial(helpers.validate_queue_name,
self._validate.queue_name)
functools.partial(helpers.validate_queue_identification,
self._validate.queue_identification)
]
def _init_routes(self):

View File

@ -111,6 +111,16 @@ class QueueLifecycleBaseTest(base.TestBase):
self.simulate_put('/v1/queues/_' + 'niceboat' * 8)
self.assertEqual(self.srmock.status, falcon.HTTP_400)
def test_project_id_restriction(self):
self.simulate_put('/v1/queues/Muv-Luv',
headers={'X-Project-ID': 'JAM Project' * 24})
self.assertEqual(self.srmock.status, falcon.HTTP_400)
# no charset restrictions
self.simulate_put('/v1/queues/Muv-Luv',
headers={'X-Project-ID': 'JAM Project'})
self.assertEqual(self.srmock.status, falcon.HTTP_201)
@ddt.data((u'/v1/queues/non-ascii-n\u0153me', 'utf-8'),
(u'/v1/queues/non-ascii-n\xc4me', 'iso8859-1'))
def test_non_ascii_name(self, (uri, enc)):