cas_login.py 4.25 KB
Newer Older
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
# -*- coding: utf-8 -*-
#
# LOGIN.PY -- Gère l'interface d'authentification à l'aide des modèles Django.
#
# Copyright (C) 2009-2010 Nicolas Dandrimont
# Authors: Nicolas Dandrimont <olasd@crans.org>
# Censor: Antoine Durand-Gasselin <adg@crans.org>
#
# 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/>.

import settings, ldap
from django.contrib.auth.models import Group, User
from django.contrib.auth.backends import ModelBackend
from django.utils.importlib import import_module
26 27
from django_cas.backends import CASBackend, _verify
from django_cas.models import User
28

29
import login
30 31 32 33 34 35
conn_pool = import_module('conn_pool', 'intranet')

class CransCASBackend(CASBackend):
    """Authentifie un utilisateur à l'aide de la base LDAP"""

    supports_anonymous_user = False
36
    supports_inactive_user = False
37 38 39 40 41

    def authenticate(self, ticket, service, request):
        """Authentifie l'utilisateur sur la base LDAP. Crée un
        utilisateur django s'il n'existe pas encore."""

42
        username, attributes = _verify(ticket, service)
43 44 45
        # Si _verify plante, username contient None.
        if username is None or not username:
            return None
46 47
        # Sanitize username
        username = username.lower()
48 49 50 51 52 53 54 55
        if attributes:
            request.session['attributes'] = attributes
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            # user will have an "unusable" password
            user = User.objects.create_user(unicode(username), '')
            user.save()
56

57
        request.session.set_expiry(settings.SESSION_EXPIRY)
58

59 60 61
        django_username = user.username

        try:
62
            ldap_user = conn_pool.get_user(user)
63 64 65 66 67
        except IndexError:
            return None
        except ldap.INVALID_CREDENTIALS:
            return None

68 69
        login.refresh_droits(user, ldap_user)
        login.refresh_fields(user, ldap_user)
70 71 72 73 74 75
        return user

    def refresh_droits(self, user, cl_user):
        """Rafraîchit les droits de l'utilisateur django `user' depuis
        l'utilisateur LDAP `cl_user'"""

76
        cl_droits = [x.value for x in cl_user.get('droits', [])]
77 78 79 80 81 82
        if u"Nounou" in cl_droits:
            user.is_staff = True
            user.is_superuser = True
        else:
            user.is_staff = False
            user.is_superuser = False
83 84
        if u"Apprenti" in cl_droits:
            user.is_staff = True
85 86 87 88 89 90

        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)
91 92 93 94
        if cl_user.paiement_ok():
            group, created = Group.objects.get_or_create(name="crans_paiement_ok")
            group.save()
            groups.append(group)
95 96 97 98 99 100 101 102
        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)
103

104
        user.groups = [ group for group in user.groups.all() if not group.name.startswith('crans_') ]
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
        user.groups.add(*groups)
        user.save()

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

        user.first_name = unicode(cl_user['prenom'][0])
        user.last_name = unicode(cl_user['nom'][0])
        mail = unicode(cl_user['mail'][0])
        if '@' not in mail:  # Ne devrait pas arriver (pour migration)
            mail += u'@crans.org'
        user.email = mail

        user.save()