79 self._addr.localpart)) |
79 self._addr.localpart)) |
80 result = dbc.fetchone() |
80 result = dbc.fetchone() |
81 dbc.close() |
81 dbc.close() |
82 if result: |
82 if result: |
83 self._uid, _mid, _qid, _ssid, _tid = result |
83 self._uid, _mid, _qid, _ssid, _tid = result |
84 if _qid != self._qlimit.qid: |
84 |
85 self._qlimit = QuotaLimit(self._dbh, qid=_qid) |
85 def load_helper(ctor, own, field, dbresult): |
86 if _ssid != self._services.ssid: |
86 cur = None if own is None else getattr(own, field) |
87 self._services = ServiceSet(self._dbh, ssid=_ssid) |
87 if cur != dbresult: |
88 if _tid != self._transport.tid: |
88 kwargs = { field : dbresult } |
89 self._transport = Transport(self._dbh, tid=_tid) |
89 return None if dbresult is None \ |
|
90 else ctor(self._dbh, **kwargs) |
|
91 |
|
92 self._qlimit = load_helper(QuotaLimit, self._qlimit, 'qid', _qid) |
|
93 self._services = load_helper(ServiceSet, self._services, 'ssid', |
|
94 _ssid) |
|
95 self._transport = load_helper(Transport, self._transport, 'tid', |
|
96 _tid) |
90 self._mail = MailLocation(self._dbh, mid=_mid) |
97 self._mail = MailLocation(self._dbh, mid=_mid) |
91 self._new = False |
98 self._new = False |
92 |
99 |
93 def _set_uid(self): |
100 def _set_uid(self): |
94 """Set the unique ID for the new Account.""" |
101 """Set the unique ID for the new Account.""" |
221 dbc = self._dbh.cursor() |
228 dbc = self._dbh.cursor() |
222 dbc.execute('INSERT INTO users (local_part, passwd, uid, gid, mid, ' |
229 dbc.execute('INSERT INTO users (local_part, passwd, uid, gid, mid, ' |
223 'qid, ssid, tid) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)', |
230 'qid, ssid, tid) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)', |
224 (self._addr.localpart, |
231 (self._addr.localpart, |
225 pwhash(self._passwd, user=self._addr), self._uid, |
232 pwhash(self._passwd, user=self._addr), self._uid, |
226 self._domain.gid, self._mail.mid, self._qlimit.qid, |
233 self._domain.gid, self._mail.mid, |
227 self._services.ssid, self._transport.tid)) |
234 self._qlimit.qid if self._qlimit else None, |
|
235 self._services.ssid if self._services else None, |
|
236 self._transport.tid if self._transport else None)) |
228 self._dbh.commit() |
237 self._dbh.commit() |
229 dbc.close() |
238 dbc.close() |
230 self._new = False |
239 self._new = False |
231 |
240 |
232 def modify(self, field, value): |
241 def modify(self, field, value): |
265 """ |
274 """ |
266 if cfg_dget('misc.dovecot_version') < 0x10102f00: |
275 if cfg_dget('misc.dovecot_version') < 0x10102f00: |
267 raise VMMError(_(u'PostgreSQL-based dictionary quota requires ' |
276 raise VMMError(_(u'PostgreSQL-based dictionary quota requires ' |
268 u'Dovecot >= v1.1.2.'), VMM_ERROR) |
277 u'Dovecot >= v1.1.2.'), VMM_ERROR) |
269 self._chk_state() |
278 self._chk_state() |
270 assert isinstance(quotalimit, QuotaLimit) |
|
271 if quotalimit == self._qlimit: |
279 if quotalimit == self._qlimit: |
272 return |
280 return |
273 self._update_tables('qid', quotalimit.qid) |
|
274 self._qlimit = quotalimit |
281 self._qlimit = quotalimit |
|
282 if quotalimit is not None: |
|
283 assert isinstance(quotalimit, QuotaLimit) |
|
284 quotalimit = quotalimit.qid |
|
285 self._update_tables('qid', quotalimit) |
275 |
286 |
276 def update_serviceset(self, serviceset): |
287 def update_serviceset(self, serviceset): |
277 """Assign a different set of services to the Account. |
288 """Assign a different set of services to the Account. |
278 |
289 |
279 Argument: |
290 Argument: |
280 |
291 |
281 `serviceset` : VirtualMailManager.serviceset.ServiceSet |
292 `serviceset` : VirtualMailManager.serviceset.ServiceSet |
282 the new service set. |
293 the new service set. |
283 """ |
294 """ |
284 self._chk_state() |
295 self._chk_state() |
285 assert isinstance(serviceset, ServiceSet) |
|
286 if serviceset == self._services: |
296 if serviceset == self._services: |
287 return |
297 return |
288 self._update_tables('ssid', serviceset.ssid) |
|
289 self._services = serviceset |
298 self._services = serviceset |
|
299 if serviceset is not None: |
|
300 assert isinstance(serviceset, ServiceSet) |
|
301 serviceset = serviceset.ssid |
|
302 self._update_tables('ssid', serviceset) |
290 |
303 |
291 def update_transport(self, transport): |
304 def update_transport(self, transport): |
292 """Sets a new transport for the Account. |
305 """Sets a new transport for the Account. |
293 |
306 |
294 Arguments: |
307 Arguments: |
295 |
308 |
296 `transport` : VirtualMailManager.transport.Transport |
309 `transport` : VirtualMailManager.transport.Transport |
297 the new transport |
310 the new transport |
298 """ |
311 """ |
299 self._chk_state() |
312 self._chk_state() |
300 assert isinstance(transport, Transport) |
|
301 if transport == self._transport: |
313 if transport == self._transport: |
302 return |
314 return |
303 if transport.transport.lower() in ('virtual', 'virtual:') and \ |
|
304 not self._mail.postfix: |
|
305 raise AErr(_(u"Invalid transport '%(transport)s' for mailbox " |
|
306 u"format '%(mbfmt)s'.") % |
|
307 {'transport': transport, 'mbfmt': self._mail.mbformat}, |
|
308 INVALID_MAIL_LOCATION) |
|
309 self._update_tables('tid', transport.tid) |
|
310 self._transport = transport |
315 self._transport = transport |
|
316 if transport is not None: |
|
317 assert isinstance(transport, Transport) |
|
318 if transport.transport.lower() in ('virtual', 'virtual:') and \ |
|
319 not self._mail.postfix: |
|
320 raise AErr(_(u"Invalid transport '%(transport)s' for mailbox " |
|
321 u"format '%(mbfmt)s'.") % |
|
322 {'transport': transport, 'mbfmt': self._mail.mbformat}, |
|
323 INVALID_MAIL_LOCATION) |
|
324 transport = transport.tid |
|
325 self._update_tables('tid', transport) |
|
326 |
|
327 def _get_info_transport(self): |
|
328 if self._transport: |
|
329 return self._transport.transport |
|
330 return format_domain_default(self._domain.transport.transport) |
|
331 |
|
332 def _get_info_serviceset(self): |
|
333 if self._services: |
|
334 services = self._services.services |
|
335 fmt = lambda s: s |
|
336 else: |
|
337 services = self._domain.serviceset.services |
|
338 fmt = format_domain_default |
|
339 |
|
340 ret = {} |
|
341 for service, state in services.iteritems(): |
|
342 # TP: A service (e.g. pop3 or imap) may be enabled/usable or |
|
343 # disabled/unusable for a user. |
|
344 ret[service] = fmt((_('disabled'), _('enabled'))[state]) |
|
345 return ret |
311 |
346 |
312 def get_info(self): |
347 def get_info(self): |
313 """Returns a dict with some information about the Account. |
348 """Returns a dict with some information about the Account. |
314 |
349 |
315 The keys of the dict are: 'address', 'gid', 'home', 'imap' |
350 The keys of the dict are: 'address', 'gid', 'home', 'imap' |
324 'users.uid = %s', (self._uid,)) |
359 'users.uid = %s', (self._uid,)) |
325 info = dbc.fetchone() |
360 info = dbc.fetchone() |
326 dbc.close() |
361 dbc.close() |
327 if info: |
362 if info: |
328 info = dict(zip(('name', 'uq_bytes', 'uq_messages'), info)) |
363 info = dict(zip(('name', 'uq_bytes', 'uq_messages'), info)) |
329 for service, state in self._services.services.iteritems(): |
364 info.update(self._get_info_serviceset()) |
330 # TP: A service (e.g. pop3 or imap) may be enabled/usable or |
|
331 # disabled/unusable for a user. |
|
332 info[service] = (_('disabled'), _('enabled'))[state] |
|
333 info['address'] = self._addr |
365 info['address'] = self._addr |
334 info['gid'] = self._domain.gid |
366 info['gid'] = self._domain.gid |
335 info['home'] = '%s/%s' % (self._domain.directory, self._uid) |
367 info['home'] = '%s/%s' % (self._domain.directory, self._uid) |
336 info['mail_location'] = self._mail.mail_location |
368 info['mail_location'] = self._mail.mail_location |
337 info['ql_bytes'] = self._qlimit.bytes |
369 info['ql_bytes'] = self._qlimit.bytes |