def _patch_put(self, request, response, is_optional): """Update the header match.""" try: header_match = self.header_matches[self._position] except IndexError: not_found( response, 'No header match at this position: {}'.format(self._position)) return kws = dict( header=lowercase, pattern=GetterSetter(regexp_validator), position=int, action=enum_validator(Action), ) if is_optional: # For a PATCH, all attributes are optional. kws['_optional'] = kws.keys() else: # For a PUT, position can remain unchanged and action can be None. kws['_optional'] = ('action', 'position') validator = Validator(**kws) try: arguments = validator(request) action = arguments.pop('action', None) if action is not None: arguments['chain'] = action.name for key, value in arguments.items(): setattr(header_match, key, value) except ValueError as error: bad_request(response, str(error)) return else: no_content(response)
def patch_put(self, request, response, is_optional): domain = getUtility(IDomainManager).get(self._domain) if domain is None: not_found(response) kws = dict( alias_domain=GetterSetter(str), description=GetterSetter(str), owner=ListOfDomainOwners(list_of_strings_validator), ) if is_optional: # For a PATCH, all attributes are optional. kws['_optional'] = kws.keys() try: Validator(**kws).update(domain, request) except ValueError as error: bad_request(response, str(error)) else: no_content(response)
def on_post(self, request, response): # We do not want to encrypt the plaintext password given in the POST # data. That would hash the password, but we need to have the # plaintext in order to pass into passlib. validator = Validator(cleartext_password=GetterSetter(str)) try: values = validator(request) except ValueError as error: bad_request(response, str(error)) return is_valid, new_hash = config.password_context.verify( values['cleartext_password'], self._user.password) if is_valid: if new_hash is not None: self._user.password = new_hash no_content(response) else: forbidden(response)
def on_post(self, request, response): """Add a header match.""" validator = Validator(header=str, pattern=GetterSetter(regexp_validator), action=enum_validator(Action), _optional=('action', )) try: arguments = validator(request) except ValueError as error: bad_request(response, str(error)) return action = arguments.pop('action', None) if action is not None: arguments['chain'] = action.name try: self.header_matches.append(**arguments) except ValueError: bad_request(response, b'This header match already exists') else: header_match = self.header_matches[-1] created(response, self._location(header_match.position))
def patch_put(self, request, response, is_optional): if self._parent is None: not_found(response) return kws = dict( acknowledge_posts=GetterSetter(as_boolean), hide_address=GetterSetter(as_boolean), delivery_mode=GetterSetter(enum_validator(DeliveryMode)), delivery_status=GetterSetter(enum_validator(DeliveryStatus)), preferred_language=GetterSetter(language_validator), receive_list_copy=GetterSetter(as_boolean), receive_own_postings=GetterSetter(as_boolean), ) if is_optional: # For a PUT, all attributes are optional. kws['_optional'] = kws.keys() try: Validator(**kws).update(self._parent, request) except ValueError as error: bad_request(response, str(error)) else: no_content(response)
def get(self, domain, attribute): assert attribute == 'owner', ( 'Unexpected attribute: {}'.format(attribute)) def sort_key(owner): # noqa: E306 return owner.addresses[0].email return sorted(domain.owners, key=sort_key) def put(self, domain, attribute, value): assert attribute == 'owner', ( 'Unexpected attribute: {}'.format(attribute)) domain.add_owners(value) ATTRIBUTES = dict( cleartext_password=PasswordEncrypterGetterSetter(), display_name=GetterSetter(str), is_server_owner=GetterSetter(as_boolean), ) CREATION_FIELDS = dict( display_name=str, email=str, is_server_owner=as_boolean, password=str, _optional=('display_name', 'password', 'is_server_owner'), ) def create_user(api, arguments, response): """Create a new user."""
# REST API. The values of the keys are the GetterSetter instance holding the # decoder used to convert the web request string to an internally valid value. # The instance also contains the get() and put() methods used to retrieve and # set the attribute values. Its .decoder attribute will be None for read-only # attributes. # # The decoder must either return the internal value or raise a ValueError if # the conversion failed (e.g. trying to turn 'Nope' into a boolean). # # Many internal value types can be automatically JSON encoded, but see # mailman.rest.helpers.ExtendedEncoder for specializations of certain types # (e.g. datetimes, timedeltas, enums). ATTRIBUTES = dict( acceptable_aliases=AcceptableAliases(list_of_strings_validator), admin_immed_notify=GetterSetter(as_boolean), admin_notify_mchanges=GetterSetter(as_boolean), administrivia=GetterSetter(as_boolean), advertised=GetterSetter(as_boolean), allow_list_posts=GetterSetter(as_boolean), anonymous_list=GetterSetter(as_boolean), archive_policy=GetterSetter(enum_validator(ArchivePolicy)), autorespond_owner=GetterSetter(enum_validator(ResponseAction)), autorespond_postings=GetterSetter(enum_validator(ResponseAction)), autorespond_requests=GetterSetter(enum_validator(ResponseAction)), autoresponse_grace_period=GetterSetter(as_timedelta), autoresponse_owner_text=GetterSetter(str), autoresponse_postings_text=GetterSetter(str), autoresponse_request_text=GetterSetter(str), bounces_address=GetterSetter(None), collapse_alternatives=GetterSetter(as_boolean),
# Attributes of a user which can be changed via the REST API. class PasswordEncrypterGetterSetter(GetterSetter): def __init__(self): super(PasswordEncrypterGetterSetter, self).__init__( config.password_context.encrypt) def get(self, obj, attribute): assert attribute == 'cleartext_password' super(PasswordEncrypterGetterSetter, self).get(obj, 'password') def put(self, obj, attribute, value): assert attribute == 'cleartext_password' super(PasswordEncrypterGetterSetter, self).put(obj, 'password', value) ATTRIBUTES = dict( display_name=GetterSetter(str), cleartext_password=PasswordEncrypterGetterSetter(), ) CREATION_FIELDS = dict( email=str, display_name=str, password=str, _optional=('display_name', 'password'), ) def create_user(arguments, response): """Create a new user."""
# REST API. The values of the keys are the GetterSetter instance holding the # decoder used to convert the web request string to an internally valid value. # The instance also contains the get() and put() methods used to retrieve and # set the attribute values. Its .decoder attribute will be None for read-only # attributes. # # The decoder must either return the internal value or raise a ValueError if # the conversion failed (e.g. trying to turn 'Nope' into a boolean). # # Many internal value types can be automatically JSON encoded, but see # mailman.rest.helpers.ExtendedEncoder for specializations of certain types # (e.g. datetimes, timedeltas, enums). ATTRIBUTES = dict( acceptable_aliases=AcceptableAliases(list_of_strings_validator), accept_these_nonmembers=GetterSetter(list_of_strings_validator), admin_immed_notify=GetterSetter(as_boolean), admin_notify_mchanges=GetterSetter(as_boolean), administrivia=GetterSetter(as_boolean), advertised=GetterSetter(as_boolean), allow_list_posts=GetterSetter(as_boolean), anonymous_list=GetterSetter(as_boolean), archive_policy=GetterSetter(enum_validator(ArchivePolicy)), archive_rendering_mode=GetterSetter(enum_validator(ArchiveRenderingMode)), autorespond_owner=GetterSetter(enum_validator(ResponseAction)), autorespond_postings=GetterSetter(enum_validator(ResponseAction)), autorespond_requests=GetterSetter(enum_validator(ResponseAction)), autoresponse_grace_period=GetterSetter(as_timedelta), autoresponse_owner_text=GetterSetter(str), autoresponse_postings_text=GetterSetter(str), autoresponse_request_text=GetterSetter(str),
# REST API. The values of the keys are the GetterSetter instance holding the # decoder used to convert the web request string to an internally valid value. # The instance also contains the get() and put() methods used to retrieve and # set the attribute values. Its .decoder attribute will be None for read-only # attributes. # # The decoder must either return the internal value or raise a ValueError if # the conversion failed (e.g. trying to turn 'Nope' into a boolean). # # Many internal value types can be automatically JSON encoded, but see # mailman.rest.helpers.ExtendedEncoder for specializations of certain types # (e.g. datetimes, timedeltas, enums). ATTRIBUTES = dict( acceptable_aliases=AcceptableAliases(list_of_strings_validator), admin_immed_notify=GetterSetter(as_boolean), admin_notify_mchanges=GetterSetter(as_boolean), administrivia=GetterSetter(as_boolean), advertised=GetterSetter(as_boolean), anonymous_list=GetterSetter(as_boolean), autorespond_owner=GetterSetter(enum_validator(ResponseAction)), autorespond_postings=GetterSetter(enum_validator(ResponseAction)), autorespond_requests=GetterSetter(enum_validator(ResponseAction)), autoresponse_grace_period=GetterSetter(as_timedelta), autoresponse_owner_text=GetterSetter(str), autoresponse_postings_text=GetterSetter(str), autoresponse_request_text=GetterSetter(str), archive_policy=GetterSetter(enum_validator(ArchivePolicy)), bounces_address=GetterSetter(None), collapse_alternatives=GetterSetter(as_boolean), convert_html_to_plaintext=GetterSetter(as_boolean),