From 998bc6bbe9d918b637c558cc4896068c2dd7ed91 Mon Sep 17 00:00:00 2001 From: Christian Herdtweck Date: Mon, 2 Dec 2019 13:08:24 +0100 Subject: [PATCH] Change creation of mail users to dynamic This is more easily extendable and avoids old bad habit of passing down huge param dicts to very specific functions like this one. User creation is hard to test, so there is no unittest for this yet. Manual tests succeeded. Have to adapt QA tests and test there further. Additionally to the original conversion, default mail users don't have to be administrators. --- src/mail_utils.py | 81 ++++++++++++++++++++++++++++++++--------------------- 1 files changed, 49 insertions(+), 32 deletions(-) diff --git a/src/mail_utils.py b/src/mail_utils.py index e3339a1..f07cf76 100644 --- a/src/mail_utils.py +++ b/src/mail_utils.py @@ -42,6 +42,7 @@ from email.utils import parsedate_to_datetime from email.parser import BytesParser from email import policy +from .simple_cnf import SimpleCnf # outsourced source, import required for compatiblity from .imap_mailbox import ImapMailbox # pylint: disable=unused-import from .mail_validator import * # pylint: disable=unused-import @@ -80,43 +81,59 @@ def prep_email_header(email_file, value, regex=None, criterion="envelopeto"): % criterion) -def create_users(usernames, config_file, params): +def create_users(usernames, **extra_params): """ - Create cyrus users from an absolute path to a user configuration file. + Create users for sending / receiving mail. - :param usernames: usernames of the created users - :type usernames: [str] - :param str config_file: template config file to use for each user - configuration - :param params: template config file to use for each user configuration - :type params: {str, str} - :raises: :py:class:`RuntimeError` if the user exists already or cannot be - created - """ - log.info("Creating new cyrus users %s", ", ".join(usernames)) - cyrus_user_path = params.get("cyrus_user_path", - "/datastore/imap-mails/user/") - - # check for existence round - for username in usernames: - if os.path.exists(os.path.join(cyrus_user_path, - username.replace(".", "^"))): - raise RuntimeError("The user %s was already created" % username) + The created user settings are complete with spamfilter settings and + groupare folders. User is per default member in groups 1 (admins) and + 2 (all). This cannot yet be changed. - for username in usernames: - params["user"] = '%i: "%s"' % (-1, username) - params["user_fullname"] = username - params_regex = {"user": r'%s,(-?\d+: ".*")'} - arnied_wrapper.set_cnf_semidynamic([config_file], - params, params_regex) + :param usernames: Names of users to create + :type usernames: [str] + All other params are forwarded to user config + """ + if isinstance(usernames, str): + usernames = [usernames,] + default_cnf = dict( + user_disabled="0", + user_locale="", + user_password="1234test", + user_spamfilter_blacklist="", + user_spamfilter_potential_spam_action="FOLDER", + user_spamfilter_potential_spam_action_destaddr="", + user_spamfilter_potential_spam_action_folder="Spamverdacht", + # TODO: this doesn't handle situations where the child variable should not be defined + user_spamfilter_potential_spam_threshold="1050", + user_spamfilter_spam_action="FOLDER", + user_spamfilter_spam_action_destaddr="", + user_spamfilter_spam_action_folder="Spam", + user_spamfilter_spam_deletedays="", + # TODO: this doesn't handle situations where the child variable should not be defined + user_spamfilter_spam_threshold="1080", + user_spamfilter_whitelist="", + user_groupware_folder_drafts="INBOX/Entwürfe", + user_groupware_folder_outbox="INBOX/Gesendete Elemente", + user_groupware_folder_trash="INBOX/Gelöschte Elemente", + ) + + cnf = SimpleCnf() for username in usernames: - if not os.path.exists(os.path.join(cyrus_user_path, - username.replace(".", "^"))): - raise RuntimeError("The user %s could not be created" % username) - else: - log.info("Added new user %s", username) - log.info("%s users successfully created!", len(usernames)) + curr_cnf = default_cnf.copy() + curr_cnf['user_fullname'] = username + curr_cnf.update(extra_params) + children = SimpleCnf() + for key, value in curr_cnf.items(): + if isinstance(value, dict): + children.add(key, children=value) + if not isinstance(value, str): + raise ValueError('Invalid value type for key "{}": {}' + .format(key, type(value))) + children.add(key, value) + children.add('user_group_member_ref', "2") + cnf.add('user', username, children=children, instance=-1) + cnf.apply() def parse_mail_file(file_name, headers_only=True, attachment_filenames=False, -- 1.7.1