login.py 4.82 KB
Newer Older
1 2
# -*- coding: utf-8 -*-
#
3
# LOGIN.PY -- Gère l'interface d'authentification à l'aide des modèles Django.
4
#
5
# Copyright (C) 2009-2010 Nicolas Dandrimont
6
# Authors: Nicolas Dandrimont <olasd@crans.org>
7
# Censor: Antoine Durand-Gasselin <adg@crans.org>
8 9 10 11 12 13 14 15 16 17 18 19 20 21
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

22

23
import ldap
24 25
from django.contrib.auth.models import Group, User
from django.contrib.auth.backends import ModelBackend
Daniel STAN's avatar
Daniel STAN committed
26
from django.views.decorators.debug import sensitive_variables
27 28

# Pour se connecter à la base ldap
Vincent Le gallic's avatar
Vincent Le gallic committed
29
import lc_ldap.shortcuts
30

31
from intranet import conn_pool, settings
32

33 34 35 36 37 38 39 40 41 42 43
def refresh_droits(user, cl_user):
    """Rafraîchit les droits de l'utilisateur django `user' depuis
    l'utilisateur LDAP `cl_user'"""

    cl_droits = [x.value for x in cl_user.get('droits', [])]
    if u"Nounou" in cl_droits:
        user.is_staff = True
        user.is_superuser = True
    else:
        user.is_staff = False
        user.is_superuser = False
44 45 46 47
    if u"Apprenti" in cl_droits:
            user.is_staff = True
    if u"Imprimeur" in cl_droits:
            user.is_staff = True
48 49 50 51 52 53 54 55 56 57

    groups = []
    for cl_droit in cl_droits:
        group, created = Group.objects.get_or_create(name="crans_%s" % cl_droit.lower())
        group.save()
        groups.append(group)
    if cl_user.paiement_ok():
        group, created = Group.objects.get_or_create(name="crans_paiement_ok")
        group.save()
        groups.append(group)
58 59 60 61 62 63 64 65
    if cl_user.imprimeur_clubs():
        group, created = Group.objects.get_or_create(name="crans_imprimeur_club")
        group.save()
        groups.append(group)
    if cl_user.clubs():
        group, created = Group.objects.get_or_create(name="crans_respo_club")
        group.save()
        groups.append(group)
66 67 68 69
    if 'aid' in cl_user:
        group, created = Group.objects.get_or_create(name="crans_adherent")
        group.save()
        groups.append(group)
Daniel STAN's avatar
Daniel STAN committed
70
    if 'aid' in cl_user:
71 72 73
        group, created = Group.objects.get_or_create(name="crans_club")
        group.save()
        groups.append(group)
74 75 76 77 78 79 80 81 82

    user.groups = [ group for group in user.groups.all() if not group.name.startswith('crans_') ]
    user.groups.add(*groups)
    user.save()

def refresh_fields(user, cl_user):
    """Rafraîchit les champs correspondants à l'utilisateur (nom,
    prénom, email)"""

83
    user.first_name = unicode(cl_user.get('prenom', [u"club"])[0])
84
    user.last_name = unicode(cl_user['nom'][0])
85
    mail = unicode(cl_user.get('mail', cl_user['uid'])[0])
86 87 88 89 90 91
    if '@' not in mail:  # Ne devrait pas arriver (pour migration)
        mail += u'@crans.org'
    user.email = mail

    user.save()

92 93 94 95 96
def post_cas_login(sender, user, created, attributes, ticket, service, **kwargs):
    ldap_user = conn_pool.get_user(user)
    refresh_droits(user, ldap_user)
    refresh_fields(user, ldap_user)

97 98
class LDAPUserBackend(ModelBackend):
    """Authentifie un utilisateur à l'aide de la base LDAP"""
Nicolas Dandrimont's avatar
Nicolas Dandrimont committed
99

100
    supports_anonymous_user = False
101

Daniel STAN's avatar
Daniel STAN committed
102
    @sensitive_variables('password')
103 104 105
    def authenticate(self, username=None, password=None):
        """Authentifie l'utilisateur sur la base LDAP. Crée un
        utilisateur django s'il n'existe pas encore."""
106

107 108
        if not username or not password:
            return None
Vincent Le gallic's avatar
Vincent Le gallic committed
109
        shortcut = lc_ldap.shortcuts.lc_ldap_test if settings.BASE_LDAP_TEST else lc_ldap.shortcuts.lc_ldap
110
        try:
Vincent Le gallic's avatar
Vincent Le gallic committed
111
            conn = shortcut(user = username, cred = password)
112 113
            myself = conn.search(dn = conn.dn, scope = ldap.SCOPE_BASE)
            ldap_user = myself[0]
114 115
        except IndexError:
            return None
116 117
        except ldap.INVALID_CREDENTIALS:
            return None
118

119 120 121 122 123 124 125 126
        # On stocke les utilisateurs dans la base django comme "uid@crans.org"
        django_username = '%s@crans.org' % username
        try:
            user = User.objects.get(username=django_username)
        except User.DoesNotExist:
            user = User(username=django_username, password="LDAP Backend User!")
        user.save()
        conn_pool.CONNS[django_username] = conn
127 128
        refresh_droits(user, ldap_user)
        refresh_fields(user, ldap_user)
129
        return user
130 131 132 133 134 135 136

    def get_user(self, uid):
        """Récupère l'objet django correspondant à l'uid"""
        try:
            return User.objects.get(pk=uid)
        except User.DoesNotExist:
            return None
137