11 import os |
11 import os |
12 import re |
12 import re |
13 from random import choice |
13 from random import choice |
14 |
14 |
15 from VirtualMailManager.constants import \ |
15 from VirtualMailManager.constants import \ |
16 ACCOUNT_AND_ALIAS_PRESENT, ACCOUNT_PRESENT, ALIAS_PRESENT, \ |
16 ACCOUNT_AND_ALIAS_PRESENT, DOMAIN_ALIAS_EXISTS, DOMAIN_EXISTS, \ |
17 DOMAIN_ALIAS_EXISTS, DOMAIN_EXISTS, DOMAIN_INVALID, DOMAIN_TOO_LONG, \ |
17 DOMAIN_INVALID, DOMAIN_TOO_LONG, NO_SUCH_DOMAIN |
18 NO_SUCH_DOMAIN |
|
19 from VirtualMailManager.errors import DomainError as DomErr |
18 from VirtualMailManager.errors import DomainError as DomErr |
|
19 from VirtualMailManager.pycompat import any |
20 from VirtualMailManager.transport import Transport |
20 from VirtualMailManager.transport import Transport |
21 |
21 |
22 |
22 |
23 MAILDIR_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz' |
23 MAILDIR_CHARS = '0123456789abcdefghijklmnopqrstuvwxyz' |
24 RE_DOMAIN = re.compile(r"^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$") |
24 RE_DOMAIN = re.compile(r"^(?:[a-z0-9-]{1,63}\.){1,}[a-z]{2,6}$") |
81 dbc = self._dbh.cursor() |
81 dbc = self._dbh.cursor() |
82 dbc.execute("SELECT nextval('domain_gid')") |
82 dbc.execute("SELECT nextval('domain_gid')") |
83 self._gid = dbc.fetchone()[0] |
83 self._gid = dbc.fetchone()[0] |
84 dbc.close() |
84 dbc.close() |
85 |
85 |
86 def _has(self, what): |
86 def _check_for_addresses(self): |
87 """Checks if aliases or accounts are assigned to the domain. |
87 """Checks dependencies for deletion. Raises a DomainError if there |
88 |
88 are accounts, aliases and/or relocated users. |
89 If there are assigned accounts or aliases True will be returned, |
89 """ |
90 otherwise False will be returned. |
90 dbc = self._dbh.cursor() |
91 |
91 dbc.execute('SELECT count(gid) FROM users WHERE gid = %(gid)u ' |
92 Argument: |
92 'UNION SELECT count(gid) FROM alias WHERE gid = %(gid)u ' |
93 |
93 'UNION SELECT count(gid) FROM relocated WHERE gid = ' |
94 `what` : basestring |
94 '%(gid)u' % {'gid': self._gid}) |
95 "alias" or "users" |
95 result = dbc.fetchall() |
96 """ |
96 dbc.close() |
97 assert what in ('alias', 'users') |
97 result = [count[0] for count in result] |
98 dbc = self._dbh.cursor() |
98 if any(result): |
99 if what == 'users': |
99 keys = ('account_count', 'alias_count', 'relocated_count') |
100 dbc.execute("SELECT count(gid) FROM users WHERE gid=%s", self._gid) |
100 raise DomErr(_(u'There are %(account_count)u accounts, ' |
101 else: |
101 u'%(alias_count)u aliases and %(relocated_count)u ' |
102 dbc.execute("SELECT count(gid) FROM alias WHERE gid=%s", self._gid) |
102 u'relocated users.') % dict(zip(keys, result)), |
103 count = dbc.fetchone() |
|
104 dbc.close() |
|
105 return count[0] > 0 |
|
106 |
|
107 def _chk_delete(self, deluser, delalias): |
|
108 """Checks dependencies for deletion. |
|
109 |
|
110 Arguments: |
|
111 deluser -- ignore available accounts (bool) |
|
112 delalias -- ignore available aliases (bool) |
|
113 """ |
|
114 if not deluser: |
|
115 hasuser = self._has('users') |
|
116 else: |
|
117 hasuser = False |
|
118 if not delalias: |
|
119 hasalias = self._has('alias') |
|
120 else: |
|
121 hasalias = False |
|
122 if hasuser and hasalias: |
|
123 raise DomErr(_(u'There are accounts and aliases.'), |
|
124 ACCOUNT_AND_ALIAS_PRESENT) |
103 ACCOUNT_AND_ALIAS_PRESENT) |
125 elif hasuser: |
|
126 raise DomErr(_(u'There are accounts.'), ACCOUNT_PRESENT) |
|
127 elif hasalias: |
|
128 raise DomErr(_(u'There are aliases.'), ALIAS_PRESENT) |
|
129 |
104 |
130 def _chk_state(self): |
105 def _chk_state(self): |
131 """Throws a DomainError if the Domain is new - not saved in the |
106 """Throws a DomainError if the Domain is new - not saved in the |
132 database.""" |
107 database.""" |
133 if self._new: |
108 if self._new: |
191 self._gid, True) |
166 self._gid, True) |
192 self._dbh.commit() |
167 self._dbh.commit() |
193 dbc.close() |
168 dbc.close() |
194 self._new = False |
169 self._new = False |
195 |
170 |
196 def delete(self, deluser=False, delalias=False): |
171 def delete(self, force=False): |
197 """Deletes the domain. |
172 """Deletes the domain. |
198 |
173 |
199 Arguments: |
174 Arguments: |
200 |
175 |
201 `deluser` : bool |
176 `force` : bool |
202 force deletion of all available accounts, default `False` |
177 force the deletion of all available accounts, aliases and |
203 `delalias` : bool |
178 relocated users. When *force* is `False` and there are accounts, |
204 force deletion of all available aliases, default `False` |
179 aliases and/or relocated users a DomainError will be raised. |
205 """ |
180 Default `False` |
206 self._chk_state() |
181 """ |
207 self._chk_delete(deluser, delalias) |
182 if not isinstance(force, bool): |
|
183 raise TypeError('force must be a bool') |
|
184 self._chk_state() |
|
185 if not force: |
|
186 self._check_for_addresses() |
208 dbc = self._dbh.cursor() |
187 dbc = self._dbh.cursor() |
209 for tbl in ('alias', 'users', 'relocated', 'domain_name', |
188 for tbl in ('alias', 'users', 'relocated', 'domain_name', |
210 'domain_data'): |
189 'domain_data'): |
211 dbc.execute("DELETE FROM %s WHERE gid = %d" % (tbl, self._gid)) |
190 dbc.execute("DELETE FROM %s WHERE gid = %u" % (tbl, self._gid)) |
212 self._dbh.commit() |
191 self._dbh.commit() |
213 dbc.close() |
192 dbc.close() |
214 self._gid = 0 |
193 self._gid = 0 |
215 self._directory = self._transport = None |
194 self._directory = self._transport = None |
216 self._new = True |
195 self._new = True |