summaryrefslogtreecommitdiff
path: root/src/mailman/rest/users.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/rest/users.py')
-rw-r--r--src/mailman/rest/users.py71
1 files changed, 40 insertions, 31 deletions
diff --git a/src/mailman/rest/users.py b/src/mailman/rest/users.py
index 80c53b565..7ab1d6818 100644
--- a/src/mailman/rest/users.py
+++ b/src/mailman/rest/users.py
@@ -27,6 +27,7 @@ __all__ = [
]
+from lazr.config import as_boolean
from passlib.utils import generate_password as generate
from uuid import UUID
from zope.component import getUtility
@@ -39,8 +40,8 @@ from mailman.interfaces.usermanager import IUserManager
from mailman.rest.addresses import UserAddresses
from mailman.rest.helpers import (
BadRequest, CollectionMixin, GetterSetter, NotFound, bad_request, child,
- created, etag, forbidden, no_content, not_found, okay, paginate, path_to,
- conflict)
+ conflict, created, etag, forbidden, no_content, not_found, okay, paginate,
+ path_to)
from mailman.rest.preferences import Preferences
from mailman.rest.validator import PatchValidator, Validator
@@ -63,6 +64,7 @@ ATTRIBUTES = dict(
cleartext_password=PasswordEncrypterGetterSetter(),
)
+
CREATION_FIELDS = dict(
email=unicode,
display_name=unicode,
@@ -73,21 +75,21 @@ CREATION_FIELDS = dict(
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.
+ # 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
+ response, b'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/{0}'.format(user.user_id.int))
+ location = path_to('users/{}'.format(user.user_id.int))
created(response, location)
return user
@@ -106,7 +108,7 @@ class _UserBase(CollectionMixin):
resource = dict(
user_id=user_id,
created_on=user.created_on,
- self_link=path_to('users/{0}'.format(user_id)),
+ 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.
@@ -280,12 +282,15 @@ class AddressUser(_UserBase):
if self._user:
conflict(response)
return
- # Check for an existing user
+ # When creating a linked user by POSTing, the user either must already
+ # exist, or it can be automatically created, if the auto_create flag
+ # is given and true (if missing, it defaults to true). However, in
+ # this case we do not accept 'email' as a POST field.
fields = CREATION_FIELDS.copy()
- del fields["email"]
- fields["user_id"] = int
- fields["autocreate"] = int
- fields["_optional"] = fields["_optional"] + ('user_id', 'autocreate')
+ del fields['email']
+ fields['user_id'] = int
+ fields['auto_create'] = as_boolean
+ fields['_optional'] = fields['_optional'] + ('user_id', 'auto_create')
try:
validator = Validator(**fields)
arguments = validator(request)
@@ -293,32 +298,34 @@ class AddressUser(_UserBase):
bad_request(response, str(error))
return
user_manager = getUtility(IUserManager)
- if "user_id" in arguments:
- user_id = UUID(int=arguments["user_id"])
+ if 'user_id' in arguments:
+ raw_uid = arguments['user_id']
+ user_id = UUID(int=raw_uid)
user = user_manager.get_user_by_id(user_id)
if user is None:
- not_found(response, b"No user with ID {0}".format(
- arguments["user_id"]))
+ not_found(response, b'No user with ID {}'.format(raw_uid))
return
okay(response)
else:
- if arguments.get("autocreate", True): # autocreate by default
- arguments.pop("autocreate", None)
- user = create_user(arguments, response) # will set "201 Created"
+ auto_create = arguments.pop('auto_create', True)
+ if auto_create:
+ # This sets the 201 or 400 status.
+ user = create_user(arguments, response)
+ if user is None:
+ return
else:
- not_found(response, b"No such user, and automatic "
- "creation is disabled.")
+ forbidden(response)
return
user.link(self._address)
def on_put(self, request, response):
- """Set or replace the addresse's user."""
+ """Set or replace the addresses's user."""
if self._user:
self._user.unlink(self._address)
- # Process post data and check for an existing user
+ # Process post data and check for an existing user.
fields = CREATION_FIELDS.copy()
- fields["user_id"] = int
- fields["_optional"] = fields["_optional"] + ('user_id', 'email')
+ fields['user_id'] = int
+ fields['_optional'] = fields['_optional'] + ('user_id', 'email')
try:
validator = Validator(**fields)
arguments = validator(request)
@@ -327,15 +334,17 @@ class AddressUser(_UserBase):
return
user_manager = getUtility(IUserManager)
if 'user_id' in arguments:
- user_id = UUID(int=arguments["user_id"])
+ raw_uid = arguments['user_id']
+ user_id = UUID(int=raw_uid)
user = user_manager.get_user_by_id(user_id)
if user is None:
- not_found(response, b"No user with ID {0}".format(
- arguments["user_id"]))
+ not_found(response, b'No user with ID {}'.format(raw_uid))
return
okay(response)
else:
- user = create_user(arguments, response) # will set "201 Created"
+ user = create_user(arguments, response)
+ if user is None:
+ return
user.link(self._address)