views.py 4.59 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 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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
# -*- encoding: utf-8 -*-
"""
    Views de l'application password_reset
"""

#: Import de settings de l'intranet
from intranet import settings

#: Import de fonctions utiles
from django.shortcuts import render, redirect
from django.core.urlresolvers import reverse_lazy

#: Import des views Django
from django.views.generic.detail import DetailView
from django.views.generic.edit import FormView

#: i18n
from django.utils.translation import ugettext_lazy as _

#: Pour stocker des messages dans la session courante
from django.contrib import messages

#: Import des formulaires
from password_reset.forms import EmailForm, UsernameForm

#: Tokenization
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode, int_to_base36
from django.utils.crypto import salted_hmac

#Copié depuis Django1.11
class MyResetTokenGenerator(PasswordResetTokenGenerator):
    """
        Classe pour la génération d'un token à partir de la
        base LDAP.
    """
    key_salt = "django.contrib.auth.tokens.PasswordResetTokenGenerator"
    secret = settings.SECRET_KEY

    def _make_token_with_timestamp(self, user, timestamp):
        ts_b36 = int_to_base36(timestamp)

        hash = salted_hmac(
            self.key_salt,
            self._make_hash_value(user, timestamp),
            secret=self.secret,
        ).hexdigest()[::2]
        return "%s-%s" % (ts_b36, hash)

    def _make_hash_value(self, user, timestamp):
        # On surchage la méthode pour rechercher les informations
        # dans la base LDAP
        login_timestamp = user['derniereConnexion'][0] or ''
        return str(user["uidNumber"][0]) + str(user['userPassword'][0])\
                + str(login_timestamp) + str(timestamp)

my_token_generator = MyResetTokenGenerator()

class PasswordResetFormView(FormView):
    template_name = "password_reset/password_reset_form.html"
    success_url = reverse_lazy("password_reset:password_reset_done")
    lform = UsernameForm
    eform = EmailForm
    token_generator = my_token_generator

    def form_valid(self, request, form, *args, **kwargs):
        user = form.get_user()
        if user:
            from gestion import mail
            c = {
                'from' : 'cableurs@crans.org',
                'to': str((user["mailExt"] or user["mail"])[0]),
                'name': str(user["cn"][0]),
                'protocol': 'https',
                'domain': request.META['HTTP_HOST'],
                'uid': urlsafe_base64_encode(force_bytes(user["aid"][0])),
                'token': self.token_generator.make_token(user),
                'username' : str(user["uid"][0]),
                'mailer' : u"reset_pw",
            }

            # On utilise la class ServerConnection() dans /usr/scripts
            with mail.ServerConnection() as conn_smtp:
                conn_smtp.send_template('password_reset', c)

        return super(PasswordResetFormView, self).form_valid(form, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        req = request.POST

        # On récupere et on rempli le formulaire approrié
        form = self.lform(req) if 'username' in req else self.eform(req)

        if form.is_valid():
            return self.form_valid(request, form, **kwargs)
        else:
            return redirect(self.success_url)

    def get(self, request, next=None, *args, **kwargs):
        # On vérifie que l'utilisateur n'est pas connecté.
        # Sinon, il ne chercherait pas à réinitialiser son mot de passe.
        if not request.user.is_anonymous():
            messages.error(request, _(u"Vous devez vous déconnecter pour accédez à cette page"))
            return redirect(reverse_lazy('index'))
        return render(
            request,
            self.template_name,
            {'lform': self.lform,
             'eform': self.eform,
            },
        )

password_reset = PasswordResetFormView.as_view()

class PasswordResetDoneView(DetailView):
    """
        Vue pour la confirmation d'instructions de réinitialisation
        de mot de passe.

        On confirme toujours sinon quoi on donnerait des informations sur l'existence
        de login ou d'adresses e-mails.
    """
    def get(self, request, next=None, *args, **kwargs):
        if not request.user.is_anonymous():
            messages.error(request, _(u"Vous devez vous déconnecter pour accédez à cette page"))
            return redirect(reverse_lazy('index'))
        return render(
            request,
            "password_reset/password_reset_done.html",
        )

password_reset_done = PasswordResetDoneView.as_view()