]> git.ipfire.org Git - ipfire.org.git/blob - www/webapp/backend/accounts.py
accounts: Fix email address detection if user has a umlaut in his name.
[ipfire.org.git] / www / webapp / backend / accounts.py
1 #!/usr/bin/python
2 # encoding: utf-8
3
4 import hashlib
5 import ldap
6 import logging
7 import urllib
8
9 from misc import Singleton
10 from settings import Settings
11
12 class Accounts(object):
13 __metaclass__ = Singleton
14
15 @property
16 def settings(self):
17 return Settings()
18
19 def __init__(self):
20 self.__db = None
21
22 self._init()
23
24 @property
25 def search_base(self):
26 return Settings().get("ldap_search_base")
27
28 @property
29 def db(self):
30 if not self.__db:
31 ldap_uri = self.settings.get("ldap_uri")
32
33 self.__db = ldap.initialize(ldap_uri)
34
35 bind_dn = self.settings.get("ldap_bind_dn")
36
37 if bind_dn:
38 bind_pw = self.settings.get("ldap_bind_pw")
39
40 self.__db.simple_bind(bind_dn, bind_pw)
41
42 return self.__db
43
44 def get(self, dn):
45 return self._accounts[dn]
46
47 def _init(self):
48 self._accounts = {}
49 results = self.db.search_s(self.search_base, ldap.SCOPE_SUBTREE,
50 "(objectClass=posixAccount)", ["loginShell"])
51
52 for dn, attrs in results:
53 #if attrs["loginShell"] == ["/bin/bash"]:
54 self._accounts[dn] = Account(dn)
55
56 def list(self):
57 return sorted(self._accounts.values())
58
59 def find(self, uid):
60 for account in self.list():
61 if account.uid == uid:
62 return account
63
64 def delete(self, uid):
65 account = self.find(uid)
66 # XXX
67
68 search = find
69
70
71 class Account(object):
72 def __init__(self, dn):
73 self.dn = dn
74
75 self.__attributes = {}
76
77 def __repr__(self):
78 return "<%s %s>" % (self.__class__.__name__, self.dn)
79
80 def __cmp__(self, other):
81 return cmp(self.cn, other.cn)
82
83 @property
84 def db(self):
85 return Accounts().db
86
87 @property
88 def attributes(self):
89 if not self.__attributes:
90 self.fetch_attributes()
91
92 return self.__attributes
93
94 def fetch_attributes(self):
95 result = self.db.search_ext_s(self.dn, ldap.SCOPE_SUBTREE, sizelimit=1)
96 dn, self.__attributes = result[0]
97
98 def get(self, key):
99 try:
100 attribute = self.attributes[key]
101 except KeyError:
102 raise AttributeError(key)
103
104 if len(attribute) == 1:
105 return attribute[0]
106
107 return attribute
108
109 __getattr__ = get
110
111 def set(self, key, value):
112 mod_op = ldap.MOD_ADD
113 if self.attributes.has_key(key):
114 mod_op = ldap.MOD_REPLACE
115
116 self._modify(mod_op, key, value)
117
118 def _modify(self, op, key, value):
119 modlist = [(op, key, value)]
120
121 self.db.modify_s(self.dn, modlist)
122
123 # Update local cache of attributes
124 self.fetch_attributes()
125
126 def delete(self, key, value=None):
127 self._modify(ldap.MOD_DELETE, key, value)
128
129 def check_password(self, password):
130 """
131 Bind to the server with given credentials and return
132 true if password is corrent and false if not.
133
134 Raises exceptions from the server on any other errors.
135 """
136
137 logging.debug("Checking credentials for %s" % self.dn)
138 try:
139 self.db.simple_bind_s(self.dn, password)
140 except ldap.INVALID_CREDENTIALS:
141 return False
142
143 return True
144
145 @property
146 def is_admin(self):
147 return True # XXX todo
148
149 @property
150 def email(self):
151 name = self.cn.lower()
152 name = name.replace(" ", ".")
153 name = name.replace("Ä", "Ae")
154 name = name.replace("Ö", "Oe")
155 name = name.replace("Ü", "Ue")
156 name = name.replace("ä", "ae")
157 name = name.replace("ö", "oe")
158 name = name.replace("ü", "ue")
159
160 for mail in self.mail:
161 if mail.startswith(name + "@"):
162 return mail
163
164 raise Exception, "Cannot figure out email address"
165
166 def gravatar_icon(self, size=128):
167 # construct the url
168 gravatar_url = "http://www.gravatar.com/avatar/" + \
169 hashlib.md5(self.email.lower()).hexdigest() + "?"
170 gravatar_url += urllib.urlencode({'d': "mm", 's': str(size)})
171
172 return gravatar_url
173
174 if __name__ == "__main__":
175 a = Accounts()
176
177 print a.list()