30 |
30 |
31 |
31 |
32 class Account(object): |
32 class Account(object): |
33 """Class to manage e-mail accounts.""" |
33 """Class to manage e-mail accounts.""" |
34 __slots__ = ('_addr', '_dbh', '_domain', '_mail', '_new', '_passwd', |
34 __slots__ = ('_addr', '_dbh', '_domain', '_mail', '_new', '_passwd', |
35 '_qlimit', '_services', '_transport', '_uid') |
35 '_qlimit', '_services', '_transport', '_note', '_uid') |
36 |
36 |
37 def __init__(self, dbh, address): |
37 def __init__(self, dbh, address): |
38 """Creates a new Account instance. |
38 """Creates a new Account instance. |
39 |
39 |
40 When an account with the given *address* could be found in the |
40 When an account with the given *address* could be found in the |
61 self._uid = 0 |
61 self._uid = 0 |
62 self._mail = None |
62 self._mail = None |
63 self._qlimit = None |
63 self._qlimit = None |
64 self._services = None |
64 self._services = None |
65 self._transport = None |
65 self._transport = None |
|
66 self._note = None |
66 self._passwd = None |
67 self._passwd = None |
67 self._new = True |
68 self._new = True |
68 self._load() |
69 self._load() |
69 |
70 |
70 def __nonzero__(self): |
71 def __nonzero__(self): |
71 """Returns `True` if the Account is known, `False` if it's new.""" |
72 """Returns `True` if the Account is known, `False` if it's new.""" |
72 return not self._new |
73 return not self._new |
73 |
74 |
74 def _load(self): |
75 def _load(self): |
75 """Load 'uid', 'mid', 'qid', 'ssid' and 'tid' from the database and |
76 """Load 'uid', 'mid', 'qid', 'ssid', 'tid' and 'note' from the |
76 set _new to `False` - if the user could be found. """ |
77 database and set _new to `False` - if the user could be found. """ |
77 dbc = self._dbh.cursor() |
78 dbc = self._dbh.cursor() |
78 dbc.execute('SELECT uid, mid, qid, ssid, tid FROM users WHERE gid = ' |
79 dbc.execute('SELECT uid, mid, qid, ssid, tid, note FROM users ' |
79 '%s AND local_part = %s', (self._domain.gid, |
80 'WHERE gid = %s AND local_part = %s', |
80 self._addr.localpart)) |
81 (self._domain.gid, self._addr.localpart)) |
81 result = dbc.fetchone() |
82 result = dbc.fetchone() |
82 dbc.close() |
83 dbc.close() |
83 if result: |
84 if result: |
84 self._uid, _mid, _qid, _ssid, _tid = result |
85 self._uid, _mid, _qid, _ssid, _tid, _note = result |
85 |
86 |
86 def load_helper(ctor, own, field, dbresult): |
87 def load_helper(ctor, own, field, dbresult): |
87 cur = None if own is None else getattr(own, field) |
88 cur = None if own is None else getattr(own, field) |
88 if cur != dbresult: |
89 if cur != dbresult: |
89 kwargs = { field : dbresult } |
90 kwargs = { field : dbresult } |
94 self._services = load_helper(ServiceSet, self._services, 'ssid', |
95 self._services = load_helper(ServiceSet, self._services, 'ssid', |
95 _ssid) |
96 _ssid) |
96 self._transport = load_helper(Transport, self._transport, 'tid', |
97 self._transport = load_helper(Transport, self._transport, 'tid', |
97 _tid) |
98 _tid) |
98 self._mail = MailLocation(self._dbh, mid=_mid) |
99 self._mail = MailLocation(self._dbh, mid=_mid) |
|
100 self._note = _note |
99 self._new = False |
101 self._new = False |
100 |
102 |
101 def _set_uid(self): |
103 def _set_uid(self): |
102 """Set the unique ID for the new Account.""" |
104 """Set the unique ID for the new Account.""" |
103 assert self._uid == 0 |
105 assert self._uid == 0 |
213 ACCOUNT_EXISTS) |
220 ACCOUNT_EXISTS) |
214 if not isinstance(password, basestring) or not password: |
221 if not isinstance(password, basestring) or not password: |
215 raise AErr(_(u"Could not accept password: '%s'") % password, |
222 raise AErr(_(u"Could not accept password: '%s'") % password, |
216 ACCOUNT_MISSING_PASSWORD) |
223 ACCOUNT_MISSING_PASSWORD) |
217 self._passwd = password |
224 self._passwd = password |
|
225 |
|
226 def set_note(self, note): |
|
227 """Set the account's (optional) note. |
|
228 |
|
229 Argument: |
|
230 |
|
231 `note` : basestring or None |
|
232 The note, or None to remove |
|
233 """ |
|
234 assert note is None or isinstance(note, basestring) |
|
235 self._note = note |
218 |
236 |
219 def save(self): |
237 def save(self): |
220 """Save the new Account in the database.""" |
238 """Save the new Account in the database.""" |
221 if not self._new: |
239 if not self._new: |
222 raise AErr(_(u"The account '%s' already exists.") % self._addr, |
240 raise AErr(_(u"The account '%s' already exists.") % self._addr, |
226 ACCOUNT_MISSING_PASSWORD) |
244 ACCOUNT_MISSING_PASSWORD) |
227 self._prepare(MailLocation(self._dbh, mbfmt=cfg_dget('mailbox.format'), |
245 self._prepare(MailLocation(self._dbh, mbfmt=cfg_dget('mailbox.format'), |
228 directory=cfg_dget('mailbox.root'))) |
246 directory=cfg_dget('mailbox.root'))) |
229 dbc = self._dbh.cursor() |
247 dbc = self._dbh.cursor() |
230 dbc.execute('INSERT INTO users (local_part, passwd, uid, gid, mid, ' |
248 dbc.execute('INSERT INTO users (local_part, passwd, uid, gid, mid, ' |
231 'qid, ssid, tid) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)', |
249 'qid, ssid, tid, note) ' |
|
250 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)', |
232 (self._addr.localpart, |
251 (self._addr.localpart, |
233 pwhash(self._passwd, user=self._addr), self._uid, |
252 pwhash(self._passwd, user=self._addr), self._uid, |
234 self._domain.gid, self._mail.mid, |
253 self._domain.gid, self._mail.mid, |
235 self._qlimit.qid if self._qlimit else None, |
254 self._qlimit.qid if self._qlimit else None, |
236 self._services.ssid if self._services else None, |
255 self._services.ssid if self._services else None, |
237 self._transport.tid if self._transport else None)) |
256 self._transport.tid if self._transport else None, |
|
257 self._note)) |
238 self._dbh.commit() |
258 self._dbh.commit() |
239 dbc.close() |
259 dbc.close() |
240 self._new = False |
260 self._new = False |
241 |
261 |
242 def modify(self, field, value): |
262 def modify(self, field, value): |
243 """Update the Account's *field* to the new *value*. |
263 """Update the Account's *field* to the new *value*. |
244 |
264 |
245 Possible values for *field* are: 'name', 'password'. |
265 Possible values for *field* are: 'name', 'password', 'note'. |
246 |
266 |
247 Arguments: |
267 Arguments: |
248 |
268 |
249 `field` : basestring |
269 `field` : basestring |
250 The attribute name: 'name' or 'password' |
270 The attribute name: 'name', 'password' or 'note' |
251 `value` : basestring |
271 `value` : basestring |
252 The new value of the attribute. |
272 The new value of the attribute. |
253 """ |
273 """ |
254 if field not in ('name', 'password'): |
274 if field not in ('name', 'password', 'note'): |
255 raise AErr(_(u"Unknown field: '%s'") % field, INVALID_ARGUMENT) |
275 raise AErr(_(u"Unknown field: '%s'") % field, INVALID_ARGUMENT) |
256 self._chk_state() |
276 self._chk_state() |
257 dbc = self._dbh.cursor() |
277 dbc = self._dbh.cursor() |
258 if field == 'password': |
278 if field == 'password': |
259 dbc.execute('UPDATE users SET passwd = %s WHERE uid = %s', |
279 dbc.execute('UPDATE users SET passwd = %s WHERE uid = %s', |
260 (pwhash(value, user=self._addr), self._uid)) |
280 (pwhash(value, user=self._addr), self._uid)) |
261 else: |
281 else: |
262 dbc.execute('UPDATE users SET name = %s WHERE uid = %s', |
282 dbc.execute('UPDATE users SET %s = %%s WHERE uid = %%s' % field, |
263 (value, self._uid)) |
283 (value, self._uid)) |
264 if dbc.rowcount > 0: |
284 if dbc.rowcount > 0: |
265 self._dbh.commit() |
285 self._dbh.commit() |
266 dbc.close() |
286 dbc.close() |
267 |
287 |
375 else: |
395 else: |
376 info['ql_bytes'] = self._domain.quotalimit.bytes |
396 info['ql_bytes'] = self._domain.quotalimit.bytes |
377 info['ql_messages'] = self._domain.quotalimit.messages |
397 info['ql_messages'] = self._domain.quotalimit.messages |
378 info['ql_domaindefault'] = True |
398 info['ql_domaindefault'] = True |
379 info['transport'] = self._get_info_transport() |
399 info['transport'] = self._get_info_transport() |
|
400 info['note'] = self._note |
380 info['uid'] = self._uid |
401 info['uid'] = self._uid |
381 return info |
402 return info |
382 # nearly impossibleā½ |
403 # nearly impossibleā½ |
383 raise AErr(_(u"Could not fetch information for account: '%s'") % |
404 raise AErr(_(u"Could not fetch information for account: '%s'") % |
384 self._addr, NO_SUCH_ACCOUNT) |
405 self._addr, NO_SUCH_ACCOUNT) |