Exemple #1
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 = 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
            created(response, path_to('addresses/{}'.format(address.email)))
Exemple #2
0
 def _resource_as_dict(self, member):
     """See `CollectionMixin`."""
     enum, dot, role = str(member.role).partition('.')
     # Both the user_id and the member_id are UUIDs.  We need to use the
     # integer equivalent in the URL.
     user_id = member.user.user_id.int
     member_id = member.member_id.int
     return dict(
         list_id=member.list_id,
         address=member.address.email,
         role=role,
         user=path_to('users/{0}'.format(user_id)),
         self_link=path_to('members/{0}'.format(member_id)),
         delivery_mode=member.delivery_mode,
         )
Exemple #3
0
 def process(self, args):
     """See `ICLISubCommand`."""
     if args.output is None:
         output = sys.stdout
     else:
         # We don't need to close output because that will happen
         # automatically when the script exits.
         output = open(args.output, 'w')
     print(MAILMAN_VERSION_FULL, file=output)
     print('Python', sys.version, file=output)
     print('config file:', config.filename, file=output)
     print('db url:', config.db.url, file=output)
     print('devmode:',
           'ENABLED' if as_boolean(config.devmode.enabled) else 'DISABLED',
           file=output)
     print('REST root url:',
           path_to('/', config.webservice.api_version),
           file=output)
     print('REST credentials: {0}:{1}'.format(config.webservice.admin_user,
                                              config.webservice.admin_pass),
           file=output)
     if args.verbose:
         print('File system paths:', file=output)
         longest = 0
         paths = {}
         for attribute in dir(config):
             if attribute.endswith('_DIR') or attribute.endswith('_FILE'):
                 paths[attribute] = getattr(config, attribute)
             longest = max(longest, len(attribute))
         for attribute in sorted(paths):
             print('    {0:{2}} = {1}'.format(attribute, paths[attribute],
                                              longest))
Exemple #4
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)
Exemple #5
0
 def create(self, request):
     """Create a new user."""
     try:
         validator = Validator(email=unicode,
                               display_name=unicode,
                               password=unicode,
                               _optional=('display_name', 'password'))
         arguments = validator(request)
     except ValueError as error:
         return http.bad_request([], str(error))
     # We can't pass the 'password' argument to the user creation method,
     # so strip that out (if it exists), then create the user, adding the
     # password after the fact if successful.
     password = arguments.pop('password', None)
     try:
         user = getUtility(IUserManager).create_user(**arguments)
     except ExistingAddressError as error:
         return http.bad_request([], b'Address already exists {0}'.format(
             error.email))
     if password is None:
         # This will have to be reset since it cannot be retrieved.
         password = generate(int(config.passwords.password_length))
     scheme = lookup(config.passwords.password_scheme.upper())
     user.password = make_secret(password, scheme)
     location = path_to('users/{0}'.format(user.user_id.int))
     return http.created(location, [], None)
Exemple #6
0
 def process(self, args):
     """See `ICLISubCommand`."""
     if args.output is None:
         output = sys.stdout
     else:
         # We don't need to close output because that will happen
         # automatically when the script exits.
         output = open(args.output, 'w')
     print(MAILMAN_VERSION_FULL, file=output)
     print('Python', sys.version, file=output)
     print('config file:', config.filename, file=output)
     print('db url:', config.db.url, file=output)
     print('devmode:',
           'ENABLED' if as_boolean(config.devmode.enabled) else 'DISABLED',
           file=output)
     print('REST root url:', path_to('/'), file=output)
     print('REST credentials: {0}:{1}'.format(
         config.webservice.admin_user, config.webservice.admin_pass),
         file=output)
     if args.verbose:
         print('File system paths:', file=output)
         longest = 0
         paths = {}
         for attribute in dir(config):
             if attribute.endswith('_DIR') or attribute.endswith('_FILE'):
                 paths[attribute] = getattr(config, attribute)
             longest = max(longest, len(attribute))
         for attribute in sorted(paths):
             print('    {0:{2}} = {1}'.format(
                 attribute, paths[attribute], longest))
Exemple #7
0
 def on_post(self, request, response):
     """Create a new member."""
     service = getUtility(ISubscriptionService)
     try:
         validator = Validator(
             list_id=unicode,
             subscriber=subscriber_validator,
             display_name=unicode,
             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)
Exemple #8
0
def create_user(arguments, response):
    """Create a new user."""
    # We can't pass the 'password' argument to the user creation method, so
    # strip that out (if it exists), then create the user, adding the password
    # after the fact if successful.
    password = arguments.pop('password', None)
    is_server_owner = arguments.pop('is_server_owner', False)
    user_manager = getUtility(IUserManager)
    try:
        user = user_manager.create_user(**arguments)
    except ExistingAddressError as error:
        # The address already exists.  If the address already has a user
        # linked to it, raise an error, otherwise create a new user and link
        # it to this address.
        email = arguments.pop('email')
        user = user_manager.get_user(email)
        if user is None:
            address = user_manager.get_address(email)
            user = user_manager.create_user(**arguments)
            user.link(address)
        else:
            bad_request(response,
                        'User already exists: {}'.format(error.address))
            return None
    if password is None:
        # This will have to be reset since it cannot be retrieved.
        password = generate(int(config.passwords.password_length))
    user.password = config.password_context.encrypt(password)
    user.is_server_owner = is_server_owner
    location = path_to('users/{}'.format(user.user_id.int))
    created(response, location)
    return user
Exemple #9
0
 def create(self, request):
     """Create a new member."""
     service = getUtility(ISubscriptionService)
     try:
         validator = Validator(
             list_id=unicode,
             subscriber=subscriber_validator,
             display_name=unicode,
             delivery_mode=enum_validator(DeliveryMode),
             role=enum_validator(MemberRole),
             _optional=('delivery_mode', 'display_name', 'role'))
         member = service.join(**validator(request))
     except AlreadySubscribedError:
         return http.conflict([], b'Member already subscribed')
     except NoSuchListError:
         return http.bad_request([], b'No such list')
     except InvalidEmailAddressError:
         return http.bad_request([], b'Invalid email address')
     except ValueError as error:
         return http.bad_request([], str(error))
     # 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))
     # Include no extra headers or body.
     return http.created(location, [], None)
Exemple #10
0
def create_user(arguments, request, response):
    """Create a new user."""
    # We can't pass the 'password' argument to the user creation method, so
    # strip that out (if it exists), then create the user, adding the password
    # after the fact if successful.
    password = arguments.pop('password', None)
    is_server_owner = arguments.pop('is_server_owner', False)
    user_manager = getUtility(IUserManager)
    try:
        user = user_manager.create_user(**arguments)
    except ExistingAddressError as error:
        # The address already exists.  If the address already has a user
        # linked to it, raise an error, otherwise create a new user and link
        # it to this address.
        email = arguments.pop('email')
        user = user_manager.get_user(email)
        if user is None:
            address = user_manager.get_address(email)
            user = user_manager.create_user(**arguments)
            user.link(address)
        else:
            bad_request(
                response, 'User already exists: {}'.format(error.address))
            return None
    if password is None:
        # This will have to be reset since it cannot be retrieved.
        password = generate(int(config.passwords.password_length))
    user.password = config.password_context.encrypt(password)
    user.is_server_owner = is_server_owner
    location = path_to('users/{}'.format(user.user_id.int),
                       request.context['api_version'])
    created(response, location)
    return user
Exemple #11
0
 def on_post(self, request, response):
     """Create a new user."""
     try:
         validator = Validator(email=unicode,
                               display_name=unicode,
                               password=unicode,
                               _optional=('display_name', 'password'))
         arguments = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     # We can't pass the 'password' argument to the user creation method,
     # so strip that out (if it exists), then create the user, adding the
     # password after the fact if successful.
     password = arguments.pop('password', None)
     try:
         user = getUtility(IUserManager).create_user(**arguments)
     except ExistingAddressError as error:
         bad_request(
             response, b'Address already exists: {0}'.format(error.address))
         return
     if password is None:
         # This will have to be reset since it cannot be retrieved.
         password = generate(int(config.passwords.password_length))
     user.password = config.password_context.encrypt(password)
     location = path_to('users/{0}'.format(user.user_id.int))
     created(response, location)
Exemple #12
0
 def on_get(self, request, response):
     """/<api>/system/versions"""
     resource = dict(
         mailman_version=system.mailman_version,
         python_version=system.python_version,
         self_link=path_to('system/versions'),
     )
     okay(response, etag(resource))
Exemple #13
0
 def on_get(self, request, response):
     """/<api>/system"""
     resource = dict(
         mailman_version=system.mailman_version,
         python_version=system.python_version,
         self_link=path_to('system'),
         )
     okay(response, etag(resource))
Exemple #14
0
 def _resource_as_dict(self, domain):
     """See `CollectionMixin`."""
     return dict(
         base_url=domain.base_url,
         description=domain.description,
         mail_host=domain.mail_host,
         self_link=path_to('domains/{0}'.format(domain.mail_host)),
         url_host=domain.url_host,
         )
Exemple #15
0
 def _resource_as_dict(self, domain):
     """See `CollectionMixin`."""
     return dict(
         base_url=domain.base_url,
         description=domain.description,
         mail_host=domain.mail_host,
         self_link=path_to('domains/{0}'.format(domain.mail_host)),
         url_host=domain.url_host,
     )
Exemple #16
0
 def _resource_as_dict(self, address):
     """See `CollectionMixin`."""
     # The canonical url for an address is its lower-cased version,
     # although it can be looked up with either its original or lower-cased
     # email address.
     representation = dict(
         email=address.email,
         original_email=address.original_email,
         registered_on=address.registered_on,
         self_link=path_to("addresses/{0}".format(address.email)),
     )
     # Add optional attributes.  These can be None or the empty string.
     if address.display_name:
         representation["display_name"] = address.display_name
     if address.verified_on:
         representation["verified_on"] = address.verified_on
     if address.user:
         representation["user"] = path_to("users/{0}".format(address.user.user_id.int))
     return representation
Exemple #17
0
 def _resource_as_dict(self, name):
     """See `CollectionMixin`."""
     switchboard = config.switchboards[name]
     files = switchboard.files
     return dict(
         name=switchboard.name,
         directory=switchboard.queue_directory,
         count=len(files),
         files=files,
         self_link=path_to('queues/{}'.format(name)),
         )
Exemple #18
0
 def _resource_as_dict(self, name):
     """See `CollectionMixin`."""
     switchboard = config.switchboards[name]
     files = switchboard.files
     return dict(
         name=switchboard.name,
         directory=switchboard.queue_directory,
         count=len(files),
         files=files,
         self_link=path_to('queues/{}'.format(name)),
     )
Exemple #19
0
 def _resource_as_dict(self, address):
     """See `CollectionMixin`."""
     # The canonical url for an address is its lower-cased version,
     # although it can be looked up with either its original or lower-cased
     # email address.
     representation = dict(
         email=address.email,
         original_email=address.original_email,
         registered_on=address.registered_on,
         self_link=path_to('addresses/{0}'.format(address.email)),
     )
     # Add optional attributes.  These can be None or the empty string.
     if address.display_name:
         representation['display_name'] = address.display_name
     if address.verified_on:
         representation['verified_on'] = address.verified_on
     if address.user:
         representation['user'] = path_to('users/{0}'.format(
             address.user.user_id.int))
     return representation
Exemple #20
0
 def _resource_as_dict(self, mlist):
     """See `CollectionMixin`."""
     return dict(
         display_name=mlist.display_name,
         fqdn_listname=mlist.fqdn_listname,
         list_name=mlist.list_name,
         mail_host=mlist.mail_host,
         member_count=mlist.members.member_count,
         volume=mlist.volume,
         self_link=path_to('lists/{0}'.format(mlist.fqdn_listname)),
         )
Exemple #21
0
 def _resource_as_dict(self, mlist):
     """See `CollectionMixin`."""
     return dict(
         display_name=mlist.display_name,
         fqdn_listname=mlist.fqdn_listname,
         list_id=mlist.list_id,
         list_name=mlist.list_name,
         mail_host=mlist.mail_host,
         member_count=mlist.members.member_count,
         volume=mlist.volume,
         self_link=path_to('lists/{0}'.format(mlist.list_id)),
     )
Exemple #22
0
 def _resource_as_dict(self, member):
     """See `CollectionMixin`."""
     enum, dot, role = str(member.role).partition('.')
     # The member will always have a member id and an address id.  It will
     # only have a user id if the address is linked to a user.
     # E.g. nonmembers we've only seen via postings to lists they are not
     # subscribed to will not have a user id.   The user_id and the
     # member_id are UUIDs.  We need to use the integer equivalent in the
     # URL.
     response = dict(
         list_id=member.list_id,
         email=member.address.email,
         role=role,
         address=path_to('addresses/{}'.format(member.address.email)),
         self_link=path_to('members/{}'.format(member.member_id.int)),
         delivery_mode=member.delivery_mode,
         )
     # Add the user link if there is one.
     user = member.user
     if user is not None:
         response['user'] = path_to('users/{}'.format(user.user_id.int))
     return response
Exemple #23
0
 def system(self, request, segments):
     """/<api>/system"""
     if len(segments) == 0:
         resource = dict(
             mailman_version=system.mailman_version,
             python_version=system.python_version,
             self_link=path_to('system'),
             )
     elif len(segments) > 1:
         return http.bad_request()
     elif segments[0] == 'preferences':
         return ReadOnlyPreferences(system_preferences, 'system'), []
     else:
         return http.bad_request()
     return http.ok([], etag(resource))
Exemple #24
0
 def _resource_as_dict(self, member):
     """See `CollectionMixin`."""
     enum, dot, role = str(member.role).partition('.')
     # The member will always have a member id and an address id.  It will
     # only have a user id if the address is linked to a user.
     # E.g. nonmembers we've only seen via postings to lists they are not
     # subscribed to will not have a user id.   The user_id and the
     # member_id are UUIDs.  We need to use the integer equivalent in the
     # URL.
     member_id = member.member_id.int
     response = dict(
         list_id=member.list_id,
         email=member.address.email,
         role=role,
         address=path_to('addresses/{}'.format(member.address.email)),
         self_link=path_to('members/{}'.format(member_id)),
         delivery_mode=member.delivery_mode,
         member_id=member_id,
     )
     # Add the user link if there is one.
     user = member.user
     if user is not None:
         response['user'] = path_to('users/{}'.format(user.user_id.int))
     return response
Exemple #25
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'))
     except ValueError as error:
         bad_request(response, str(error))
     else:
         created(response, path_to('lists/{0}'.format(mlist.list_id)))
Exemple #26
0
 def create(self, request):
     """Create a new mailing list."""
     try:
         validator = Validator(fqdn_listname=unicode)
         mlist = create_list(**validator(request))
     except ListAlreadyExistsError:
         return http.bad_request([], b'Mailing list exists')
     except BadDomainSpecificationError as error:
         return http.bad_request([], b'Domain does not exist {0}'.format(
             error.domain))
     except ValueError as error:
         return http.bad_request([], str(error))
     # wsgiref wants headers to be bytes, not unicodes.
     location = path_to('lists/{0}'.format(mlist.fqdn_listname))
     # Include no extra headers or body.
     return http.created(location, [], None)
Exemple #27
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'))
     except ValueError as error:
         bad_request(response, str(error))
     else:
         created(response, path_to('lists/{0}'.format(mlist.list_id)))
Exemple #28
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)))
Exemple #29
0
 def on_get(self, request, response):
     resource = dict()
     for attr in PREFERENCES:
         # Handle this one specially.
         if attr == 'preferred_language':
             continue
         value = getattr(self._parent, attr, None)
         if value is not None:
             resource[attr] = value
     # Add the preferred language, if it's not missing.
     preferred_language = self._parent.preferred_language
     if preferred_language is not None:
         resource['preferred_language'] = preferred_language.code
     # Add the self link.
     resource['self_link'] = path_to(
         '{0}/preferences'.format(self._base_url))
     okay(response, etag(resource))
Exemple #30
0
 def on_post(self, request, response):
     """Create a new domain."""
     domain_manager = getUtility(IDomainManager)
     try:
         validator = Validator(mail_host=unicode,
                               description=unicode,
                               base_url=unicode,
                               contact_address=unicode,
                               _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)))
Exemple #31
0
 def on_get(self, request, response):
     resource = dict()
     for attr in PREFERENCES:
         # Handle this one specially.
         if attr == 'preferred_language':
             continue
         value = getattr(self._parent, attr, None)
         if value is not None:
             resource[attr] = value
     # Add the preferred language, if it's not missing.
     preferred_language = self._parent.preferred_language
     if preferred_language is not None:
         resource['preferred_language'] = preferred_language.code
     # Add the self link.
     resource['self_link'] = path_to(
         '{0}/preferences'.format(self._base_url), self.api_version)
     okay(response, etag(resource))
Exemple #32
0
 def create(self, request):
     """Create a new domain."""
     domain_manager = getUtility(IDomainManager)
     try:
         validator = Validator(mail_host=unicode,
                               description=unicode,
                               base_url=unicode,
                               contact_address=unicode,
                               _optional=('description', 'base_url',
                                          'contact_address'))
         domain = domain_manager.add(**validator(request))
     except BadDomainSpecificationError:
         return http.bad_request([], b'Domain exists')
     except ValueError as error:
         return http.bad_request([], str(error))
     location = path_to('domains/{0}'.format(domain.mail_host))
     # Include no extra headers or body.
     return http.created(location, [], None)
Exemple #33
0
 def _resource_as_dict(self, user):
     """See `CollectionMixin`."""
     # The canonical URL for a user is their unique user id, although we
     # can always look up a user based on any registered and validated
     # email address associated with their account.  The user id is a UUID,
     # but we serialize its integer equivalent.
     user_id = user.user_id.int
     resource = dict(
         user_id=user_id,
         created_on=user.created_on,
         self_link=path_to('users/{}'.format(user_id)),
         )
     # Add the password attribute, only if the user has a password.  Same
     # with the real name.  These could be None or the empty string.
     if user.password:
         resource['password'] = user.password
     if user.display_name:
         resource['display_name'] = user.display_name
     return resource
Exemple #34
0
def create_user(arguments, response):
    """Create a new user."""
    # We can't pass the 'password' argument to the user creation method, so
    # strip that out (if it exists), then create the user, adding the password
    # after the fact if successful.
    password = arguments.pop('password', None)
    try:
        user = getUtility(IUserManager).create_user(**arguments)
    except ExistingAddressError as error:
        bad_request(
            response, 'Address already exists: {}'.format(error.address))
        return None
    if password is None:
        # This will have to be reset since it cannot be retrieved.
        password = generate(int(config.passwords.password_length))
    user.password = config.password_context.encrypt(password)
    location = path_to('users/{}'.format(user.user_id.int))
    created(response, location)
    return user
Exemple #35
0
 def _resource_as_dict(self, user):
     """See `CollectionMixin`."""
     # The canonical URL for a user is their unique user id, although we
     # can always look up a user based on any registered and validated
     # email address associated with their account.  The user id is a UUID,
     # but we serialize its integer equivalent.
     user_id = user.user_id.int
     resource = dict(
         user_id=user_id,
         created_on=user.created_on,
         self_link=path_to('users/{0}'.format(user_id)),
         )
     # Add the password attribute, only if the user has a password.  Same
     # with the real name.  These could be None or the empty string.
     if user.password:
         resource['password'] = user.password
     if user.display_name:
         resource['display_name'] = user.display_name
     return resource
Exemple #36
0
def create_user(arguments, response):
    """Create a new user."""
    # We can't pass the 'password' argument to the user creation method, so
    # strip that out (if it exists), then create the user, adding the password
    # after the fact if successful.
    password = arguments.pop('password', None)
    is_server_owner = arguments.pop('is_server_owner', False)
    try:
        user = getUtility(IUserManager).create_user(**arguments)
    except ExistingAddressError as error:
        bad_request(
            response, 'Address already exists: {}'.format(error.address))
        return None
    if password is None:
        # This will have to be reset since it cannot be retrieved.
        password = generate(int(config.passwords.password_length))
    user.password = config.password_context.encrypt(password)
    user.is_server_owner = is_server_owner
    location = path_to('users/{}'.format(user.user_id.int))
    created(response, location)
    return user
Exemple #37
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:
            bad_request(response, b"Address already exists")
        else:
            # Link the address to the current user and return it.
            address.user = self._user
            created(response, path_to("addresses/{0}".format(address.email)))
Exemple #38
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,
                               owner=list_of_strings_validator,
                               _optional=('description', 'base_url',
                                          'owner'))
         values = validator(request)
         # For consistency, owners are passed in as multiple `owner` keys,
         # but .add() requires an `owners` keyword.  Match impedence.
         owners = values.pop('owner', None)
         if owners is not None:
             values['owners'] = owners
         domain = domain_manager.add(**values)
     except BadDomainSpecificationError as error:
         bad_request(response, str(error))
     except ValueError as error:
         bad_request(response, str(error))
     else:
         created(response, path_to('domains/{0}'.format(domain.mail_host)))
Exemple #39
0
 def on_post(self, request, response):
     """Inject a message into the queue."""
     try:
         validator = Validator(list_id=str,
                               text=str)
         values = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     list_id = values['list_id']
     mlist = getUtility(IListManager).get_by_list_id(list_id)
     if mlist is None:
         bad_request(response, 'No such list: {}'.format(list_id))
         return
     try:
         filebase = inject_text(
             mlist, values['text'], switchboard=self._name)
     except Exception as error:
         bad_request(response, str(error))
         return
     else:
         location = path_to('queues/{}/{}'.format(self._name, filebase))
         created(response, location)
Exemple #40
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,
                               owner=list_of_strings_validator,
                               _optional=(
                                   'description', 'base_url', 'owner'))
         values = validator(request)
         # For consistency, owners are passed in as multiple `owner` keys,
         # but .add() requires an `owners` keyword.  Match impedence.
         owners = values.pop('owner', None)
         if owners is not None:
             values['owners'] = owners
         domain = domain_manager.add(**values)
     except BadDomainSpecificationError as error:
         bad_request(response, str(error))
     except ValueError as error:
         bad_request(response, str(error))
     else:
         created(response, path_to('domains/{0}'.format(domain.mail_host)))
Exemple #41
0
 def on_post(self, request, response):
     """Inject a message into the queue."""
     try:
         validator = Validator(list_id=str, text=str)
         values = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     list_id = values['list_id']
     mlist = getUtility(IListManager).get_by_list_id(list_id)
     if mlist is None:
         bad_request(response, 'No such list: {}'.format(list_id))
         return
     try:
         filebase = inject_text(mlist,
                                values['text'],
                                switchboard=self._name)
     except Exception as error:
         bad_request(response, str(error))
         return
     else:
         location = path_to('queues/{}/{}'.format(self._name, filebase))
         created(response, location)
Exemple #42
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:
            bad_request(response, b'Address already exists')
        else:
            # Link the address to the current user and return it.
            address.user = self._user
            created(response, path_to('addresses/{0}'.format(address.email)))
Exemple #43
0
    def create(self, request):
        """POST to /addresses

        Add a new address to the user record.
        """
        if self._user is None:
            return http.not_found()
        user_manager = getUtility(IUserManager)
        validator = Validator(email=unicode,
                              display_name=unicode,
                              _optional=('display_name',))
        try:
            address = user_manager.create_address(**validator(request))
        except ValueError as error:
            return http.bad_request([], str(error))
        except InvalidEmailAddressError:
            return http.bad_request([], b'Invalid email address')
        except ExistingAddressError:
            return http.bad_request([], b'Address already exists')
        else:
            # Link the address to the current user and return it.
            address.user = self._user
            location = path_to('addresses/{0}'.format(address.email))
            return http.created(location, [], None)
Exemple #44
0
 def on_get(self, request, response):
     """<api>/queues"""
     resource = self._make_collection(request)
     resource['self_link'] = path_to('queues')
     okay(response, etag(resource))
Exemple #45
0
 def on_post(self, request, response):
     """Create a new member."""
     try:
         validator = Validator(list_id=str,
                               subscriber=subscriber_validator,
                               display_name=str,
                               delivery_mode=enum_validator(DeliveryMode),
                               role=enum_validator(MemberRole),
                               pre_verified=bool,
                               pre_confirmed=bool,
                               pre_approved=bool,
                               _optional=('delivery_mode', 'display_name',
                                          'role', 'pre_verified',
                                          'pre_confirmed', 'pre_approved'))
         arguments = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     # Dig the mailing list out of the arguments.
     list_id = arguments.pop('list_id')
     mlist = getUtility(IListManager).get_by_list_id(list_id)
     if mlist is None:
         bad_request(response, b'No such list')
         return
     # Figure out what kind of subscriber is being registered.  Either it's
     # a user via their preferred email address or it's an explicit address.
     # If it's a UUID, then it must be associated with an existing user.
     subscriber = arguments.pop('subscriber')
     user_manager = getUtility(IUserManager)
     # We use the display name if there is one.
     display_name = arguments.pop('display_name', '')
     if isinstance(subscriber, UUID):
         user = user_manager.get_user_by_id(subscriber)
         if user is None:
             bad_request(response, b'No such user')
             return
         subscriber = user
     else:
         # This must be an email address.  See if there's an existing
         # address object associated with this email.
         address = user_manager.get_address(subscriber)
         if address is None:
             # Create a new address, which of course will not be validated.
             address = user_manager.create_address(subscriber, display_name)
         subscriber = address
     # What role are we subscribing?  Regular members go through the
     # subscription policy workflow while owners, moderators, and
     # nonmembers go through the legacy API for now.
     role = arguments.pop('role', MemberRole.member)
     if role is MemberRole.member:
         # Get the pre_ flags for the subscription workflow.
         pre_verified = arguments.pop('pre_verified', False)
         pre_confirmed = arguments.pop('pre_confirmed', False)
         pre_approved = arguments.pop('pre_approved', False)
         # Now we can run the registration process until either the
         # subscriber is subscribed, or the workflow is paused for
         # verification, confirmation, or approval.
         registrar = IRegistrar(mlist)
         try:
             token, token_owner, member = registrar.register(
                 subscriber,
                 pre_verified=pre_verified,
                 pre_confirmed=pre_confirmed,
                 pre_approved=pre_approved)
         except AlreadySubscribedError:
             conflict(response, b'Member already subscribed')
             return
         if token is None:
             assert token_owner is TokenOwner.no_one, token_owner
             # The subscription completed.  Let's get the resulting member
             # and return the location to the new member.  Member ids are
             # UUIDs and need to be converted to URLs because JSON doesn't
             # directly support UUIDs.
             member_id = member.member_id.int
             location = path_to('members/{0}'.format(member_id))
             created(response, location)
             return
         # The member could not be directly subscribed because there are
         # some out-of-band steps that need to be completed.  E.g. the user
         # must confirm their subscription or the moderator must approve
         # it.  In this case, an HTTP 202 Accepted is exactly the code that
         # we should use, and we'll return both the confirmation token and
         # the "token owner" so the client knows who should confirm it.
         assert token is not None, token
         assert token_owner is not TokenOwner.no_one, token_owner
         assert member is None, member
         content = dict(token=token, token_owner=token_owner.name)
         accepted(response, etag(content))
         return
     # 2015-04-15 BAW: We're subscribing some role other than a regular
     # member.  Use the legacy API for this for now.
     assert role in (MemberRole.owner, MemberRole.moderator,
                     MemberRole.nonmember)
     # 2015-04-15 BAW: We're limited to using an email address with this
     # legacy API, so if the subscriber is a user, the user must have a
     # preferred address, which we'll use, even though it will subscribe
     # the explicit address.  It is an error if the user does not have a
     # preferred address.
     #
     # If the subscriber is an address object, just use that.
     if IUser.providedBy(subscriber):
         if subscriber.preferred_address is None:
             bad_request(response, b'User without preferred address')
             return
         email = subscriber.preferred_address.email
     else:
         assert IAddress.providedBy(subscriber)
         email = subscriber.email
     delivery_mode = arguments.pop('delivery_mode', DeliveryMode.regular)
     record = RequestRecord(email, display_name, delivery_mode)
     try:
         member = add_member(mlist, record, role)
     except InvalidEmailAddressError:
         bad_request(response, b'Invalid email address')
         return
     except MembershipIsBannedError:
         bad_request(response, b'Membership is banned')
         return
     # The subscription completed.  Let's get the resulting member
     # and return the location to the new member.  Member ids are
     # UUIDs and need to be converted to URLs because JSON doesn't
     # directly support UUIDs.
     member_id = member.member_id.int
     location = path_to('members/{0}'.format(member_id))
     created(response, location)
     return
Exemple #46
0
 def on_post(self, request, response):
     """Create a new member."""
     try:
         validator = Validator(
             list_id=str,
             subscriber=subscriber_validator,
             display_name=str,
             delivery_mode=enum_validator(DeliveryMode),
             role=enum_validator(MemberRole),
             pre_verified=bool,
             pre_confirmed=bool,
             pre_approved=bool,
             _optional=('delivery_mode', 'display_name', 'role',
                        'pre_verified', 'pre_confirmed', 'pre_approved'))
         arguments = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     # Dig the mailing list out of the arguments.
     list_id = arguments.pop('list_id')
     mlist = getUtility(IListManager).get_by_list_id(list_id)
     if mlist is None:
         bad_request(response, b'No such list')
         return
     # Figure out what kind of subscriber is being registered.  Either it's
     # a user via their preferred email address or it's an explicit address.
     # If it's a UUID, then it must be associated with an existing user.
     subscriber = arguments.pop('subscriber')
     user_manager = getUtility(IUserManager)
     # We use the display name if there is one.
     display_name = arguments.pop('display_name', '')
     if isinstance(subscriber, UUID):
         user = user_manager.get_user_by_id(subscriber)
         if user is None:
             bad_request(response, b'No such user')
             return
         subscriber = user
     else:
         # This must be an email address.  See if there's an existing
         # address object associated with this email.
         address = user_manager.get_address(subscriber)
         if address is None:
             # Create a new address, which of course will not be validated.
             address = user_manager.create_address(
                 subscriber, display_name)
         subscriber = address
     # What role are we subscribing?  Regular members go through the
     # subscription policy workflow while owners, moderators, and
     # nonmembers go through the legacy API for now.
     role = arguments.pop('role', MemberRole.member)
     if role is MemberRole.member:
         # Get the pre_ flags for the subscription workflow.
         pre_verified = arguments.pop('pre_verified', False)
         pre_confirmed = arguments.pop('pre_confirmed', False)
         pre_approved = arguments.pop('pre_approved', False)
         # Now we can run the registration process until either the
         # subscriber is subscribed, or the workflow is paused for
         # verification, confirmation, or approval.
         registrar = IRegistrar(mlist)
         try:
             token, token_owner, member = registrar.register(
                 subscriber,
                 pre_verified=pre_verified,
                 pre_confirmed=pre_confirmed,
                 pre_approved=pre_approved)
         except AlreadySubscribedError:
             conflict(response, b'Member already subscribed')
             return
         if token is None:
             assert token_owner is TokenOwner.no_one, token_owner
             # The subscription completed.  Let's get the resulting member
             # and return the location to the new member.  Member ids are
             # UUIDs and need to be converted to URLs because JSON doesn't
             # directly support UUIDs.
             member_id = member.member_id.int
             location = path_to('members/{0}'.format(member_id))
             created(response, location)
             return
         # The member could not be directly subscribed because there are
         # some out-of-band steps that need to be completed.  E.g. the user
         # must confirm their subscription or the moderator must approve
         # it.  In this case, an HTTP 202 Accepted is exactly the code that
         # we should use, and we'll return both the confirmation token and
         # the "token owner" so the client knows who should confirm it.
         assert token is not None, token
         assert token_owner is not TokenOwner.no_one, token_owner
         assert member is None, member
         content = dict(token=token, token_owner=token_owner.name)
         accepted(response, etag(content))
         return
     # 2015-04-15 BAW: We're subscribing some role other than a regular
     # member.  Use the legacy API for this for now.
     assert role in (MemberRole.owner,
                     MemberRole.moderator,
                     MemberRole.nonmember)
     # 2015-04-15 BAW: We're limited to using an email address with this
     # legacy API, so if the subscriber is a user, the user must have a
     # preferred address, which we'll use, even though it will subscribe
     # the explicit address.  It is an error if the user does not have a
     # preferred address.
     #
     # If the subscriber is an address object, just use that.
     if IUser.providedBy(subscriber):
         if subscriber.preferred_address is None:
             bad_request(response, b'User without preferred address')
             return
         email = subscriber.preferred_address.email
     else:
         assert IAddress.providedBy(subscriber)
         email = subscriber.email
     delivery_mode = arguments.pop('delivery_mode', DeliveryMode.regular)
     record = RequestRecord(email, display_name, delivery_mode)
     try:
         member = add_member(mlist, record, role)
     except InvalidEmailAddressError:
         bad_request(response, b'Invalid email address')
         return
     except MembershipIsBannedError:
         bad_request(response, b'Membership is banned')
         return
     # The subscription completed.  Let's get the resulting member
     # and return the location to the new member.  Member ids are
     # UUIDs and need to be converted to URLs because JSON doesn't
     # directly support UUIDs.
     member_id = member.member_id.int
     location = path_to('members/{0}'.format(member_id))
     created(response, location)
     return
Exemple #47
0
 def on_get(self, request, response):
     """<api>/queues"""
     resource = self._make_collection(request)
     resource['self_link'] = path_to('queues')
     okay(response, etag(resource))