diff options
| author | Barry Warsaw | 2012-09-22 13:35:24 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2012-09-22 13:35:24 -0400 |
| commit | 7e97811156ad3fbf9daafc253a2c473b05e07542 (patch) | |
| tree | 82009bad2d877462d42cf1757d3dd96ad436d643 /src/mailman/rest/validator.py | |
| parent | a8e5f267b418cd4bb577ae229fd7e22d5720e93f (diff) | |
| download | mailman-7e97811156ad3fbf9daafc253a2c473b05e07542.tar.gz mailman-7e97811156ad3fbf9daafc253a2c473b05e07542.tar.zst mailman-7e97811156ad3fbf9daafc253a2c473b05e07542.zip | |
Diffstat (limited to 'src/mailman/rest/validator.py')
| -rw-r--r-- | src/mailman/rest/validator.py | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/mailman/rest/validator.py b/src/mailman/rest/validator.py index 7484aa260..f6f0cd7e6 100644 --- a/src/mailman/rest/validator.py +++ b/src/mailman/rest/validator.py @@ -21,6 +21,7 @@ from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ + 'PatchValidator', 'Validator', 'enum_validator', 'language_validator', @@ -31,6 +32,8 @@ __all__ = [ from uuid import UUID from zope.component import getUtility +from mailman.core.errors import ( + ReadOnlyPATCHRequestError, UnknownPATCHRequestError) from mailman.interfaces.languages import ILanguageManager @@ -119,3 +122,50 @@ class Validator: missing = COMMASPACE.join(sorted(required_keys - value_keys)) raise ValueError('Missing parameters: {0}'.format(missing)) return values + + def update(self, obj, request): + """Update the object with the values in the request. + + This first validates and converts the attributes in the request, then + updates the given object with the newly converted values. + + :param obj: The object to update. + :type obj: object + :param request: The HTTP request. + :raises ValueError: if conversion failed for some attribute. + """ + for key, value in self.__call__(request).items(): + self._converters[key].put(obj, key, value) + + + +class PatchValidator(Validator): + """Create a special validator for PATCH requests. + + PATCH is different than PUT because with the latter, you're changing the + entire resource, so all expected attributes must exist. With the former, + you're only changing a subset of the attributes, so you only validate the + ones that exist in the request. + """ + def __init__(self, request, converters): + """Create a validator for the PATCH request. + + :param request: The request object, which must have a .PATCH + attribute. + :param converters: A mapping of attribute names to the converter for + that attribute's type. Generally, this will be a GetterSetter + instance, but it might be something more specific for custom data + types (e.g. non-basic types like unicodes). + :raises UnknownPATCHRequestError: if the request contains an unknown + attribute, i.e. one that is not in the `attributes` mapping. + :raises ReadOnlyPATCHRequest: if the requests contains an attribute + that is defined as read-only. + """ + validationators = {} + for attribute in request.PATCH: + if attribute not in converters: + raise UnknownPATCHRequestError(attribute) + if converters[attribute].decoder is None: + raise ReadOnlyPATCHRequestError(attribute) + validationators[attribute] = converters[attribute] + super(PatchValidator, self).__init__(**validationators) |
