|
1 #!/usr/bin/env python |
|
2 # -*- coding: UTF-8 -*- |
|
3 # opyright 2007-2008 VEB IT |
|
4 # See COPYING for distribution information. |
|
5 # $Id$ |
|
6 |
|
7 """Virtual Mail Manager's Account class to manage email accounts.""" |
|
8 |
|
9 __author__ = 'Pascal Volk <p.volk@veb-it.de>' |
|
10 __version__ = 'rev '+'$Rev$'.split()[1] |
|
11 __date__ = '$Date$'.split()[1] |
|
12 |
|
13 from Exceptions import VMMAccountException |
|
14 from Domain import Domain |
|
15 import constants.ERROR as ERR |
|
16 |
|
17 class Account: |
|
18 """Class to manage email accounts.""" |
|
19 def __init__(self, dbh, basedir, address, password=None): |
|
20 self._dbh = dbh |
|
21 self._base = basedir |
|
22 self._base = None |
|
23 self._addr = address |
|
24 self._localpart = None |
|
25 self._name = None |
|
26 self._uid = 0 |
|
27 self._gid = 0 |
|
28 self._passwd = password |
|
29 self._home = None |
|
30 self._setAddr(address) |
|
31 self._exists() |
|
32 if self._isAlias(): |
|
33 raise VMMAccountException( |
|
34 ('There is already an alias with address «%s»' % address, |
|
35 ERR.ALIAS_EXISTS)) |
|
36 |
|
37 def _exists(self): |
|
38 dbc = self._dbh.cursor() |
|
39 dbc.execute("SELECT uid FROM users WHERE gid=%s AND local_part=%s", |
|
40 self._gid, self._localpart) |
|
41 uid = dbc.fetchone() |
|
42 dbc.close() |
|
43 if uid is not None: |
|
44 self._uid = uid[0] |
|
45 return True |
|
46 else: |
|
47 return False |
|
48 |
|
49 def _isAlias(self): |
|
50 dbc = self._dbh.cursor() |
|
51 dbc.execute("SELECT id FROM alias WHERE gid=%s AND address=%s", |
|
52 self._gid, self._localpart) |
|
53 aid = dbc.fetchone() |
|
54 dbc.close() |
|
55 if aid is not None: |
|
56 return True |
|
57 else: |
|
58 return False |
|
59 |
|
60 def _setAddr(self, address): |
|
61 self._localpart, d = address.split('@') |
|
62 dom = Domain(self._dbh, d, self._base) |
|
63 self._gid = dom.getID() |
|
64 self._base = dom.getDir() |
|
65 if self._gid == 0: |
|
66 raise VMMAccountException(("Domain %s doesn't exist." % d, |
|
67 ERR.NO_SUCH_DOMAIN)) |
|
68 |
|
69 def _setID(self): |
|
70 dbc = self._dbh.cursor() |
|
71 dbc.execute("SELECT nextval('users_uid')") |
|
72 self._uid = dbc.fetchone()[0] |
|
73 dbc.close() |
|
74 |
|
75 def _prepare(self): |
|
76 self._setID() |
|
77 self._home = "%i" % self._uid |
|
78 |
|
79 def _switchState(self, state): |
|
80 if not isinstance(state, bool): |
|
81 return False |
|
82 if self._uid < 1: |
|
83 raise VMMAccountException(("Account doesn't exists", |
|
84 ERR.NO_SUCH_ACCOUNT)) |
|
85 dbc = self._dbh.cursor() |
|
86 dbc.execute("""UPDATE users SET disabled=%s WHERE local_part=%s\ |
|
87 AND gid=%s""", state, self._localpart, self._gid) |
|
88 if dbc.rowcount > 0: |
|
89 self._dbh.commit() |
|
90 dbc.close() |
|
91 |
|
92 def getUID(self): |
|
93 return self._uid |
|
94 |
|
95 def getGID(self): |
|
96 return self._gid |
|
97 |
|
98 def getDir(self, directory): |
|
99 if directory == 'domain': |
|
100 return '%s' % self._base |
|
101 elif directory == 'home': |
|
102 return '%s/%i' % (self._base, self._uid) |
|
103 |
|
104 def enable(self): |
|
105 self._switchState(False) |
|
106 |
|
107 def disable(self): |
|
108 self._switchState(True) |
|
109 |
|
110 def save(self, mail): |
|
111 if self._uid < 1: |
|
112 self._prepare() |
|
113 dbc = self._dbh.cursor() |
|
114 dbc.execute("""INSERT INTO users (local_part, passwd, uid, gid,\ |
|
115 home, mail) VALUES (%s, %s, %s, %s, %s, %s)""", self._localpart, |
|
116 self._passwd, self._uid, self._gid, self._home, mail) |
|
117 self._dbh.commit() |
|
118 dbc.close() |
|
119 else: |
|
120 raise VMMAccountException(('Account already exists.', |
|
121 ERR.ACCOUNT_EXISTS)) |
|
122 |
|
123 def modify(self, what, value): |
|
124 if self._uid == 0: |
|
125 raise VMMAccountException(("Account doesn't exists", |
|
126 ERR.NO_SUCH_ACCOUNT)) |
|
127 if what not in ['name', 'password']: |
|
128 return False |
|
129 dbc = self._dbh.cursor() |
|
130 if what == 'password': |
|
131 dbc.execute("UPDATE users SET passwd=%s WHERE local_part=%s AND\ |
|
132 gid=%s", value, self._localpart, self._gid) |
|
133 else: |
|
134 dbc.execute("UPDATE users SET name=%s WHERE local_part=%s AND\ |
|
135 gid=%s", value, self._localpart, self._gid) |
|
136 if dbc.rowcount > 0: |
|
137 self._dbh.commit() |
|
138 dbc.close() |
|
139 |
|
140 def getInfo(self): |
|
141 dbc = self._dbh.cursor() |
|
142 dbc.execute("SELECT name, uid, gid, home, mail, disabled FROM users\ |
|
143 WHERE local_part=%s AND gid=%s", self._localpart, self._gid) |
|
144 info = dbc.fetchone() |
|
145 dbc.close() |
|
146 if info is None: |
|
147 raise VMMAccountException(("Account doesn't exists", |
|
148 ERR.NO_SUCH_ACCOUNT)) |
|
149 else: |
|
150 keys = ['name', 'uid', 'gid', 'home', 'mail', 'disabled'] |
|
151 info = dict(zip(keys, info)) |
|
152 if bool(info['disabled']): |
|
153 info['disabled'] = 'Yes' |
|
154 else: |
|
155 info['disabled'] = 'No' |
|
156 info['address'] = self._addr |
|
157 info['home'] = '%s/%s' % (self._base, info['home']) |
|
158 return info |
|
159 |
|
160 def delete(self): |
|
161 if self._uid > 0: |
|
162 dbc = self._dbh.cursor() |
|
163 dbc.execute("DELETE FROM users WHERE gid=%s AND local_part=%s", |
|
164 self._gid, self._localpart) |
|
165 if dbc.rowcount > 0: |
|
166 self._dbh.commit() |
|
167 dbc.close() |
|
168 else: |
|
169 raise VMMAccountException(("Account doesn't exists", |
|
170 ERR.NO_SUCH_ACCOUNT)) |