summaryrefslogtreecommitdiffstats
path: root/auth.py
blob: 5a4790d08b6c8b90079e9f8c8171e30607720dc3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
from flask_peewee.auth import Auth
from flask import session
from models import User, Session
from app import app, db, pad
from datetime import datetime
from padlite import APIException
import ldap
import uuid

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()
        session['uuid'] = uuid.uuid4()
        return super(LdapAuth, self).login_user(user)

    def logout_user(self):
        if 'uuid' in session:
            for s in Session.select().where(Session.uuid == session['uuid']):
                try:
                    s.delete_instance()
                except APIException:
                    pass
            del session['uuid']
        return super(LdapAuth, self).logout_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)