Example #1
0
 def on_post(self, request, response):
     """POST to /domains/<domain>/owners """
     if self._domain is None:
         not_found(response)
         return
     validator = Validator(
         owner=ListOfDomainOwners(list_of_strings_validator))
     try:
         validator.update(self._domain, request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     return no_content(response)
Example #2
0
 def on_post(self, request, response):
     """POST to /domains/<domain>/owners """
     if self._domain is None:
         not_found(response)
         return
     validator = Validator(
         owner=ListOfDomainOwners(list_of_strings_validator))
     try:
         validator.update(self._domain, request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     return no_content(response)
Example #3
0
 def on_put(self, request, response):
     """Set a mailing list configuration."""
     attribute = self._attribute
     if attribute is None:
         validator = Validator(**VALIDATORS)
         try:
             validator.update(self._mlist, request)
         except ValueError as error:
             bad_request(response, str(error))
             return
     elif attribute not in ATTRIBUTES:
         bad_request(response, b'Unknown attribute: {}'.format(attribute))
         return
     elif ATTRIBUTES[attribute].decoder is None:
         bad_request(
             response, b'Read-only attribute: {}'.format(attribute))
         return
     else:
         validator = Validator(**{attribute: VALIDATORS[attribute]})
         try:
             validator.update(self._mlist, request)
         except ValueError as error:
             bad_request(response, str(error))
             return
     no_content(response)
    def _find(self, request, response):
        validator = Validator(
            header=str,
            action=enum_validator(Action),
            tag=str,
            _optional=('action', 'tag', 'header')
           )
        try:
            data = validator(request)
        except ValueError as error:
            bad_request(response, str(error))
            return

        # Remove any optional pagination elements.
        action = data.pop('action', None)
        if action is not None:
            data['chain'] = action.name
        service = IHeaderMatchList(self._mlist)
        self.header_matches = list(service.filter(**data))

        # Return 404 if no values were found.
        if len(self.header_matches) == 0:
            return not_found(
                response,
                'Cound not find any HeaderMatch for provided search options.')

        resource = self._make_collection(request)
        okay(response, etag(resource))
Example #5
0
 def on_post(self, request, response):
     """Create a new member."""
     service = getUtility(ISubscriptionService)
     try:
         validator = Validator(list_id=str,
                               subscriber=subscriber_validator,
                               display_name=str,
                               delivery_mode=enum_validator(DeliveryMode),
                               role=enum_validator(MemberRole),
                               _optional=('delivery_mode', 'display_name',
                                          'role'))
         member = service.join(**validator(request))
     except AlreadySubscribedError:
         conflict(response, b'Member already subscribed')
     except NoSuchListError:
         bad_request(response, b'No such list')
     except InvalidEmailAddressError:
         bad_request(response, b'Invalid email address')
     except ValueError as error:
         bad_request(response, str(error))
     else:
         # The member_id are UUIDs.  We need to use the integer equivalent
         # in the URL.
         member_id = member.member_id.int
         location = path_to('members/{0}'.format(member_id))
         created(response, location)
Example #6
0
 def _find(self, request, response):
     """Find a member"""
     service = getUtility(ISubscriptionService)
     validator = Validator(
         list_id=str,
         subscriber=str,
         role=enum_validator(MemberRole),
         # Allow pagination.
         page=int,
         count=int,
         fields=list_of_strings_validator,
         _optional=('list_id', 'subscriber', 'role', 'page', 'count',
                    'fields'))
     try:
         data = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
     else:
         # Remove any optional pagination query elements; they will be
         # handled later.
         data.pop('page', None)
         data.pop('count', None)
         fields = data.pop('fields', None)
         members = service.find_members(**data)
         resource = _FoundMembers(members, self.api)
         try:
             collection = resource._make_collection(request, fields)
         except ValueError as ex:
             bad_request(response, str(ex))
             return
         okay(response, etag(collection))
Example #7
0
 def on_post(self, request, response):
     try:
         validator = Validator(send=as_boolean,
                               bump=as_boolean,
                               periodic=as_boolean,
                               _optional=('send', 'bump', 'periodic'))
         values = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     if values.get('send', False) and values.get('periodic', False):
         # Send and periodic and mutually exclusive options.
         bad_request(response,
                     'send and periodic options are mutually exclusive')
         return
     if len(values) == 0:
         # There's nothing to do, but that's okay.
         okay(response)
         return
     if values.get('bump', False):
         bump_digest_number_and_volume(self._mlist)
     if values.get('send', False):
         maybe_send_digest_now(self._mlist, force=True)
     if values.get('periodic', False) and self._mlist.digest_send_periodic:
         maybe_send_digest_now(self._mlist, force=True)
     accepted(response)
Example #8
0
 def on_post(self, request, response):
     try:
         validator = Validator(action=enum_validator(Action))
         arguments = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     requests = IListRequests(self._mlist)
     try:
         request_id = int(self._request_id)
     except ValueError:
         bad_request(response)
         return
     results = requests.get_request(request_id)
     if results is None:
         not_found(response)
         return
     key, data = results
     try:
         request_type = RequestType[data['_request_type']]
     except ValueError:
         bad_request(response)
         return
     if request_type is RequestType.subscription:
         handle_subscription(self._mlist, request_id, **arguments)
     elif request_type is RequestType.unsubscription:
         handle_unsubscription(self._mlist, request_id, **arguments)
     else:
         bad_request(response)
         return
     no_content(response)
Example #9
0
 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=str,
         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)
Example #10
0
 def on_put(self, request, response):
     """Set or replace the addresses's user."""
     if self._user:
         self._user.unlink(self._address)
     # Process post data and check for an existing user.
     fields = CREATION_FIELDS.copy()
     fields['user_id'] = self.api.to_uuid
     fields['_optional'] = fields['_optional'] + (
         'user_id', 'email', 'is_server_owner')
     try:
         validator = Validator(**fields)
         arguments = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     user_manager = getUtility(IUserManager)
     if 'user_id' in arguments:
         user_id = arguments['user_id']
         user = user_manager.get_user_by_id(user_id)
         if user is None:
             not_found(response, b'No user with ID {}'.format(user_id))
             return
         okay(response)
     else:
         user = create_user(self.api, arguments, response)
         if user is None:
             return
     user.link(self._address)
    def on_get(self, request, response):
        """/lists/listname/requests"""
        validator = Validator(
            token_owner=enum_validator(TokenOwner),
            request_type=enum_validator(PendType),
            page=int,
            count=int,
            _optional=['token_owner', 'page', 'count', 'request_type'],
            )

        try:
            data = validator(request)
        except ValueError as error:
            bad_request(response, str(error))
        else:
            data.pop('page', None)
            data.pop('count', None)
            token_owner = data.pop('token_owner', None)
            pend_type = data.pop('request_type', PendType.subscription)
            pendings = getUtility(IPendings).find(
                mlist=self._mlist,
                pend_type=pend_type.name,
                token_owner=token_owner)
            resource = _SubscriptionRequestsFound(
                [token for token, pendable in pendings])
            okay(response, etag(resource._make_collection(request)))
Example #12
0
 def _find(self, request, response):
     validator = Validator(
         subscriber=subscriber_validator(self.api),
         role=enum_validator(MemberRole),
         # Allow pagination.
         page=int,
         count=int,
         _optional=('role', 'page', 'count'))
     try:
         data = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     else:
         # Remove any optional pagination query elements.
         data.pop('page', None)
         data.pop('count', None)
         service = getUtility(ISubscriptionService)
         # Get all membership records for given subscriber.
         memberships = service.find_members(**data)
         # Get all the lists from from the membership records.
         lists = [
             getUtility(IListManager).get_by_list_id(member.list_id)
             for member in memberships
         ]
         # If there are no matching lists, return a 404.
         if not len(lists):
             return not_found(response)
         resource = _ListOfLists(lists, self.api)
         okay(response, etag(resource._make_collection(request)))
Example #13
0
    def on_patch(self, request, response):
        """Patch the membership.

        This is how subscription changes are done.
        """
        if self._member is None:
            not_found(response)
            return
        try:
            values = Validator(
                address=str,
                delivery_mode=enum_validator(DeliveryMode),
                moderation_action=enum_validator(Action, allow_blank=True),
                _optional=('address', 'delivery_mode', 'moderation_action'),
            )(request)
        except ValueError as error:
            bad_request(response, str(error))
            return
        if 'address' in values:
            email = values['address']
            address = getUtility(IUserManager).get_address(email)
            if address is None:
                bad_request(response, b'Address not registered')
                return
            try:
                self._member.address = address
            except (MembershipError, UnverifiedAddressError) as error:
                bad_request(response, str(error))
                return
        if 'delivery_mode' in values:
            self._member.preferences.delivery_mode = values['delivery_mode']
        if 'moderation_action' in values:
            self._member.moderation_action = values['moderation_action']
        no_content(response)
Example #14
0
    def on_post(self, request, response):
        """POST to /addresses

        Add a new address to the user record.
        """
        if self._user is None:
            not_found(response)
            return
        user_manager = getUtility(IUserManager)
        validator = Validator(email=str,
                              display_name=str,
                              _optional=('display_name', ))
        try:
            address = user_manager.create_address(**validator(request))
        except ValueError as error:
            bad_request(response, str(error))
        except InvalidEmailAddressError:
            bad_request(response, b'Invalid email address')
        except ExistingAddressError:
            # Check if the address is not linked to any user, link it to the
            # current user and return it.  Since we're linking to an existing
            # address, ignore any given display_name attribute.
            address = user_manager.get_address(validator(request)['email'])
            if address.user is None:
                address.user = self._user
                location = self.path_to('addresses/{}'.format(address.email))
                created(response, location)
            else:
                bad_request(response, 'Address belongs to other user.')
        else:
            # Link the address to the current user and return it.
            address.user = self._user
            location = self.path_to('addresses/{}'.format(address.email))
            created(response, location)
Example #15
0
 def put_update(self, request):
     """Put the user's configuration (i.e. full update)."""
     if self._user is None:
         return http.not_found()
     validator = Validator(**ATTRIBUTES)
     try:
         validator.update(self._user, request)
     except UnknownPATCHRequestError as error:
         return http.bad_request(
             [], b'Unknown attribute: {0}'.format(error.attribute))
     except ReadOnlyPATCHRequestError as error:
         return http.bad_request(
             [], b'Read-only attribute: {0}'.format(error.attribute))
     except ValueError as error:
         return http.bad_request([], str(error))
     return no_content()
Example #16
0
 def on_post(self, request, response):
     try:
         resource = Validator(number=int)(request)
         self._plugin.number = resource['number']
     except ValueError as error:
         bad_request(response, str(error))
     else:
         no_content(response)
    def on_post(self, request, response):
        """POST to /addresses

        Add a new address to the user record.
        """
        assert self._user is not None
        preferred = None
        user_manager = getUtility(IUserManager)
        validator = Validator(email=str,
                              display_name=str,
                              preferred=as_boolean,
                              absorb_existing=bool,
                              _optional=('display_name', 'absorb_existing',
                                         'preferred'))
        try:
            data = validator(request)
            # We cannot set the address to be preferred when it is
            # created so remove it from the arguments here and
            # set it below.
            preferred = data.pop('preferred', False)
        except ValueError as error:
            bad_request(response, str(error))
            return
        absorb_existing = data.pop('absorb_existing', False)
        try:
            address = user_manager.create_address(**data)
        except InvalidEmailAddressError:
            bad_request(response, b'Invalid email address')
            return
        except ExistingAddressError:
            # If the address is not linked to any user, link it to the current
            # user and return it.  Since we're linking to an existing address,
            # ignore any given display_name attribute.
            address = user_manager.get_address(data['email'])
            if address.user is None:
                address.user = self._user
                location = self.api.path_to('addresses/{}'.format(
                    address.email))
                created(response, location)
                return
            elif not absorb_existing:
                bad_request(response, 'Address belongs to other user')
                return
            else:
                # The address exists and is linked but we can merge the users.
                address = user_manager.get_address(data['email'])
                self._user.absorb(address.user)
        else:
            # Link the address to the current user and return it.
            address.user = self._user

            # Set the preferred address here if we were signalled to do so.
            if preferred:
                address.verified_on = now()
                self._user.preferred_address = address

        location = self.api.path_to('addresses/{}'.format(address.email))
        created(response, location)
Example #18
0
 def on_put(self, request, response):
     """Put the user's configuration (i.e. full update)."""
     if self._user is None:
         not_found(response)
         return
     validator = Validator(**ATTRIBUTES)
     try:
         validator.update(self._user, request)
     except UnknownPATCHRequestError as error:
         bad_request(
             response, b'Unknown attribute: {0}'.format(error.attribute))
     except ReadOnlyPATCHRequestError as error:
         bad_request(
             response, b'Read-only attribute: {0}'.format(error.attribute))
     except ValueError as error:
         bad_request(response, str(error))
     else:
         no_content(response)
Example #19
0
 def on_post(self, request, response):
     """Create a new user."""
     try:
         validator = Validator(**CREATION_FIELDS)
         arguments = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     create_user(self.api, arguments, response)
Example #20
0
 def on_put(self, request, response):
     """Put the user's configuration (i.e. full update)."""
     if self._user is None:
         not_found(response)
         return
     validator = Validator(**ATTRIBUTES)
     try:
         validator.update(self._user, request)
     except UnknownPATCHRequestError as error:
         bad_request(
             response, b'Unknown attribute: {0}'.format(error.attribute))
     except ReadOnlyPATCHRequestError as error:
         bad_request(
             response, b'Read-only attribute: {0}'.format(error.attribute))
     except ValueError as error:
         bad_request(response, str(error))
     else:
         no_content(response)
Example #21
0
 def on_delete(self, request, response):
     """Delete the member (i.e. unsubscribe)."""
     # Leaving a list is a bit different than deleting a moderator or
     # owner.  Handle the former case first.  For now too, we will not send
     # an admin or user notification.
     if self._member is None:
         not_found(response)
         return
     mlist = getUtility(IListManager).get_by_list_id(self._member.list_id)
     if self._member.role is MemberRole.member:
         try:
             values = Validator(
                 pre_confirmed=as_boolean,
                 pre_approved=as_boolean,
                 _optional=('pre_confirmed', 'pre_approved'),
             )(request)
         except ValueError as error:
             bad_request(response, str(error))
             return
         manager = ISubscriptionManager(mlist)
         # XXX(maxking): For backwards compat, we are going to keep
         # pre-confirmed to be "True" by defualt instead of "False", that it
         # should be. Any, un-authenticated requests should manually specify
         # that it is *not* confirmed by the user.
         if 'pre_confirmed' in values:
             pre_confirmed = values.get('pre_confirmed')
         else:
             pre_confirmed = True
         token, token_owner, member = manager.unregister(
             self._member.address,
             pre_approved=values.get('pre_approved'),
             pre_confirmed=pre_confirmed)
         if member is None:
             assert token is None
             assert token_owner is TokenOwner.no_one
             no_content(response)
         else:
             assert token is not None
             content = dict(token=token, token_owner=token_owner.name)
             accepted(response, etag(content))
     else:
         self._member.unsubscribe()
         no_content(response)
Example #22
0
 def patch_put(self, request, is_optional):
     if self._parent is None:
         return http.not_found()
     kws = dict(
         acknowledge_posts=as_boolean,
         delivery_mode=enum_validator(DeliveryMode),
         delivery_status=enum_validator(DeliveryStatus),
         preferred_language=language_validator,
         receive_list_copy=as_boolean,
         receive_own_postings=as_boolean,
         )
     if is_optional:
         # For a PUT, all attributes are optional.
         kws['_optional'] = kws.keys()
     try:
         values = Validator(**kws)(request)
     except ValueError as error:
         return http.bad_request([], str(error))
     for key, value in values.items():
         setattr(self._parent, key, value)
     return no_content()
Example #23
0
 def on_put(self, request, response):
     """Set a mailing list configuration."""
     attribute = self._attribute
     if attribute is None:
         validator = Validator(**VALIDATORS)
         try:
             validator.update(self._mlist, request)
         except ValueError as error:
             bad_request(response, str(error))
             return
     elif attribute not in ATTRIBUTES:
         bad_request(response, b'Unknown attribute: {}'.format(attribute))
         return
     elif ATTRIBUTES[attribute].decoder is None:
         bad_request(
             response, b'Read-only attribute: {}'.format(attribute))
         return
     else:
         validator = Validator(**{attribute: VALIDATORS[attribute]})
         try:
             validator.update(self._mlist, request)
         except ValueError as error:
             bad_request(response, str(error))
             return
     no_content(response)
Example #24
0
 def on_post(self, request, response):
     """Ban some email from subscribing."""
     validator = Validator(email=str)
     try:
         email = validator(request)['email']
     except ValueError as error:
         bad_request(response, str(error))
         return
     if self.ban_manager.is_banned(email):
         bad_request(response, b'Address is already banned')
     else:
         self.ban_manager.ban(email)
         created(response, self._location(email))
Example #25
0
 def patch_put(self, request, response, is_optional):
     archiver_set = IListArchiverSet(self._mlist)
     kws = {archiver.name: ArchiverGetterSetter(self._mlist)
            for archiver in archiver_set.archivers}
     if is_optional:
         # For a PATCH, all attributes are optional.
         kws['_optional'] = kws.keys()
     try:
         Validator(**kws).update(self._mlist, request)
     except ValueError as error:
         bad_request(response, str(error))
     else:
         no_content(response)
Example #26
0
 def on_put(self, request, response):
     """Set a mailing list configuration."""
     attribute = self._attribute
     # The list of required attributes differs between API version.  For
     # backward compatibility, in API 3.0 all of the *_uri attributes are
     # optional.  In API 3.1 none of these are allowed since they are
     # handled by the template manager API.
     validators = VALIDATORS.copy()
     attributes = api_attributes(self.api)
     if self.api.version_info == (3, 0):
         validators.update({
             attribute: URIAttributeMapper(str)
             for attribute in TEMPLATE_ATTRIBUTES
             })
         validators['_optional'] = TEMPLATE_ATTRIBUTES.keys()
     if attribute is None:
         # This is a request to update all the list's writable
         # configuration variables.  All must be provided in the request.
         validator = Validator(**validators)
         try:
             validator.update(self._mlist, request)
         except ValueError as error:
             # Unlike the case where we're PUTting to a specific
             # configuration sub-resource, if we're PUTting to the list's
             # entire configuration, but the request has a bogus attribute,
             # the entire request is considered bad.  We can also get here
             # if one of the attributes is read-only.  The error will
             # contain sufficient details, so just return it as the reason.
             bad_request(response, str(error))
             return
     elif attribute not in attributes:
         # Here we're PUTting to a specific resource, but that attribute is
         # bogus so the URL is considered pointing to a missing resource.
         not_found(response, 'Unknown attribute: {}'.format(attribute))
         return
     elif attributes[attribute].decoder is None:
         bad_request(
             response, 'Read-only attribute: {}'.format(attribute))
         return
     else:
         # We're PUTting to a specific configuration sub-resource.
         validator = Validator(**{attribute: validators[attribute]})
         try:
             validator.update(self._mlist, request)
         except ValueError as error:
             bad_request(response, str(error))
             return
     no_content(response)
Example #27
0
 def on_post(self, request, response):
     """Find a member"""
     service = getUtility(ISubscriptionService)
     validator = Validator(list_id=str,
                           subscriber=str,
                           role=enum_validator(MemberRole),
                           _optional=('list_id', 'subscriber', 'role'))
     try:
         members = service.find_members(**validator(request))
     except ValueError as error:
         bad_request(response, str(error))
     else:
         resource = _FoundMembers(members, self.api_version)
         okay(response, etag(resource._make_collection(request)))
Example #28
0
 def on_post(self, request, response):
     """Create a new mailing list."""
     try:
         validator = Validator(fqdn_listname=str,
                               style_name=str,
                               _optional=('style_name', ))
         mlist = create_list(**validator(request))
     except ListAlreadyExistsError:
         bad_request(response, b'Mailing list exists')
     except BadDomainSpecificationError as error:
         reason = 'Domain does not exist: {}'.format(error.domain)
         bad_request(response, reason.encode('utf-8'))
     else:
         location = self.api.path_to('lists/{0}'.format(mlist.list_id))
         created(response, location)
Example #29
0
 def _patch_put(self, request, response, is_optional):
     kws = {uri: str for uri in self.URIs}
     optionals = ['username', 'password']
     if is_optional:
         optionals.extend(self.URIs)
     # When PATCHing or PUTing all uris, a single optional
     # username/password applies to them all.
     kws['username'] = str
     kws['password'] = str
     kws['_optional'] = optionals
     try:
         arguments = Validator(**kws)(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     username = arguments.pop('username', None)
     password = arguments.pop('password', None)
     if not username and not password:
         # Normalize arguments.
         set_kws = {}
     elif username and password:
         # It's fine if both are specified.
         set_kws = dict(username=username, password=password)
     else:
         bad_request(response,
                     'Specify both username and password, or neither')
         return
     manager = getUtility(ITemplateManager)
     for key, value in arguments.items():
         if len(value) == 0:
             # The empty string is equivalent to DELETE.  Yeah, this isn't
             # very RESTful, but practicality beats purity.
             manager.delete(key, self._raw_context)
         else:
             manager.set(key, self._raw_context, value, **set_kws)
     no_content(response)
Example #30
0
 def on_delete(self, request, response):
     """DELETE to /domains/<domain>/owners"""
     if self._domain is None:
         not_found(response)
     try:
         # No arguments.
         Validator()(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     owner_email = [
         owner.addresses[0].email for owner in self._domain.owners
     ]
     for email in owner_email:
         self._domain.remove_owner(email)
     return no_content(response)
Example #31
0
 def patch_put(self, request, response, is_optional):
     domain = getUtility(IDomainManager).get(self._domain)
     if domain is None:
         not_found(response)
     kws = dict(
         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_get(self, request, response):
     validator = Validator(
         token_owner=enum_validator(TokenOwner),
         request_type=enum_validator(PendType),
         _optional=['token_owner', 'request_type'])
     try:
         data = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
     else:
         token_owner = data.pop('token_owner', None)
         pend_type = data.pop('request_type', PendType.subscription)
         count = getUtility(IPendings).count(
             mlist=self._mlist,
             pend_type=pend_type.name,
             token_owner=token_owner)
         okay(response, etag(dict(count=count)))
Example #33
0
 def on_delete(self, request, response):
     """Delete the members of the named mailing list."""
     status = {}
     try:
         validator = Validator(emails=list_of_strings_validator)
         arguments = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     emails = arguments.pop('emails')
     success, fail = getUtility(ISubscriptionService).unsubscribe_members(
         self._mlist.list_id, emails)
     # There should be no email in both sets.
     assert success.isdisjoint(fail), (success, fail)
     status.update({email: True for email in success})
     status.update({email: False for email in fail})
     okay(response, etag(status))
Example #34
0
 def on_post(self, request, response):
     """Create a new domain."""
     domain_manager = getUtility(IDomainManager)
     try:
         validator = Validator(mail_host=str,
                               description=str,
                               base_url=str,
                               contact_address=str,
                               _optional=('description', 'base_url',
                                          'contact_address'))
         domain = domain_manager.add(**validator(request))
     except BadDomainSpecificationError:
         bad_request(response, b'Domain exists')
     except ValueError as error:
         bad_request(response, str(error))
     else:
         created(response, path_to('domains/{0}'.format(domain.mail_host)))
 def on_patch(self, request, response):
     """Patch an existing Address."""
     if self._address is None:
         not_found(response)
     else:
         # The only attribute of a address that can be PATCH'd is the
         # display_name. To change the verified_on, use the /verify
         # endpoint.
         validator = Validator(display_name=str)
         try:
             data = validator(request)
         except ValueError as error:
             bad_request(response, str(error))
             return
         display_name = data.pop('display_name')
         self._address.display_name = display_name
         no_content(response)
Example #36
0
 def on_put(self, request, response):
     """Set a mailing list configuration."""
     attribute = self._attribute
     if attribute is None:
         # This is a request to update all the list's writable
         # configuration variables.  All must be provided in the request.
         validator = Validator(**VALIDATORS)
         try:
             validator.update(self._mlist, request)
         except ValueError as error:
             # Unlike the case where we're PUTting to a specific
             # configuration sub-resource, if we're PUTting to the list's
             # entire configuration, but the request has a bogus attribute,
             # the entire request is considered bad.  We can also get here
             # if one of the attributes is read-only.  The error will
             # contain sufficient details, so just return it as the reason.
             bad_request(response, str(error))
             return
     elif attribute not in ATTRIBUTES:
         # Here we're PUTting to a specific resource, but that attribute is
         # bogus so the URL is considered pointing to a missing resource.
         not_found(response, 'Unknown attribute: {}'.format(attribute))
         return
     elif ATTRIBUTES[attribute].decoder is None:
         bad_request(
             response, 'Read-only attribute: {}'.format(attribute))
         return
     else:
         # We're PUTting to a specific configuration sub-resource.
         validator = Validator(**{attribute: VALIDATORS[attribute]})
         try:
             validator.update(self._mlist, request)
         except ValueError as error:
             bad_request(response, str(error))
             return
     no_content(response)