71 def _load(self): |
71 def _load(self): |
72 """Load 'uid', 'mid' and 'tid' from the database and set _new to |
72 """Load 'uid', 'mid' and 'tid' from the database and set _new to |
73 `False` - if the user could be found. """ |
73 `False` - if the user could be found. """ |
74 dbc = self._dbh.cursor() |
74 dbc = self._dbh.cursor() |
75 dbc.execute('SELECT uid, mid, tid FROM users WHERE gid = %s AND ' |
75 dbc.execute('SELECT uid, mid, tid FROM users WHERE gid = %s AND ' |
76 'local_part = %s', self._domain.gid, self._addr.localpart) |
76 'local_part=%s', (self._domain.gid, self._addr.localpart)) |
77 result = dbc.fetchone() |
77 result = dbc.fetchone() |
78 dbc.close() |
78 dbc.close() |
79 if result: |
79 if result: |
80 self._uid, _mid, _tid = result |
80 self._uid, _mid, _tid = result |
81 if _tid != self._transport.tid: |
81 if _tid != self._transport.tid: |
144 |
144 |
145 def _count_aliases(self): |
145 def _count_aliases(self): |
146 """Count all alias addresses where the destination address is the |
146 """Count all alias addresses where the destination address is the |
147 address of the Account.""" |
147 address of the Account.""" |
148 dbc = self._dbh.cursor() |
148 dbc = self._dbh.cursor() |
149 sql = "SELECT COUNT(destination) FROM alias WHERE destination = '%s'"\ |
149 dbc.execute('SELECT COUNT(destination) FROM alias WHERE destination ' |
150 % self._addr |
150 '= %s', (self._addr,)) |
151 dbc.execute(sql) |
|
152 a_count = dbc.fetchone()[0] |
151 a_count = dbc.fetchone()[0] |
153 dbc.close() |
152 dbc.close() |
154 return a_count |
153 return a_count |
155 |
154 |
156 def _chk_state(self): |
155 def _chk_state(self): |
257 sieve_col = 'sieve' |
256 sieve_col = 'sieve' |
258 else: |
257 else: |
259 sieve_col = 'managesieve' |
258 sieve_col = 'managesieve' |
260 self._prepare(MailLocation(self._dbh, mbfmt=cfg_dget('mailbox.format'), |
259 self._prepare(MailLocation(self._dbh, mbfmt=cfg_dget('mailbox.format'), |
261 directory=cfg_dget('mailbox.root'))) |
260 directory=cfg_dget('mailbox.root'))) |
262 sql = "INSERT INTO users (local_part, passwd, uid, gid, mid, tid,\ |
261 dbc = self._dbh.cursor() |
263 smtp, pop3, imap, %s) VALUES ('%s', '%s', %d, %d, %d, %d, %s, %s, %s, %s)" % ( |
262 dbc.execute('INSERT INTO users (local_part, passwd, uid, gid, mid, ' |
264 sieve_col, self._addr.localpart, pwhash(self._passwd, |
263 'tid, smtp, pop3, imap, %s) VALUES' % (sieve_col,) + \ |
265 user=self._addr), |
264 '(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)', |
266 self._uid, self._domain.gid, self._mail.mid, self._transport.tid, |
265 (self._addr.localpart, |
267 cfg_dget('account.smtp'), cfg_dget('account.pop3'), |
266 pwhash(self._passwd, user=self._addr), self._uid, |
268 cfg_dget('account.imap'), cfg_dget('account.sieve')) |
267 self._domain.gid, self._mail.mid, self._transport.tid, |
269 dbc = self._dbh.cursor() |
268 cfg_dget('account.smtp'), cfg_dget('account.pop3'), |
270 dbc.execute(sql) |
269 cfg_dget('account.imap'), cfg_dget('account.sieve'))) |
271 self._dbh.commit() |
270 self._dbh.commit() |
272 dbc.close() |
271 dbc.close() |
273 self._new = False |
272 self._new = False |
274 |
273 |
275 def modify(self, field, value): |
274 def modify(self, field, value): |
289 raise AErr(_(u"Unknown field: '%s'") % field, INVALID_ARGUMENT) |
288 raise AErr(_(u"Unknown field: '%s'") % field, INVALID_ARGUMENT) |
290 self._chk_state() |
289 self._chk_state() |
291 dbc = self._dbh.cursor() |
290 dbc = self._dbh.cursor() |
292 if field == 'password': |
291 if field == 'password': |
293 dbc.execute('UPDATE users SET passwd = %s WHERE uid = %s', |
292 dbc.execute('UPDATE users SET passwd = %s WHERE uid = %s', |
294 pwhash(value, user=self._addr), self._uid) |
293 (pwhash(value, user=self._addr), self._uid)) |
295 elif field == 'transport': |
294 elif field == 'transport': |
296 if value != self._transport.transport: |
295 if value != self._transport.transport: |
297 self._transport = Transport(self._dbh, transport=value) |
296 self._transport = Transport(self._dbh, transport=value) |
298 dbc.execute('UPDATE users SET tid = %s WHERE uid = %s', |
297 dbc.execute('UPDATE users SET tid = %s WHERE uid = %s', |
299 self._transport.tid, self._uid) |
298 (self._transport.tid, self._uid)) |
300 else: |
299 else: |
301 dbc.execute('UPDATE users SET name = %s WHERE uid = %s', |
300 dbc.execute('UPDATE users SET name = %s WHERE uid = %s', |
302 value, self._uid) |
301 (value, self._uid)) |
303 if dbc.rowcount > 0: |
302 if dbc.rowcount > 0: |
304 self._dbh.commit() |
303 self._dbh.commit() |
305 dbc.close() |
304 dbc.close() |
306 |
305 |
307 def get_info(self): |
306 def get_info(self): |
349 self._chk_state() |
348 self._chk_state() |
350 dbc = self._dbh.cursor() |
349 dbc = self._dbh.cursor() |
351 dbc.execute("SELECT address ||'@'|| domainname FROM alias, " |
350 dbc.execute("SELECT address ||'@'|| domainname FROM alias, " |
352 "domain_name WHERE destination = %s AND domain_name.gid = " |
351 "domain_name WHERE destination = %s AND domain_name.gid = " |
353 "alias.gid AND domain_name.is_primary ORDER BY address", |
352 "alias.gid AND domain_name.is_primary ORDER BY address", |
354 str(self._addr)) |
353 (str(self._addr),)) |
355 addresses = dbc.fetchall() |
354 addresses = dbc.fetchall() |
356 dbc.close() |
355 dbc.close() |
357 aliases = [] |
356 aliases = [] |
358 if addresses: |
357 if addresses: |
359 aliases = [alias[0] for alias in addresses] |
358 aliases = [alias[0] for alias in addresses] |
372 if not isinstance(force, bool): |
371 if not isinstance(force, bool): |
373 raise TypeError('force must be a bool') |
372 raise TypeError('force must be a bool') |
374 self._chk_state() |
373 self._chk_state() |
375 dbc = self._dbh.cursor() |
374 dbc = self._dbh.cursor() |
376 if force: |
375 if force: |
377 dbc.execute('DELETE FROM users WHERE uid = %s', self._uid) |
376 dbc.execute('DELETE FROM users WHERE uid = %s', (self._uid),) |
378 # delete also all aliases where the destination address is the same |
377 # delete also all aliases where the destination address is the same |
379 # as for this account. |
378 # as for this account. |
380 dbc.execute("DELETE FROM alias WHERE destination = %s", |
379 dbc.execute("DELETE FROM alias WHERE destination = %s", |
381 str(self._addr)) |
380 (str(self._addr),)) |
382 self._dbh.commit() |
381 self._dbh.commit() |
383 else: # check first for aliases |
382 else: # check first for aliases |
384 a_count = self._count_aliases() |
383 a_count = self._count_aliases() |
385 if a_count > 0: |
384 if a_count > 0: |
386 dbc.close() |
385 dbc.close() |
387 raise AErr(_(u"There are %(count)d aliases with the " |
386 raise AErr(_(u"There are %(count)d aliases with the " |
388 u"destination address '%(address)s'.") % |
387 u"destination address '%(address)s'.") % |
389 {'count': a_count, 'address': self._addr}, |
388 {'count': a_count, 'address': self._addr}, |
390 ALIAS_PRESENT) |
389 ALIAS_PRESENT) |
391 dbc.execute('DELETE FROM users WHERE uid = %s', self._uid) |
390 dbc.execute('DELETE FROM users WHERE uid = %s', (self._uid,)) |
392 self._dbh.commit() |
391 self._dbh.commit() |
393 dbc.close() |
392 dbc.close() |
394 self._new = True |
393 self._new = True |
395 self._uid = 0 |
394 self._uid = 0 |
396 self._addr = self._dbh = self._domain = self._passwd = None |
395 self._addr = self._dbh = self._domain = self._passwd = None |
418 raise AErr(_(u'UID must be greater than 0.'), INVALID_ARGUMENT) |
417 raise AErr(_(u'UID must be greater than 0.'), INVALID_ARGUMENT) |
419 dbc = dbh.cursor() |
418 dbc = dbh.cursor() |
420 dbc.execute("SELECT local_part||'@'|| domain_name.domainname AS address, " |
419 dbc.execute("SELECT local_part||'@'|| domain_name.domainname AS address, " |
421 "uid, users.gid FROM users LEFT JOIN domain_name ON " |
420 "uid, users.gid FROM users LEFT JOIN domain_name ON " |
422 "(domain_name.gid = users.gid AND is_primary) WHERE uid = %s", |
421 "(domain_name.gid = users.gid AND is_primary) WHERE uid = %s", |
423 uid) |
422 (uid,)) |
424 info = dbc.fetchone() |
423 info = dbc.fetchone() |
425 dbc.close() |
424 dbc.close() |
426 if not info: |
425 if not info: |
427 raise AErr(_(u"There is no account with the UID '%d'.") % uid, |
426 raise AErr(_(u"There is no account with the UID '%d'.") % uid, |
428 NO_SUCH_ACCOUNT) |
427 NO_SUCH_ACCOUNT) |