Merge "feat(validation): verify project id length"
This commit is contained in:
commit
194a1bbf1e
@ -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):
|
||||
|
@ -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.')
|
||||
|
@ -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):
|
||||
|
@ -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)):
|
||||
|
Loading…
x
Reference in New Issue
Block a user