created_mailboxes = None
# mailboxes to update during file traversal
acl_mailboxes = None
+ # acls retrieved from a file
+ file_acls = None
def __init__(self):
"""Creates a connection and a user session."""
self.created_mailboxes = []
self.acl_mailboxes = []
-
- return
+ self.file_acls = {}
@classmethod
def _message_read(cls, filename):
return message
- @classmethod
- def load_mailbox_list(cls, mboxlistfile = ""):
+ def load_mailbox_list(self, mboxlistfile, original_user):
"""Load the list of mailboxes and acl rights for each from file."""
- mboxdb = {}
- if mboxlistfile != "":
- try:
- with open(mboxlistfile, 'r') as acl_file:
- for line in acl_file:
-
- acls = {}
+ try:
+ with open(mboxlistfile, 'r') as acl_file:
+ for line in acl_file:
+
+ # read a line using regex
+ acls = {}
+ try:
+ linedata = MBOXFILE_LINE.match(line).groups()
+ except AttributeError:
+ logging.warning("Illegal line in mailbox list dump: %s", line)
+ continue
+ aclstr = linedata[1]
+
+ # changes acls key encoding to internal cyrus format and makes it absolute (as folder).
+ key = linedata[0].replace("INBOX/", "user/" + original_user + "/")
+ key = key.replace(".", "^")
+ key = key.replace("/", ".")
+
+ # loop through acl rights string and build dictionary of users and rights
+ while(aclstr != ""):
try:
- linedata = MBOXFILE_LINE.match(line).groups()
+ acldata = ACL_STRING.match(aclstr).groups()
except AttributeError:
- logging.warning("Illegal line in mailbox list dump: %s", line)
+ logging.warning("Illegal acl string in mailbox list dump: %s", line)
+ aclstr = ""
continue
- key = linedata[0]
- aclstr = linedata[1]
-
- # loop through acl rights string and build dictionary of users and rights
- while(aclstr != ""):
- try:
- acldata = ACL_STRING.match(aclstr).groups()
- except AttributeError:
- logging.warning("Illegal acl string in mailbox list dump: %s", line)
- aclstr = ""
- continue
- aclstr = acldata[2]
- acls[acldata[0]] = acldata[1]
-
- mboxdb[key] = acls
- except IOError:
- logging.warning("Could not open mboxlist file %s", mboxlistfile)
-
- return mboxdb
+ aclstr = acldata[2]
+ acls[acldata[0]] = acldata[1]
+
+ self.acl_mailboxes[key] = acls
+ except IOError:
+ logging.warning("Could not open mboxlist file %s", mboxlistfile)
def load_mails(self, filepath, mailpath):
"""Loads all e-mails from file hierarchy.
# mark mailboxes that need acl update
self.acl_mailboxes.append(mailpath)
-
- return
\ No newline at end of file
session = MailIterator(args.server, args.user, psw)
storage = FileIterator()
- # retrieve mailbox list from the mailbox list file
- mailbox_list = storage.load_mailbox_list(args.mboxlistfile)
+ # retrieve mailbox list if a mailbox list file is specified
+ if args.mboxlistfile != "":
+ storage.load_mailbox_list(args.mboxlistfile, args.ouser)
# delete olf IMAP folders if no append requested
if not args.append:
# inject emails
path_generator = storage.load_mails(args.source, args.destination)
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 = []
-
+ update_mailboxes(storage, session, args)
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)
+ # last iteration for mailboxes in case root mailbox has no e-mails for injection
+ update_mailboxes(storage, session, args)
logging.info("Finished injecting mails. Exiting with code %s.", warnings_handler.detected_problems)
return warnings_handler.detected_problems
+def update_mailboxes(storage, session, args):
+ """Create new mailboxes if necessary and add acls to mailboxes if necessary."""
+
+ # create new mailboxes if found by the file iterator
+ for new_mailbox in storage.created_mailboxes:
+ session.create_mailbox(new_mailbox)
+
+ # add acls after all subfolders or their acls will be derived from parent folder
+ for acl_mailbox in storage.acl_mailboxes:
+ # find folder acls record and retrieve them
+ try:
+ mb_acls = storage.file_acls[acl_mailbox]
+ except KeyError:
+ # no rights for the mailbox were found and warn if acl file loaded
+ if len(storage.file_acls) > 0:
+ logging.warning("Could not find the acls for mailbox %s for user %s.", acl_mailbox, args.ouser)
+ mb_acls = {}
+ session.add_acls(acl_mailbox, mb_acls, args.ouser, args.user)
+ storage.created_mailboxes = []
+ storage.acl_mailboxes = []
+
def configure_args():
"""Configure arguments and return them."""
return
- def add_acls(self, mailbox, mailbox_list, original_user, target_user):
+ def add_acls(self, mailbox, mb_acls, original_user, target_user):
"""Add acls to mailbox."""
- # change encoding to internal cyrus format and make folder absolute
- mailbox = mailbox.replace("INBOX/", "user/" + original_user + "/")
- mailbox = mailbox.replace(".", "^")
- mailbox = mailbox.replace("/", ".")
-
- # find folder to set all acls
- try:
- 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:
+ for acl_user in mb_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])
- logging.debug("Set acls %s for user %s on mailbox %s", mbox_acls[acl_user], acl_user, mailbox)
+ self.mail_con.setacl(mailbox, acl_user, mb_acls[acl_user])
+ logging.debug("Set acls %s for user %s on mailbox %s", mb_acls[acl_user], acl_user, mailbox)
except self.mail_con.error as ex:
- logging.warning("Could not set acls %s for user %s on mailbox %s: %s", mbox_acls[acl_user], acl_user, mailbox, ex)
+ logging.warning("Could not set acls %s for user %s on mailbox %s: %s", mb_acls[acl_user], acl_user, mailbox, ex)
return
for mailbox in self.mailboxes:
pattern = '^\"?' + deleted_mailbox
# if INBOX it cannot be deleted so add delimiter
- if (deleted_mailbox == "INBOX"):
+ if deleted_mailbox == "INBOX":
pattern += mailbox[1]
if re.compile(pattern).match(mailbox[2]):
result, data = self.mail_con.delete(mailbox[2])
return
def create_mailbox(self, mailbox):
-
"""Create new mailbox to inject messages."""
+
if mailbox != "INBOX":
result, data = self.mail_con.create(mailbox)
if result == "OK":
return
def inject_message(self, message, mailbox, internal_date):
-
"""Inject a message into a mailbox."""
+
result, data = self.mail_con.append(mailbox, "\\Seen", internal_date, message.encode())
if result == "OK":
logging.debug("Appending message to mailbox %s", mailbox)