import ldap
import pvl.ldap.domain
import pvl.users.group
import logging; log = logging.getLogger('pvl.login.auth')
class AuthError (Exception) :
def __init__ (self, error) :
self.error = error
def __unicode__ (self) :
return u"Authenticating against the backend failed: {self.error}".format(self=self)
class LDAPAuth (object) :
def __init__ (self, ldap) :
self.ldap = ldap
def auth (self, username, password) :
"""
Attempt to bind against LDAP with given user object and password.
Returns None if the user does not seem to exist, False on invalid auth, True on valid auth.
Raises AuthError.
"""
# search
try :
user = self.ldap.users.get(username)
except KeyError :
log.info("%s: not found", username)
return None
else :
log.info("%s: %s", username, user)
# bind
bind = self.bind(user, password)
if bind :
return user
else :
return False
def bind (self, user, password) :
"""
Attempt to bind against LDAP with given user object and password.
Returns the bound connection, or
None - if the user does not seem toe xist
False - invalid auth
Raises AuthError.
"""
conn = self.ldap.open()
try :
conn.bind(user.dn, password)
except ldap.INVALID_CREDENTIALS as ex :
log.info("%s: INVALID_CREDENTIALS", user)
return False
except ldap.NO_SUCH_OBJECT as ex :
log.info("%s: ldap.NO_SUCH_OBJECT", user)
return None
except ldap.LDAPError as ex :
log.exception("%s", user)
raise AuthError(ex)
else :
log.info("%s", user)
return conn
def access (self, user) :
"""
Yield a list of access control tokens for the given auth username.
"""
yield pvl.users.group.Group.fromldap(self.ldap.users.group(user))
for group in self.ldap.users.groups(user) :
yield pvl.users.group.Group.fromldap(group)
def userdata (self, user) :
"""
Yield arbitrary userdata for given auth state.
"""
return user.get('cn')
def renew (self, username) :
"""
Re-lookup auth state for given username.
"""
try :
return self.ldap.users.get(username)
except KeyError :
return None