Les nouveaux comptes doivent maintenant être activés par un lien courriel.
authorEric Mc Sween <eric.mcsween@gmail.com>
Tue, 14 Dec 2010 00:13:22 +0000 (19:13 -0500)
committerEric Mc Sween <eric.mcsween@gmail.com>
Tue, 14 Dec 2010 00:13:22 +0000 (19:13 -0500)
auf_savoirs_en_partage/chercheurs/forms.py
auf_savoirs_en_partage/chercheurs/models.py
auf_savoirs_en_partage/chercheurs/views.py
auf_savoirs_en_partage/templates/chercheurs/activation.html [new file with mode: 0644]
auf_savoirs_en_partage/templates/chercheurs/activation_email.txt [new file with mode: 0644]
auf_savoirs_en_partage/templates/chercheurs/chercheur_form.html
auf_savoirs_en_partage/templates/chercheurs/inscription_faite.html [new file with mode: 0644]
auf_savoirs_en_partage/templates/chercheurs/password_reset_email.txt
auf_savoirs_en_partage/templates/chercheurs/password_reset_form.html
auf_savoirs_en_partage/urls.py

index 69ab78b..6230bcc 100644 (file)
@@ -56,7 +56,7 @@ class ChercheurForm(forms.ModelForm):
 
     class Meta:
         model = Chercheur
-        fields = ('nom', 'prenom', 'courriel', 'genre',
+        fields = ('nom', 'prenom', 'genre',
                   'statut', 'diplome', 'discipline', 'theme_recherche',
                   'groupe_recherche', 'mots_cles', 'url_site_web',
                   'url_blog', 'url_reseau_social', 'attestation',
@@ -172,24 +172,9 @@ class ChercheurForm(forms.ModelForm):
         return bool(int(self.cleaned_data['expertises_auf']))
 
 class ChercheurInscriptionForm(ChercheurForm):
-    password = forms.CharField(widget=forms.PasswordInput(), label="Mot de passe") 
-    password_confirmation = forms.CharField(widget=forms.PasswordInput(), label="Confirmez votre mot de passe")
 
     class Meta(ChercheurForm.Meta):
-        fields = ChercheurForm.Meta.fields + ('password',)
-        
-    def clean_password_confirmation(self):
-        """S'assurer que le mot de passe et la confirmation sont identiques."""
-        password = self.cleaned_data.get('password')
-        confirmation = self.cleaned_data.get('password_confirmation')
-        if password != confirmation:
-            raise forms.ValidationError('Les deux mots de passe ne correspondent pas.')
-        return confirmation
-
-    def save(self):
-        super(ChercheurInscriptionForm, self).save()
-        self.instance.user.set_password(self.cleaned_data['password'])
-        self.instance.user.save()
+        fields = ChercheurForm.Meta.fields + ('courriel',)
 
 class GroupesForm(forms.Form):
     """Formulaire qui associe des groupes à un chercheur."""
@@ -245,11 +230,11 @@ class ChercheurFormGroup(object):
        d'un chercheur."""
 
     def __init__(self, data=None, chercheur=None):
-        chercheur_form_class = ChercheurInscriptionForm if chercheur is None else ChercheurForm
         try:
             these = chercheur and chercheur.these
         except These.DoesNotExist:
             these = These()
+        chercheur_form_class = ChercheurInscriptionForm if chercheur is None else ChercheurForm
         self.chercheur = chercheur_form_class(data=data, prefix='chercheur', instance=chercheur)
         self.groupes = GroupesForm(data=data, prefix='chercheur', chercheur=chercheur)
         self.expertises = ExpertiseFormSet(data=data, prefix='expertise', instance=chercheur)
@@ -284,6 +269,7 @@ class ChercheurFormGroup(object):
             self.publications.save()
             self.expertises.instance = chercheur
             self.expertises.save()
+            return self.chercheur.instance
 
 class RepertoireSearchForm (forms.Form):
     q = forms.CharField(required=False, label="Rechercher dans tous les champs")
@@ -352,9 +338,9 @@ class SendPasswordForm(forms.Form):
                 raise forms.ValidationError("Cette adresse n'existe pas dans notre base de données.")       
         return email
 
-class NewPasswordForm(forms.Form):
+class SetPasswordForm(forms.Form):
     password = forms.CharField(widget=forms.PasswordInput(), required=True, label="Mot de passe") 
-    password_repeat = forms.CharField(widget=forms.PasswordInput(), required=True, label="Confirmez mot de passe")
+    password_repeat = forms.CharField(widget=forms.PasswordInput(), required=True, label="Confirmez votre mot de passe")
 
     def clean_password_repeat(self):
         cleaned_data = self.cleaned_data
@@ -364,4 +350,3 @@ class NewPasswordForm(forms.Form):
             if password != password_repeat:
                 raise forms.ValidationError("Les mots de passe ne concordent pas")
         return password_repeat   
-
index 97d9169..1334ab0 100644 (file)
@@ -2,10 +2,12 @@
 import hashlib
 from authentification import get_django_user_for_email
 from datamaster_modeles.models import *
+from django.conf import settings
 from django.contrib.auth.models import User
 from django.db import models
 from django.db.models import Q
 from django.utils.encoding import smart_str
+from django.utils.hashcompat import sha_constructor
 from djangosphinx.models import SphinxSearch
 from savoirs.models import Discipline, SEPManager, SEPSphinxQuerySet, SEPQuerySet
 
@@ -42,7 +44,8 @@ class Personne(models.Model):
         else:
             if self.user:
                 self.user.is_active = False
-        self.user.save()
+        if self.user:
+            self.user.save()
         super(Personne, self).save()
 
 class ChercheurQuerySet(SEPQuerySet):
@@ -241,6 +244,9 @@ class Chercheur(Personne):
             self.etablissement_autre_pays = None
         super(Chercheur, self).save()
 
+    def activation_token(self):
+        return sha_constructor(settings.SECRET_KEY + unicode(self.id)).hexdigest()[::2]
+
 class Publication(models.Model):
     chercheur = models.ForeignKey(Chercheur, related_name='publications')
     auteurs = models.CharField(max_length=255, blank=True, verbose_name='auteur(s)')
index 1e98053..9df1482 100644 (file)
@@ -1,6 +1,9 @@
 # -*- encoding: utf-8 -*-
 import hashlib
 from chercheurs.decorators import chercheur_required
+from chercheurs.forms import RepertoireSearchForm, SetPasswordForm, ChercheurFormGroup 
+from chercheurs.models import Chercheur
+from datamaster_modeles.models import Etablissement
 from django.shortcuts import render_to_response
 from django.http import HttpResponseRedirect, HttpResponse
 from django.template import Context, RequestContext
@@ -8,10 +11,12 @@ from django.template.loader import get_template
 from django.core.urlresolvers import reverse as url
 from django.core.mail import send_mail
 from django.conf import settings
+from django.contrib.auth.tokens import default_token_generator as token_generator
+from django.contrib.sites.models import RequestSite
 from django.utils import simplejson
+from django.utils.http import int_to_base36, base36_to_int
 from django.views.decorators.cache import never_cache
 
-from forms import *
 from django.forms.models import inlineformset_factory
 
 from auf_references_client.models import Discipline, TypeImplantation
@@ -54,11 +59,14 @@ def inscription(request):
     if request.method == 'POST':
         forms = ChercheurFormGroup(request.POST)
         if forms.is_valid():
-            forms.save()
-            # login automatique
-            login(request, authenticate(username=forms.chercheur.cleaned_data['courriel'], 
-                                        password=forms.chercheur.cleaned_data['password']))
-            return HttpResponseRedirect(url('chercheurs.views.perso'))
+            chercheur = forms.save()
+            id_base36 = int_to_base36(chercheur.id)
+            token = chercheur.activation_token()
+            template = get_template('chercheurs/activation_email.txt')
+            domain = RequestSite(request).domain
+            message = template.render(Context(dict(chercheur=chercheur, id_base36=id_base36, token=token, domain=domain)))
+            send_mail('Votre inscription à Savoirs en partage', message, None, [chercheur.courriel])
+            return HttpResponseRedirect(url('chercheurs-inscription-faite'))
     else:
         forms = ChercheurFormGroup()
     
@@ -66,6 +74,33 @@ def inscription(request):
                               dict(forms=forms),
                               context_instance=RequestContext(request))
 
+def activation(request, id_base36, token):
+    """Activation d'un chercheur"""
+    id = base36_to_int(id_base36)
+    chercheur = get_object_or_404(Chercheur, id=id)
+    if token == chercheur.activation_token():
+        validlink = True
+        if request.method == 'POST':
+            form = SetPasswordForm(request.POST)
+            if form.is_valid():
+                password = form.cleaned_data['password']
+                email = chercheur.courriel
+                chercheur.actif = True
+                chercheur.save()
+                chercheur.user.set_password(password)
+                chercheur.user.save()
+
+                # Auto-login
+                login(request, authenticate(username=email, password=password))
+                return HttpResponseRedirect(url('chercheurs.views.perso'))
+        else:
+            form = SetPasswordForm()
+    else:
+        form = None
+        validlink = False
+    return render_to_response('chercheurs/activation.html', dict(form=form, validlink=validlink),
+                              context_instance=RequestContext(request))
+
 @chercheur_required
 def desinscription(request):
     """Désinscription du chercheur"""
diff --git a/auf_savoirs_en_partage/templates/chercheurs/activation.html b/auf_savoirs_en_partage/templates/chercheurs/activation.html
new file mode 100644 (file)
index 0000000..71387bd
--- /dev/null
@@ -0,0 +1,18 @@
+{% extends "container_base.html" %}
+
+{% block contenu %}
+<div class="cadre">
+    <h1>Activation de votre compte</h1>
+    {% if validlink %}
+    <form method="post">
+        <p>Veuillez choisir un mot de passe.</p>
+        <table>
+            {% include "render_form.html" %}
+            <tr><th></th><td><input type="submit" value="Envoyer" /></td></tr>
+        </table>
+    </form>
+    {% else %}
+    <p>Cette clé d'activation est invalide. Assurez-vous de bien copier le lien qui vous a été envoyé par courriel.</p>
+    {% endif %}
+</div>
+{% endblock %}
diff --git a/auf_savoirs_en_partage/templates/chercheurs/activation_email.txt b/auf_savoirs_en_partage/templates/chercheurs/activation_email.txt
new file mode 100644 (file)
index 0000000..429707b
--- /dev/null
@@ -0,0 +1,17 @@
+Bonjour,
+
+Nous avons enregistré votre inscription à Savoirs en partage.
+
+Veuillez maintenant confirmer votre adresse électronique en suivant le lien
+suivant:
+
+  http://{{ domain }}{% url chercheurs-activation id_base36=id_base36, token=token %}
+
+Si vous rencontrez des difficultés, vous pouvez écrire à : contact-savoirsenpartage@auf.org
+
+Avec nos meilleures salutations.
+
+-- 
+Savoirs en partage
+http://{{ domain }}
+contact-savoirsenpartage@auf.org
index 305fbea..9102e51 100644 (file)
@@ -8,12 +8,10 @@
     <table>
         {% form_field forms.chercheur.nom %}
         {% form_field forms.chercheur.prenom %}
+        {% if forms.chercheur.courriel %}
         {% form_field forms.chercheur.courriel %}
-        {% form_field forms.chercheur.genre %}
-        {% if forms.chercheur.password %}
-        {% form_field forms.chercheur.password %}
-        {% form_field forms.chercheur.password_confirmation %}
         {% endif %}
+        {% form_field forms.chercheur.genre %}
     </table>
 </fieldset>
 
diff --git a/auf_savoirs_en_partage/templates/chercheurs/inscription_faite.html b/auf_savoirs_en_partage/templates/chercheurs/inscription_faite.html
new file mode 100644 (file)
index 0000000..4c4225c
--- /dev/null
@@ -0,0 +1,8 @@
+{% extends "container_base.html" %}
+
+{% block contenu %}
+<div class="cadre">
+    <p>Un courriel contenant un lien d'activation vous a été envoyé.</p>
+    <p><a href="{% url savoirs.views.index %}">Retour à l'accueil</a></p>
+</div>
+{% endblock %}
index 1a4e39a..9e02f7d 100644 (file)
@@ -2,7 +2,7 @@ Bonjour {{user.personne.prenom}} {{user.personne.nom}},
 
 Nous avons reçu une demande de changement de mot de passe.
 
-Pour procéder à cette manoeuvre, veuillez vous rendre au lien suivant:
+Pour procéder à cette manoeuvre, veuillez suivre le lien suivant:
 
 {{ protocol }}://{{ domain }}{% url chercheurs-password-reset-confirm uidb36=uid, token=token %}
 
index ebb94fc..f776261 100644 (file)
@@ -5,7 +5,10 @@
     <h1>Demande de changement de mot de passe</h1>
     <form method="post">
         <p>Veuillez entrer l'adresse électronique avec laquelle vous avez completé votre inscription.</p>
-        {{ form.email }}
+        <p>
+            {{ form.email }}
+            {% if form.email.errors %}{{ form.email.errors }}{% endif %}
+        </p>
         <input type="submit" name="Submit" value="Envoyer" class="bouton" />
     </form>
 </div>
index c2664bc..1a239dd 100644 (file)
@@ -65,6 +65,10 @@ urlpatterns = sep_patterns + patterns(
     (r'^chercheurs/$', 'chercheurs.views.index'),
     (r'^chercheurs/(?P<id>\d+)/$', 'chercheurs.views.retrieve'),
     (r'^chercheurs/inscription/$', 'chercheurs.views.inscription'),
+    (r'^chercheurs/inscription_faite/$', 'django.views.generic.simple.direct_to_template', dict(
+        template='chercheurs/inscription_faite.html'
+    ), 'chercheurs-inscription-faite'),
+    (r'^chercheurs/activation/(?P<id_base36>.*)/(?P<token>.*)/$', 'chercheurs.views.activation', {}, 'chercheurs-activation'),
     (r'^chercheurs/desinscription/$', 'chercheurs.views.desinscription'),
     (r'^chercheurs/perso/$', 'chercheurs.views.perso'),
     (r'^chercheurs/edit/$', 'chercheurs.views.edit'),