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