15 |
14 |
16 from Exceptions import VMMAccountException as AccE |
15 from Exceptions import VMMAccountException as AccE |
17 from Domain import Domain |
16 from Domain import Domain |
18 from Transport import Transport |
17 from Transport import Transport |
19 from MailLocation import MailLocation |
18 from MailLocation import MailLocation |
|
19 from EmailAddress import EmailAddress |
20 import VirtualMailManager as VMM |
20 import VirtualMailManager as VMM |
21 import constants.ERROR as ERR |
21 import constants.ERROR as ERR |
22 |
22 |
23 class Account: |
23 class Account: |
24 """Class to manage e-mail accounts.""" |
24 """Class to manage e-mail accounts.""" |
25 def __init__(self, dbh, address, password=None): |
25 def __init__(self, dbh, address, password=None): |
26 self._dbh = dbh |
26 self._dbh = dbh |
27 self._base = None |
27 self._base = None |
28 self._addr = VMM.VirtualMailManager.chkEmailAddress(address) |
28 if isinstance(address, EmailAddress): |
29 self._localpart = None |
29 self._addr = address |
30 self._name = None |
30 else: |
|
31 raise TypeError("Argument 'address' is not an EmailAddress") |
31 self._uid = 0 |
32 self._uid = 0 |
32 self._gid = 0 |
33 self._gid = 0 |
33 self._mid = 0 |
34 self._mid = 0 |
34 self._tid = 0 |
35 self._tid = 0 |
35 self._passwd = password |
36 self._passwd = password |
36 self._setAddr() |
37 self._setAddr() |
37 self._exists() |
38 self._exists() |
38 if self._isAlias(): |
39 if VMM.VirtualMailManager.aliasExists(self._dbh, self._addr): |
39 raise AccE(_(u"There is already an alias with the address »%s«.") %\ |
40 raise AccE(_(u"There is already an alias with the address »%s«.") %\ |
40 address, ERR.ALIAS_EXISTS) |
41 self._addr, ERR.ALIAS_EXISTS) |
|
42 if VMM.VirtualMailManager.relocatedExists(self._dbh, self._addr): |
|
43 raise AccE( |
|
44 _(u"There is already an relocated user with the address »%s«.") %\ |
|
45 self._addr, ERR.RELOCATED_EXISTS) |
41 |
46 |
42 def _exists(self): |
47 def _exists(self): |
43 dbc = self._dbh.cursor() |
48 dbc = self._dbh.cursor() |
44 dbc.execute("SELECT uid, mid, tid FROM users \ |
49 dbc.execute("SELECT uid, mid, tid FROM users \ |
45 WHERE gid=%s AND local_part=%s", |
50 WHERE gid=%s AND local_part=%s", |
46 self._gid, self._localpart) |
51 self._gid, self._addr._localpart) |
47 result = dbc.fetchone() |
52 result = dbc.fetchone() |
48 dbc.close() |
53 dbc.close() |
49 if result is not None: |
54 if result is not None: |
50 self._uid, self._mid, self._tid = result |
55 self._uid, self._mid, self._tid = result |
51 return True |
56 return True |
52 else: |
57 else: |
53 return False |
58 return False |
54 |
59 |
55 def _isAlias(self): |
|
56 dbc = self._dbh.cursor() |
|
57 dbc.execute("SELECT gid FROM alias WHERE gid=%s AND address=%s", |
|
58 self._gid, self._localpart) |
|
59 gid = dbc.fetchone() |
|
60 dbc.close() |
|
61 if gid is not None: |
|
62 return True |
|
63 else: |
|
64 return False |
|
65 |
|
66 def _setAddr(self): |
60 def _setAddr(self): |
67 self._localpart, d = self._addr.split('@') |
61 dom = Domain(self._dbh, self._addr._domainname) |
68 dom = Domain(self._dbh, d) |
|
69 self._gid = dom.getID() |
62 self._gid = dom.getID() |
70 if self._gid == 0: |
63 if self._gid == 0: |
71 raise AccE(_(u"The domain »%s« doesn't exist yet.") % d, |
64 raise AccE(_(u"The domain »%s« doesn't exist yet.") %\ |
72 ERR.NO_SUCH_DOMAIN) |
65 self._addr._domainname, ERR.NO_SUCH_DOMAIN) |
73 self._base = dom.getDir() |
66 self._base = dom.getDir() |
74 self._tid = dom.getTransportID() |
67 self._tid = dom.getTransportID() |
75 |
68 |
76 def _setID(self): |
69 def _setID(self): |
77 dbc = self._dbh.cursor() |
70 dbc = self._dbh.cursor() |
94 ERR.NO_SUCH_ACCOUNT) |
87 ERR.NO_SUCH_ACCOUNT) |
95 dbc = self._dbh.cursor() |
88 dbc = self._dbh.cursor() |
96 if service in ['smtp', 'pop3', 'imap', 'managesieve']: |
89 if service in ['smtp', 'pop3', 'imap', 'managesieve']: |
97 dbc.execute( |
90 dbc.execute( |
98 "UPDATE users SET %s=%s WHERE local_part='%s' AND gid=%s" |
91 "UPDATE users SET %s=%s WHERE local_part='%s' AND gid=%s" |
99 % (service, state, self._localpart, self._gid)) |
92 % (service, state, self._addr._localpart, self._gid)) |
100 elif state: |
93 elif state: |
101 dbc.execute("UPDATE users SET smtp = TRUE, pop3 = TRUE,\ |
94 dbc.execute("UPDATE users SET smtp = TRUE, pop3 = TRUE,\ |
102 imap = TRUE, managesieve = TRUE WHERE local_part = %s AND gid = %s", |
95 imap = TRUE, managesieve = TRUE WHERE local_part = %s AND gid = %s", |
103 self._localpart, self._gid) |
96 self._addr._localpart, self._gid) |
104 else: |
97 else: |
105 dbc.execute("UPDATE users SET smtp = FALSE, pop3 = FALSE,\ |
98 dbc.execute("UPDATE users SET smtp = FALSE, pop3 = FALSE,\ |
106 imap = FALSE, managesieve = FALSE WHERE local_part = %s AND gid = %s", |
99 imap = FALSE, managesieve = FALSE WHERE local_part = %s AND gid = %s", |
107 self._localpart, self._gid) |
100 self._addr._localpart, self._gid) |
108 if dbc.rowcount > 0: |
101 if dbc.rowcount > 0: |
109 self._dbh.commit() |
102 self._dbh.commit() |
110 dbc.close() |
103 dbc.close() |
111 |
104 |
112 def __aliaseCount(self): |
105 def __aliaseCount(self): |
144 self._prepare(maillocation) |
137 self._prepare(maillocation) |
145 dbc = self._dbh.cursor() |
138 dbc = self._dbh.cursor() |
146 dbc.execute("""INSERT INTO users (local_part, passwd, uid, gid,\ |
139 dbc.execute("""INSERT INTO users (local_part, passwd, uid, gid,\ |
147 mid, tid, smtp, pop3, imap, managesieve)\ |
140 mid, tid, smtp, pop3, imap, managesieve)\ |
148 VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", |
141 VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""", |
149 self._localpart, self._passwd, self._uid, self._gid, self._mid, |
142 self._addr._localpart, self._passwd, self._uid, self._gid, |
150 self._tid, smtp, pop3, imap, managesieve) |
143 self._mid, self._tid, smtp, pop3, imap, managesieve) |
151 self._dbh.commit() |
144 self._dbh.commit() |
152 dbc.close() |
145 dbc.close() |
153 else: |
146 else: |
154 raise AccE(_(u'The account »%s« already exists.') % self._addr, |
147 raise AccE(_(u'The account »%s« already exists.') % self._addr, |
155 ERR.ACCOUNT_EXISTS) |
148 ERR.ACCOUNT_EXISTS) |
161 if what not in ['name', 'password', 'transport']: |
154 if what not in ['name', 'password', 'transport']: |
162 return False |
155 return False |
163 dbc = self._dbh.cursor() |
156 dbc = self._dbh.cursor() |
164 if what == 'password': |
157 if what == 'password': |
165 dbc.execute("UPDATE users SET passwd=%s WHERE local_part=%s AND\ |
158 dbc.execute("UPDATE users SET passwd=%s WHERE local_part=%s AND\ |
166 gid=%s", value, self._localpart, self._gid) |
159 gid=%s", value, self._addr._localpart, self._gid) |
167 elif what == 'transport': |
160 elif what == 'transport': |
168 self._tid = Transport(self._dbh, transport=value).getID() |
161 self._tid = Transport(self._dbh, transport=value).getID() |
169 dbc.execute("UPDATE users SET tid=%s WHERE local_part=%s AND\ |
162 dbc.execute("UPDATE users SET tid=%s WHERE local_part=%s AND\ |
170 gid=%s", self._tid, self._localpart, self._gid) |
163 gid=%s", self._tid, self._addr._localpart, self._gid) |
171 else: |
164 else: |
172 dbc.execute("UPDATE users SET name=%s WHERE local_part=%s AND\ |
165 dbc.execute("UPDATE users SET name=%s WHERE local_part=%s AND\ |
173 gid=%s", value, self._localpart, self._gid) |
166 gid=%s", value, self._addr._localpart, self._gid) |
174 if dbc.rowcount > 0: |
167 if dbc.rowcount > 0: |
175 self._dbh.commit() |
168 self._dbh.commit() |
176 dbc.close() |
169 dbc.close() |
177 |
170 |
178 def getInfo(self): |
171 def getInfo(self): |
179 dbc = self._dbh.cursor() |
172 dbc = self._dbh.cursor() |
180 dbc.execute("SELECT name, uid, gid, mid, tid, smtp, pop3, imap, \ |
173 dbc.execute("SELECT name, uid, gid, mid, tid, smtp, pop3, imap, \ |
181 managesieve FROM users WHERE local_part=%s AND gid=%s", |
174 managesieve FROM users WHERE local_part=%s AND gid=%s", |
182 self._localpart, self._gid) |
175 self._addr._localpart, self._gid) |
183 info = dbc.fetchone() |
176 info = dbc.fetchone() |
184 dbc.close() |
177 dbc.close() |
185 if info is None: |
178 if info is None: |
186 raise AccE(_(u"The account »%s« doesn't exists.") % self._addr, |
179 raise AccE(_(u"The account »%s« doesn't exists.") % self._addr, |
187 ERR.NO_SUCH_ACCOUNT) |
180 ERR.NO_SUCH_ACCOUNT) |
207 raise AccE(_(u"The account »%s« doesn't exists.") % self._addr, |
200 raise AccE(_(u"The account »%s« doesn't exists.") % self._addr, |
208 ERR.NO_SUCH_ACCOUNT) |
201 ERR.NO_SUCH_ACCOUNT) |
209 dbc = self._dbh.cursor() |
202 dbc = self._dbh.cursor() |
210 if delalias == 'delalias': |
203 if delalias == 'delalias': |
211 dbc.execute("DELETE FROM users WHERE gid=%s AND local_part=%s", |
204 dbc.execute("DELETE FROM users WHERE gid=%s AND local_part=%s", |
212 self._gid, self._localpart) |
205 self._gid, self._addr._localpart) |
213 u_rc = dbc.rowcount |
206 u_rc = dbc.rowcount |
214 # delete also all aliases where the destination address is the same |
207 # delete also all aliases where the destination address is the same |
215 # as for this account. |
208 # as for this account. |
216 dbc.execute("DELETE FROM alias WHERE destination = %s", self._addr) |
209 dbc.execute("DELETE FROM alias WHERE destination = %s", self._addr) |
217 if u_rc > 0 or dbc.rowcount > 0: |
210 if u_rc > 0 or dbc.rowcount > 0: |
218 self._dbh.commit() |
211 self._dbh.commit() |
219 else: # check first for aliases |
212 else: # check first for aliases |
220 a_count = self.__aliaseCount() |
213 a_count = self.__aliaseCount() |
221 if a_count == 0: |
214 if a_count == 0: |
222 dbc.execute("DELETE FROM users WHERE gid=%s AND local_part=%s", |
215 dbc.execute("DELETE FROM users WHERE gid=%s AND local_part=%s", |
223 self._gid, self._localpart) |
216 self._gid, self._addr._localpart) |
224 if dbc.rowcount > 0: |
217 if dbc.rowcount > 0: |
225 self._dbh.commit() |
218 self._dbh.commit() |
226 else: |
219 else: |
227 dbc.close() |
220 dbc.close() |
228 raise AccE( |
221 raise AccE( |