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)
def add_member(mlist, email, display_name, password, delivery_mode, language, role=MemberRole.member): """Add a member right now. The member's subscription must be approved by whatever policy the list enforces. :param mlist: The mailing list to add the member to. :type mlist: `IMailingList` :param email: The email address to subscribe. :type email: str :param display_name: The subscriber's full name. :type display_name: str :param password: The subscriber's plain text password. :type password: str :param delivery_mode: The delivery mode the subscriber has chosen. :type delivery_mode: DeliveryMode :param language: The language that the subscriber is going to use. :type language: str :param role: The membership role for this subscription. :type role: `MemberRole` :return: The just created member. :rtype: `IMember` :raises AlreadySubscribedError: if the user is already subscribed to the mailing list. :raises InvalidEmailAddressError: if the email address is not valid. :raises MembershipIsBannedError: if the membership is not allowed. """ # Let's be extra cautious. getUtility(IEmailValidator).validate(email) # Check to see if the email address is banned. if getUtility(IBanManager).is_banned(email, mlist.fqdn_listname): raise MembershipIsBannedError(mlist, email) # See if there's already a user linked with the given address. user_manager = getUtility(IUserManager) user = user_manager.get_user(email) if user is None: # A user linked to this address does not yet exist. Is the address # itself known but just not linked to a user? address = user_manager.get_address(email) if address is None: # Nope, we don't even know about this address, so create both the # user and address now. user = user_manager.create_user(email, display_name) # Do it this way so we don't have to flush the previous change. address = list(user.addresses)[0] else: # The address object exists, but it's not linked to a user. # Create the user and link it now. user = user_manager.create_user() user.display_name = display_name if display_name else address.display_name user.link(address) # Encrypt the password using the currently selected scheme. The # scheme is recorded in the hashed password string. scheme = lookup(config.passwords.password_scheme.upper()) user.password = make_secret(password, scheme) user.preferences.preferred_language = language member = mlist.subscribe(address, role) member.preferences.delivery_mode = delivery_mode else: # The user exists and is linked to the address. for address in user.addresses: if address.email == email: break else: raise AssertionError("User should have had linked address: {0}".format(address)) # Create the member and set the appropriate preferences. member = mlist.subscribe(address, role) member.preferences.preferred_language = language member.preferences.delivery_mode = delivery_mode return member