From 12d5b37a22ef6eda5b1103cc6a9479ef4bea92e4 Mon Sep 17 00:00:00 2001 From: Plamen Dimitrov Date: Wed, 11 Jul 2012 09:56:58 +0200 Subject: [PATCH] Main module rename and one additional warning in case acls for mailbox were not found --- src/imap_restore_mail.py | 135 ++++++++++++++++++++++++++++++++++++++++++++ src/mail_iterator.py | 4 + src/restore_mail_inject.py | 134 ------------------------------------------- src/unit_tester.py | 2 +- 4 files changed, 140 insertions(+), 135 deletions(-) create mode 100644 src/imap_restore_mail.py delete mode 100644 src/restore_mail_inject.py diff --git a/src/imap_restore_mail.py b/src/imap_restore_mail.py new file mode 100644 index 0000000..e991398 --- /dev/null +++ b/src/imap_restore_mail.py @@ -0,0 +1,135 @@ +''' +restore-mail-inject.py - Tool to inject mails via IMAP + +Copyright (c) 2012 Intra2net AG +Author: Plamen Dimitrov and Thomas Jarosch + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +''' +import logging +import argparse +from mail_iterator import MailIterator +from file_iterator import FileIterator +from warnings_handler import WarningsHandler + +# logging settings +LOG_FILENAME = "restore_mail_inject.log" +LOG_FILE_LEVEL = logging.DEBUG +LOG_SHELL_LEVEL = logging.INFO +LOG_UNCLEAN_EXIT_LEVEL = logging.WARNING + +def main(): + """Main function.""" + + # prepare configuration + args = configure_args() + warnings_handler = prepare_logger() + logging.info("The module restore_mail_inject.py started with user %s, folder %s and source %s.", + args.user, args.folder, args.srcdir) + + # connect to unix socket or server + if(args.unix_socket_disabled): + session = MailIterator(args.user) + else: + session = MailIterator(args.user) + #session = MailIterator("/var/imap/socket/imap", "cyrus", "geheim") + storage = FileIterator() + + # retrieve mailbox list from the mailbox list file + mailbox_list = storage.load_mailbox_list(args.mboxlistfile) + + # delete olf IMAP folders if no append requested + if not args.append: + session.delete_mailboxes(args.folder) + if args.folder == "INBOX": + session.clear_inbox_acls(args.user) + + # inject emails + path_generator = storage.load_mails(args.srcdir, args.folder) + for message, mailbox, date_modified in path_generator: + + # mailboxes marked for creating and acl update + # add acls after all subfolders or their acls will be derived from parent folder + for new_mailbox in storage.created_mailboxes: + session.create_mailbox(new_mailbox) + for acl_mailbox in storage.acl_mailboxes: + session.add_acls(acl_mailbox, mailbox_list, args.ouser, args.user) + storage.created_mailboxes = [] + storage.acl_mailboxes = [] + + session.inject_message(message, mailbox, date_modified) + + # last iteration mailboxes in case root mailbox has no e-mails for injection + for new_mailbox in storage.created_mailboxes: + session.create_mailbox(new_mailbox) + for acl_mailbox in storage.acl_mailboxes: + session.add_acls(acl_mailbox, mailbox_list, args.ouser, args.user) + + logging.info("Finished injecting mails. Exiting with code %s.", warnings_handler.detected_problems) + return warnings_handler.detected_problems + +def configure_args(): + """Configure arguments and return them.""" + + # parse arguments + parser = argparse.ArgumentParser(description="Tool to inject mails via IMAP.") + parser.add_argument('-u', '--username', dest='user', action='store', + required=True, help='user to store mails to') + parser.add_argument('-f', '--foldername', dest='folder', action='store', + default="INBOX", help='folder to store mails to - if not specified we overwrite INBOX') + parser.add_argument('-s', '--sourcedir', dest='srcdir', action='store', + required=True, help='folder to read mail from') + parser.add_argument('-m', '--mboxlistfile', dest='mboxlistfile', action='store', + default="", help='mboxlist file (flat file format) to read the ACLs from') + parser.add_argument('-o', '--ouser', dest='ouser', action='store', + default="", help='name of the original user (=username if not specified)') + parser.add_argument('-a', '--append', dest='append', action='store_true', + default=False, help="append mails, don't delete anything") + parser.add_argument('-n', '--normal', dest='unix_socket_disabled', action='store_true', + default=False, help='disable unix socket usage for the IMAP connection') + args = parser.parse_args() + + if (args.folder != "INBOX"): + args.folder = "INBOX/" + args.folder + if (args.ouser == ""): + args.ouser = args.user + + return args + +def prepare_logger(): + """Sets up the logging functionality""" + + # reset the log + with open(LOG_FILENAME, 'w'): + pass + + # add basic configuration + logging.basicConfig(filename=LOG_FILENAME, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + level=LOG_FILE_LEVEL) + + # add a handler for a console output + default_logger = logging.getLogger('') + console = logging.StreamHandler() + console.setLevel(LOG_SHELL_LEVEL) + formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') + console.setFormatter(formatter) + default_logger.addHandler(console) + + # add a handler for warnings counting + warnings_handler = WarningsHandler() + warnings_handler.setLevel(LOG_UNCLEAN_EXIT_LEVEL) + default_logger.addHandler(warnings_handler) + + return warnings_handler + +if __name__ == "__main__": + main() diff --git a/src/mail_iterator.py b/src/mail_iterator.py index 74a9f81..e7c7f8f 100644 --- a/src/mail_iterator.py +++ b/src/mail_iterator.py @@ -114,8 +114,12 @@ class MailIterator: mbox_acls = mailbox_list[mailbox] except KeyError: # no rights for the mailbox were found + logging.warning("Could not find the acls for mailbox %s for user %s.", mailbox, original_user) return for acl_user in mbox_acls: + # (in case target user != original user): + # - don't overwrite acls eventually set for the current targetuser + # - don't set the default owner acls for the new folder if acl_user != target_user and acl_user != original_user: try: self.mail_con.setacl(mailbox, acl_user, mbox_acls[acl_user]) diff --git a/src/restore_mail_inject.py b/src/restore_mail_inject.py deleted file mode 100644 index a22f758..0000000 --- a/src/restore_mail_inject.py +++ /dev/null @@ -1,134 +0,0 @@ -''' -restore-mail-inject.py - Tool to inject mails via IMAP - -Copyright (c) 2012 Intra2net AG -Author: Plamen Dimitrov and Thomas Jarosch - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -''' -import logging -import argparse -from mail_iterator import MailIterator -from file_iterator import FileIterator -from warnings_handler import WarningsHandler - -LOG_FILENAME = "restore_mail_inject.log" -LOG_FILE_LEVEL = logging.DEBUG -LOG_SHELL_LEVEL = logging.INFO -LOG_UNCLEAN_EXIT_LEVEL = logging.WARNING - -def main(): - """Main function.""" - - # prepare configuration - args = configure_args() - warnings_handler = prepare_logger() - logging.info("The module restore_mail_inject.py started with user %s, folder %s and source %s.", - args.user, args.folder, args.srcdir) - - # connect to unix socket or server - if(args.unix_socket_disabled): - session = MailIterator(args.user) - else: - session = MailIterator(args.user) - #session = MailIterator("/var/imap/socket/imap", "cyrus", "geheim") - storage = FileIterator() - - # retrieve mailbox list from the mailbox list file - mailbox_list = storage.load_mailbox_list(args.mboxlistfile) - - # delete olf IMAP folders if no append requested - if not args.append: - session.delete_mailboxes(args.folder) - if args.folder == "INBOX": - session.clear_inbox_acls(args.user) - - # inject emails - path_generator = storage.load_mails(args.srcdir, args.folder) - for message, mailbox, date_modified in path_generator: - - # mailboxes marked for creating and acl update - # add acls after all subfolders or their acls will be derived from parent folder - for new_mailbox in storage.created_mailboxes: - session.create_mailbox(new_mailbox) - for acl_mailbox in storage.acl_mailboxes: - session.add_acls(acl_mailbox, mailbox_list, args.ouser, args.user) - storage.created_mailboxes = [] - storage.acl_mailboxes = [] - - session.inject_message(message, mailbox, date_modified) - - # last iteration mailboxes in case root mailbox has no e-mails for injection - for new_mailbox in storage.created_mailboxes: - session.create_mailbox(new_mailbox) - for acl_mailbox in storage.acl_mailboxes: - session.add_acls(acl_mailbox, mailbox_list, args.ouser, args.user) - - logging.info("Finished injecting mails. Exiting with code %s.", warnings_handler.detected_problems) - return warnings_handler.detected_problems - -def configure_args(): - """Configure arguments and return them.""" - - # parse arguments - parser = argparse.ArgumentParser(description="Tool to inject mails via IMAP.") - parser.add_argument('-u', '--username', dest='user', action='store', - required=True, help='user to store mails to') - parser.add_argument('-f', '--foldername', dest='folder', action='store', - default="INBOX", help='folder to store mails to - if not specified we overwrite INBOX') - parser.add_argument('-s', '--sourcedir', dest='srcdir', action='store', - required=True, help='folder to read mail from') - parser.add_argument('-m', '--mboxlistfile', dest='mboxlistfile', action='store', - default="", help='mboxlist file (flat file format) to read the ACLs from') - parser.add_argument('-o', '--ouser', dest='ouser', action='store', - default="", help='name of the original user (=username if not specified)') - parser.add_argument('-a', '--append', dest='append', action='store_true', - default=False, help="append mails, don't delete anything") - parser.add_argument('-n', '--normal', dest='unix_socket_disabled', action='store_true', - default=False, help='disable unix socket usage for the IMAP connection') - args = parser.parse_args() - - if (args.folder != "INBOX"): - args.folder = "INBOX/" + args.folder - if (args.ouser == ""): - args.ouser = args.user - - return args - -def prepare_logger(): - """Sets up the logging functionality""" - - # reset the log - with open(LOG_FILENAME, 'w'): - pass - - # add basic configuration - logging.basicConfig(filename=LOG_FILENAME, - format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', - level=LOG_FILE_LEVEL) - - # add a handler for a console output - default_logger = logging.getLogger('') - console = logging.StreamHandler() - console.setLevel(LOG_SHELL_LEVEL) - formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') - console.setFormatter(formatter) - default_logger.addHandler(console) - - # add a handler for warnings counting - warnings_handler = WarningsHandler() - warnings_handler.setLevel(LOG_UNCLEAN_EXIT_LEVEL) - default_logger.addHandler(warnings_handler) - - return warnings_handler - -if __name__ == "__main__": - main() diff --git a/src/unit_tester.py b/src/unit_tester.py index e30a0f6..ea9747a 100644 --- a/src/unit_tester.py +++ b/src/unit_tester.py @@ -62,7 +62,7 @@ class FileContentsParse(unittest.TestCase): parsed_acls = self.file_iter.load_mailbox_list(self.dummy_filename) self.assertIn("user.00schneider", parsed_acls) self.assertIn("00schneider", parsed_acls["user.00schneider"]) - self.assertEqual(parsed_acls["user.00schneider"]["00schneider"], "lrswipkxtecda", "Wront acls were parsed for a user.") + self.assertEqual(parsed_acls["user.00schneider"]["00schneider"], "lrswipkxtecda", "Wrong acls were parsed for a user.") def test_mboxlist_totals(self): -- 1.7.1