Basic acl functionality added
[imap-restore-mail] / mail_iterator.py
CommitLineData
67e2ec02
PD
1'''
2restore-mail-inject.py - Tool to inject mails via IMAP
3
4Copyright (c) 2012 Intra2net AG
5'''
6
7import imaplib
8import re
9
10MAILBOX_RESP = re.compile(r'\((?P<flags>.*?)\) "(?P<delimiter>.*)" (?P<name>.*)')
11UIDVAL_RESP = re.compile(r'(?P<name>.*) \(UIDVALIDITY (?P<uidval>.*)\)')
12
13class MailIterator:
14 """This class communicates with the e-mail server."""
15
16 # class attributes
17 # IMAP4_SSL for connection with an IMAP server
18 mail_con = None
19 # list of tuples (uidvalidity, mailboxname) for the retrieved mailboxes
20 mailboxes = None
21 # logged in status
22 logged_in = None
23
24 def __init__(self, server, username, password):
25 """Creates a connection and a user session."""
26 # authentication
27 try:
28 self.mail_con = imaplib.IMAP4_SSL(server)
29 self.mail_con.login(username, password)
30 print("Logged in as %s." % username)
31 except:
32 self.logged_in = False
33 print("Could not log in as user " + username + ".")
34 raise UserWarning
35 self.logged_in = True
36
37 # prepare mailboxes
38 _result, mailboxes = self.mail_con.list()
39 self.mailboxes = []
40 for mailbox in mailboxes:
41 mailbox = MAILBOX_RESP.match(mailbox.decode('iso-8859-1')).groups()
42 self.mailboxes.append(mailbox)
43 self.mailboxes = sorted(self.mailboxes, key=lambda box: box[2], reverse=True)
44 return
45
46 def __del__(self):
47 """Closes the connection and the user session."""
e42bd6a5 48 if self.logged_in:
67e2ec02
PD
49 try:
50 self.mail_con.close()
51 self.mail_con.logout()
52 except:
53 pass
54
55 def clear_inbox_acls(self, user):
56 """Resets the inbox acls for each user."""
57 try:
58 hashref = self.mail_con.getacl("INBOX")
59 except:
60 print("Could not get the acls of INBOX.")
61 print(hashref)
62 for acluser in hashref:
e42bd6a5 63 if acluser != user:
67e2ec02
PD
64 try:
65 #print(self.mail_con.setacl("INBOX", acluser, ""))
66 print("Reset acls on INBOX for user %s" % acluser)
67 except:
68 print("Could not reset acls on INBOX for user %s" % acluser)
69 return
70
e42bd6a5 71 def add_acls(self, mailbox, mailbox_list, original_user, target_user):
67e2ec02
PD
72 """Add acls to mailbox."""
73
e42bd6a5
PD
74 # change encoding to internal cyrus format and make folder absolute
75 mailbox = mailbox.replace("INBOX/", "user/" + original_user + "/")
67e2ec02
PD
76 mailbox = mailbox.replace(".", "^")
77 mailbox = mailbox.replace("/", ".")
e42bd6a5
PD
78
79 lookfor = mailbox
80 for current_folder in mailbox_list:
81 # find folder to set all acls
82 if current_folder[0] == lookfor:
83 acl_listref = current_folder[1]
84 for aclref in acl_listref:
85 print(aclref[0], target_user, original_user)
86 if aclref[0] != target_user and aclref[0] != original_user:
87 try:
88 #self.mail_con.setacl(mailbox, thisaclref[0], thisaclref[1])
89 print("Set acls %s for user %s on mailbox %s." % (aclref[1], aclref[0], mailbox))
90 except:
91 print("Could not set acls %s for user %s on mailbox %s." % (aclref[1], aclref[0], mailbox))
92 break
93
67e2ec02
PD
94 return
95
96 def delete_mailboxes(self, deleted_mailbox):
97 """Delete specified mailbox or empty inbox."""
98 for mailbox in self.mailboxes:
99 pattern = '^\"?' + deleted_mailbox
100 # if INBOX it cannot be deleted so add delimiter
101 if (deleted_mailbox == "INBOX"):
102 pattern += mailbox[1]
e42bd6a5 103 if re.compile(pattern).match(mailbox[2]):
67e2ec02 104 result, data = self.mail_con.delete(mailbox[2])
e42bd6a5 105 if result == "OK":
67e2ec02
PD
106 print("Deleted mailbox %s" % mailbox[2])
107 else:
108 print("Could not delete folder %s: %s" % (mailbox[2], data[0]))
109 return
110
111 def create_mailbox(self, mailbox):
112 """Create new mailbox to inject messages."""
e42bd6a5 113 if mailbox != "INBOX":
67e2ec02 114 result, data = self.mail_con.create(mailbox)
e42bd6a5 115 if result == "OK":
67e2ec02
PD
116 print("Creating mailbox %s" % mailbox)
117 else:
118 print("Could not create mailbox %s: %s" % (mailbox, data[0]))
119 return
120
121 def inject_message(self, message, mailbox, internal_date):
122 """Inject a message into a mailbox."""
123
124 #$imap->append_file($folder, $full_path, undef, "\\Seen", true)
125 try:
126 result, data = self.mail_con.append(mailbox, "\\Seen",
127 internal_date, message)
128 print("Appending message to mailbox %s" % mailbox)
129 except:
130 raise UserWarning("Could not append the e-mail." % message)
131 return