from flask_peewee.auth import Auth from models import User from app import app, db, pad from datetime import datetime import ldap class LdapAuth(Auth): def get_user_model(self): return User def authenticate(self, username, password): ldap.protocol_version = 3 l = ldap.initialize(app.config['LDAP']['host']) l.set_option( ldap.OPT_X_TLS_DEMAND, True ) try: user_dn = self._format_dn([('uid', username)]) l.simple_bind_s(user_dn, password) except ldap.INVALID_CREDENTIALS: return False try: user = User.get(User.username == username) except User.DoesNotExist: user_data = l.search_s(user_dn, ldap.SCOPE_BASE) if (len(user_data) != 1): return False (dn, user_data) = user_data[0] user = User.create( username = username, email = user_data['mail'][0], api_id = pad.createAuthorIfNotExistsFor(user_dn, username)) return user def login_user(self, user): user.last_login = datetime.now() user.save() super(LdapAuth, self).login_user(user) def _format_dn(self, attr, with_base_dn = True): if with_base_dn: attr.extend(app.config['LDAP']['base_dn']) dn = ['%s=%s' % (item[0], self._escape(item[1])) for item in attr] return ','.join(dn) def _escape(self, s, wildcard=False): chars_to_escape = ['\\',',','=','+','<','>',';','"','\'','#','(',')','\0'] if not wildcard: chars_to_escape.append('*') escape = lambda x,y: x.replace(y,'\%02X' % ord(y)) return reduce(escape, chars_to_escape, s) auth = LdapAuth(app, db, user_model=User)