diff options
| author | Barry Warsaw | 2010-08-23 21:58:44 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2010-08-23 21:58:44 -0400 |
| commit | ea5836d0922db7e8935ecf62ae1b1ecde7da7785 (patch) | |
| tree | 527bdf301b999ed0736cae67a6ce9eee000c6950 /src | |
| parent | 537a9b8682565ebfa79aad0ed3e4efb6b89aa3f4 (diff) | |
| download | mailman-ea5836d0922db7e8935ecf62ae1b1ecde7da7785.tar.gz mailman-ea5836d0922db7e8935ecf62ae1b1ecde7da7785.tar.zst mailman-ea5836d0922db7e8935ecf62ae1b1ecde7da7785.zip | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/bin/qrunner.py | 1 | ||||
| -rw-r--r-- | src/mailman/rest/configuration.py | 3 | ||||
| -rw-r--r-- | src/mailman/rest/docs/helpers.txt | 2 | ||||
| -rw-r--r-- | src/mailman/rest/domains.py | 3 | ||||
| -rw-r--r-- | src/mailman/rest/helpers.py | 69 | ||||
| -rw-r--r-- | src/mailman/rest/lists.py | 3 | ||||
| -rw-r--r-- | src/mailman/rest/members.py | 4 | ||||
| -rw-r--r-- | src/mailman/rest/validator.py | 94 |
8 files changed, 104 insertions, 75 deletions
diff --git a/src/mailman/bin/qrunner.py b/src/mailman/bin/qrunner.py index ac8cd7dd3..67d2d9abb 100644 --- a/src/mailman/bin/qrunner.py +++ b/src/mailman/bin/qrunner.py @@ -25,6 +25,7 @@ __all__ = [ ] +import os import sys import signal import logging diff --git a/src/mailman/rest/configuration.py b/src/mailman/rest/configuration.py index d2653fea4..95bcf32db 100644 --- a/src/mailman/rest/configuration.py +++ b/src/mailman/rest/configuration.py @@ -31,7 +31,8 @@ from restish import http, resource from mailman.config import config from mailman.interfaces.autorespond import ResponseAction from mailman.interfaces.mailinglist import IAcceptableAliasSet -from mailman.rest.helpers import Validator, enum_validator, etag +from mailman.rest.helpers import etag +from mailman.rest.validator import Validator, enum_validator diff --git a/src/mailman/rest/docs/helpers.txt b/src/mailman/rest/docs/helpers.txt index 23cd2f162..b2482b370 100644 --- a/src/mailman/rest/docs/helpers.txt +++ b/src/mailman/rest/docs/helpers.txt @@ -65,7 +65,7 @@ POST unpacking Another helper unpacks POST request variables, validating and converting their values. - >>> from mailman.rest.helpers import Validator + >>> from mailman.rest.validator import Validator >>> validator = Validator(one=int, two=unicode, three=bool) >>> class FakeRequest: diff --git a/src/mailman/rest/domains.py b/src/mailman/rest/domains.py index 8bc68a6c1..a2041c083 100644 --- a/src/mailman/rest/domains.py +++ b/src/mailman/rest/domains.py @@ -31,7 +31,8 @@ from zope.component import getUtility from mailman.interfaces.domain import ( BadDomainSpecificationError, IDomainManager) -from mailman.rest.helpers import CollectionMixin, Validator, etag, path_to +from mailman.rest.helpers import CollectionMixin, etag, path_to +from mailman.rest.validator import Validator diff --git a/src/mailman/rest/helpers.py b/src/mailman/rest/helpers.py index 8c4f0bae9..3117ed47e 100644 --- a/src/mailman/rest/helpers.py +++ b/src/mailman/rest/helpers.py @@ -22,7 +22,6 @@ from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ 'ContainerMixin', - 'enum_validator', 'etag', 'no_content', 'path_to', @@ -41,9 +40,6 @@ from restish.http import Response from mailman.config import config -COMMASPACE = ', ' - - def path_to(resource): """Return the url path to a resource. @@ -154,71 +150,6 @@ class CollectionMixin: -class enum_validator: - """Convert an enum value name into an enum value.""" - - def __init__(self, enum_class): - self._enum_class = enum_class - - def __call__(self, enum_value): - # This will raise a ValueError if the enum value is unknown. Let that - # percolate up. - return self._enum_class[enum_value] - - -class Validator: - """A validator of parameter input.""" - - def __init__(self, **kws): - if '_optional' in kws: - self._optional = set(kws.pop('_optional')) - else: - self._optional = set() - self._converters = kws.copy() - - def __call__(self, request): - values = {} - extras = set() - cannot_convert = set() - form_data = {} - # All keys which show up only once in the form data get a scalar value - # in the pre-converted dictionary. All keys which show up more than - # once get a list value. - missing = object() - for key, new_value in request.POST.items(): - old_value = form_data.get(key, missing) - if old_value is missing: - form_data[key] = new_value - elif isinstance(old_value, list): - old_value.append(new_value) - else: - form_data[key] = [old_value, new_value] - # Now do all the conversions. - for key, value in form_data.items(): - try: - values[key] = self._converters[key](value) - except KeyError: - extras.add(key) - except (TypeError, ValueError): - cannot_convert.add(key) - # Make sure there are no unexpected values. - if len(extras) != 0: - extras = COMMASPACE.join(sorted(extras)) - raise ValueError('Unexpected parameters: {0}'.format(extras)) - # Make sure everything could be converted. - if len(cannot_convert) != 0: - bad = COMMASPACE.join(sorted(cannot_convert)) - raise ValueError('Cannot convert parameters: {0}'.format(bad)) - # Make sure nothing's missing. - value_keys = set(values) - required_keys = set(self._converters) - self._optional - if value_keys & required_keys != required_keys: - missing = COMMASPACE.join(sorted(required_keys - value_keys)) - raise ValueError('Missing parameters: {0}'.format(missing)) - return values - - - # XXX 2010-02-24 barry Seems like contrary to the documentation, matchers # cannot be plain functions, because matchers must have a .score attribute. # OTOH, I think they support regexps, so that might be a better way to go. diff --git a/src/mailman/rest/lists.py b/src/mailman/rest/lists.py index af5b3ced5..adbf4f176 100644 --- a/src/mailman/rest/lists.py +++ b/src/mailman/rest/lists.py @@ -37,8 +37,9 @@ from mailman.interfaces.listmanager import ( from mailman.interfaces.member import MemberRole from mailman.rest.configuration import ListConfiguration from mailman.rest.helpers import ( - CollectionMixin, Validator, etag, no_content, path_to, restish_matcher) + CollectionMixin, etag, no_content, path_to, restish_matcher) from mailman.rest.members import AMember, MembersOfList +from mailman.rest.validator import Validator diff --git a/src/mailman/rest/members.py b/src/mailman/rest/members.py index 67dfb6533..3fdc7dbeb 100644 --- a/src/mailman/rest/members.py +++ b/src/mailman/rest/members.py @@ -38,8 +38,8 @@ from mailman.interfaces.listmanager import NoSuchListError from mailman.interfaces.member import ( AlreadySubscribedError, DeliveryMode, MemberRole) from mailman.interfaces.membership import ISubscriptionService -from mailman.rest.helpers import ( - CollectionMixin, Validator, enum_validator, etag, path_to) +from mailman.rest.helpers import CollectionMixin, etag, path_to +from mailman.rest.validator import Validator, enum_validator diff --git a/src/mailman/rest/validator.py b/src/mailman/rest/validator.py new file mode 100644 index 000000000..e9bcf4729 --- /dev/null +++ b/src/mailman/rest/validator.py @@ -0,0 +1,94 @@ +# Copyright (C) 2010 by the Free Software Foundation, Inc. +# +# This file is part of GNU Mailman. +# +# GNU Mailman is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# +# GNU Mailman is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Mailman. If not, see <http://www.gnu.org/licenses/>. + +"""REST web form validation.""" + +from __future__ import absolute_import, unicode_literals + +__metaclass__ = type +__all__ = [ + 'Validator', + 'enum_validator', + ] + + +COMMASPACE = ', ' + + + +class enum_validator: + """Convert an enum value name into an enum value.""" + + def __init__(self, enum_class): + self._enum_class = enum_class + + def __call__(self, enum_value): + # This will raise a ValueError if the enum value is unknown. Let that + # percolate up. + return self._enum_class[enum_value] + + +class Validator: + """A validator of parameter input.""" + + def __init__(self, **kws): + if '_optional' in kws: + self._optional = set(kws.pop('_optional')) + else: + self._optional = set() + self._converters = kws.copy() + + def __call__(self, request): + values = {} + extras = set() + cannot_convert = set() + form_data = {} + # All keys which show up only once in the form data get a scalar value + # in the pre-converted dictionary. All keys which show up more than + # once get a list value. + missing = object() + for key, new_value in request.POST.items(): + old_value = form_data.get(key, missing) + if old_value is missing: + form_data[key] = new_value + elif isinstance(old_value, list): + old_value.append(new_value) + else: + form_data[key] = [old_value, new_value] + # Now do all the conversions. + for key, value in form_data.items(): + try: + values[key] = self._converters[key](value) + except KeyError: + extras.add(key) + except (TypeError, ValueError): + cannot_convert.add(key) + # Make sure there are no unexpected values. + if len(extras) != 0: + extras = COMMASPACE.join(sorted(extras)) + raise ValueError('Unexpected parameters: {0}'.format(extras)) + # Make sure everything could be converted. + if len(cannot_convert) != 0: + bad = COMMASPACE.join(sorted(cannot_convert)) + raise ValueError('Cannot convert parameters: {0}'.format(bad)) + # Make sure nothing's missing. + value_keys = set(values) + required_keys = set(self._converters) - self._optional + if value_keys & required_keys != required_keys: + missing = COMMASPACE.join(sorted(required_keys - value_keys)) + raise ValueError('Missing parameters: {0}'.format(missing)) + return values |
