GenGroup partially
[mirror/userdir-ldap.git] / UDLdap.py
1 import ldap
2 import time
3 import userdir_ldap
4
5 class Account:
6     array_values = ['keyFingerPrint', 'mailWhitelist', 'mailRBL', 'mailRHSBL', 'supplementaryGid']
7     int_values = ['shadowExpire', 'gidNumber']
8     defaults = {
9                  'accountStatus': 'active',
10                  'keyFingerPrint': []
11                }
12
13     @staticmethod
14     def from_search(ldap_connection, base, user):
15         searchresult = ldap_connection.search_s(base, ldap.SCOPE_SUBTREE, 'uid=%s'%(user))
16         if len(searchresult) < 1:
17             sys.stderr.write("No such user: %s\n"%(user))
18             return
19         elif len(searchresult) > 1:
20             sys.stderr.write("More than one hit when getting %s\n"%(user))
21             return
22         else:
23             return Account(searchresult[0][0], searchresult[0][1])
24
25     def __init__(self, dn, attributes):
26         self.dn = dn
27         self.attributes = attributes
28
29     def __getitem__(self, key):
30         if key in self.attributes:
31             if key in self.array_values:
32                 return self.attributes[key]
33             elif key in self.int_values:
34                 if len(self.attributes[key]) == 1:
35                     return int(self.attributes[key][0])
36                 else:
37                     raise ValueError, 'non-array value has not exactly one value'
38             else:
39                 return self.attributes[key][0]
40         elif key in self.defaults:
41             return self.defaults[key]
42         else:
43             raise IndexError
44
45     def __contains__(self, key):
46         return key in self.attributes
47
48     def has_mail(self):
49         if 'mailDisableMessage' in self.attributes:
50             return False
51         return True
52
53     # not locked locked,  just reset to something invalid like {crypt}*SSLRESET* is still active
54     def pw_active(self):
55         if self['userPassword'] == '{crypt}*LK*':
56             return False
57         if self['userPassword'].startswith("!"):
58             return False
59         return True
60
61     # not expired
62     def shadow_active(self):
63         if 'shadowExpire' in self and \
64             self['shadowExpire'] < (time.time() / 3600 / 24):
65             return False
66         return True
67
68     def numkeys(self):
69         return len(self['keyFingerPrint'])
70
71     def is_active_user(self):
72         return self['accountStatus'] == 'active' and self.numkeys() != 0
73
74     def latitude_dec(self, anonymized=False):
75         return userdir_ldap.DecDegree(self['latitude'], anonymized)
76     def longitude_dec(self, anonymized=False):
77         return userdir_ldap.DecDegree(self['longitude'], anonymized)
78
79     def verbose_status(self):
80         status = []
81         status.append('mail: %s'  %(['disabled', 'active'][ self.has_mail() ]))
82         status.append('pw: %s'    %(['locked', 'active'][ self.pw_active() ]))
83         status.append('shadow: %s'%(['expired', 'active'][ self.shadow_active() ]))
84         status.append('keys: %d'  %( self.numkeys() ))
85         status.append('status: %s'%( self['accountStatus'] ))
86
87         return '(%s)'%(', '.join(status))
88
89     def get_dn(self):
90         return self.dn
91
92 # vim:set et:
93 # vim:set ts=4:
94 # vim:set shiftwidth=4: