import ldap from functools import reduce def user_cls(login): def decorator(cls): login.user_loader(lambda uid: cls.query.get(uid)) return cls return decorator def _format_dn(attr, base_dn=None): attr = [attr] if base_dn is not None: attr.extend(base_dn) return ','.join(['%s=%s' % (key, ldap.dn.escape_dn_chars(value)) for (key, value) in attr]) def auth(config, model, username, password): ldap.protocol_version = 3 l = ldap.initialize(config['host']) l.set_option(ldap.OPT_X_TLS_DEMAND, True) try: user_dn = _format_dn(('uid', username), config['base_dn']) l.simple_bind_s(user_dn, password) except ldap.INVALID_CREDENTIALS: return None user = model.query.filter_by(name=username).first() if user is None: user_data = l.search_s(user_dn, ldap.SCOPE_BASE) if len(user_data) != 1: return None (dn, user_data) = user_data[0] user = model.create(name=username, email=user_data['mail'][0]) return user