瀏覽代碼

Password recoevery and change

Denis Merigoux 9 年之前
父節點
當前提交
609ddd6b07

+ 1 - 0
counter/templates/homeTemplate.html

@@ -131,5 +131,6 @@
131 131
 </div>
132 132
 <div class="row text-center">
133 133
 		<a href="{% url 'logout' %}" class="btn btn-danger">Se déconnecter</a>
134
+		<a href="{% url 'password_change' %}" class="btn btn-warning">Changer de mot de passe</a>
134 135
 </div>
135 136
 {% endblock %}

+ 3 - 2
counter/templates/login.html

@@ -15,15 +15,16 @@
15 15
                     {% csrf_token %}
16 16
                     <div class="form-group">
17 17
                         <label for="id_username">Trigramme</label>
18
-                        <input id="id_username" maxlength="3" type="text" class="form-control text-uppercase" name="username" />
18
+                        <input id="id_username" maxlength="3" type="text" class="form-control text-uppercase" name="username" required />
19 19
                     </div>
20 20
                     <div class="form-group">
21 21
                         <label for="id_username">Mot de passe</label>
22
-                        <input id="id_username" type="password" class="form-control" name="password" />
22
+                        <input id="id_username" type="password" class="form-control" name="password" required />
23 23
                     </div>
24 24
                     <input type="hidden" name="next" value="{{ next }}" />
25 25
                     <div class="text-center">
26 26
                         <button type="submit" class="btn btn-default btn-success">Se connecter</button>
27
+                        <a href="{% url 'password_reset' %}" class="btn btn-default btn-danger">Mot de passe oublié</a>
27 28
                     </div>
28 29
                 </form>
29 30
             </div>

+ 48 - 0
counter/templates/passwordChange.html

@@ -0,0 +1,48 @@
1
+{% extends 'baseTemplate.html' %} {% block title %}Changement du mot de passe{% endblock %}{% block content %}
2
+<div class="container">
3
+    <div class="row">
4
+        <div class="text-center">
5
+            <h1>SeumBook™</h1>
6
+        </div>
7
+    </div>
8
+    <div class="row">
9
+        <div class="panel panel-primary">
10
+            <div class="panel-heading">
11
+                <h2 class="panel-title">Change ton mot de passe du seum !</h2>
12
+            </div>
13
+            <div class=" panel-body">
14
+                <form class='' method="POST" action="{% url 'password_change' %}">
15
+                    {% csrf_token %}
16
+                    <div class="form-group">
17
+                        <label for="id_old_password">Ancien mot de passe</label>
18
+                        <input id="id_old_password" type="password" class="form-control" name="old_password" required />
19
+                    </div>
20
+                    <div class="form-group">
21
+                        <label for="id_new_password1">Nouveau mot de passe</label>
22
+                        <input id="id_new_password1" type="password" class="form-control" name="new_password1" required />
23
+                    </div>
24
+                    <div class="form-group">
25
+                        <label for="id_new_password2">Confirmer le nouveau mot de passe</label>
26
+                        <input id="id_new_password2" type="password" class="form-control" name="new_password2" required />
27
+                    </div>
28
+                    <div class="text-center">
29
+                        <button type="submit" class="btn btn-default btn-success">Changer le mot de passe</button>
30
+                    </div>
31
+                </form>
32
+            </div>
33
+        </div>
34
+    </div>
35
+    {% if form.errors %}
36
+    <div class="row">
37
+        <div class="panel panel-danger">
38
+            <div class="panel-heading">
39
+                <h2 class="panel-title">Erreur</h2>
40
+            </div>
41
+            <div class=" panel-body">
42
+                <p>T'arrives même pas à changer ton mot de passe, seum.</p>
43
+            </div>
44
+        </div>
45
+    </div>
46
+    {% endif %}
47
+</div>
48
+{% endblock %}

+ 22 - 0
counter/templates/passwordChangeDone.html

@@ -0,0 +1,22 @@
1
+{% extends 'baseTemplate.html' %} {% block title %}Mot de passe changé !{% endblock %}{% block content %}
2
+<div class="container">
3
+    <div class="row">
4
+        <div class="text-center">
5
+            <h1>SeumBook™</h1>
6
+        </div>
7
+    </div>
8
+    <div class="row">
9
+        <div class="panel panel-primary">
10
+            <div class="panel-heading">
11
+                <h2 class="panel-title">Victoire !</h2>
12
+            </div>
13
+            <div class=" panel-body">
14
+                <p>T'as changé ton mot de passe !</p>
15
+                <div class="text-center">
16
+                    <a href="{% url 'home' %}" type="submit" class="btn btn-default btn-success">Retour à l'accueil</a>
17
+                </div>
18
+            </div>
19
+        </div>
20
+    </div>
21
+</div>
22
+{% endblock %}

+ 40 - 0
counter/templates/passwordReset.html

@@ -0,0 +1,40 @@
1
+{% extends 'baseTemplate.html' %} {% block title %}Mot de passe oublié{% endblock %}{% block content %}
2
+<div class="container">
3
+    <div class="row">
4
+        <div class="text-center">
5
+            <h1>SeumBook™</h1>
6
+        </div>
7
+    </div>
8
+    <div class="row">
9
+        <div class="panel panel-primary">
10
+            <div class="panel-heading">
11
+                <h2 class="panel-title">Réinitialisation du mot de passe</h2>
12
+            </div>
13
+            <div class=" panel-body">
14
+                <form class='' method="POST" action="{% url 'password_reset' %}">
15
+                    {% csrf_token %}
16
+                    <div class="form-group">
17
+                        <label for="id_email">Email auquel sera envoyé le lien de réinitialisation</label>
18
+                        <input id="id_email" type="email" class="form-control" name="email" required/>
19
+                    </div>
20
+                    <div class="text-center">
21
+                        <button type="submit" class="btn btn-default btn-success">Envoyer</button>
22
+                    </div>
23
+                </form>
24
+            </div>
25
+        </div>
26
+    </div>
27
+    {% if form.errors %}
28
+    <div class="row">
29
+        <div class="panel panel-danger">
30
+            <div class="panel-heading">
31
+                <h2 class="panel-title">Erreur</h2>
32
+            </div>
33
+            <div class=" panel-body">
34
+                <p>T'arrives même pas à te connecter, seum.</p>
35
+            </div>
36
+        </div>
37
+    </div>
38
+    {% endif %}
39
+</div>
40
+{% endblock %}

+ 22 - 0
counter/templates/passwordResetComplete.html

@@ -0,0 +1,22 @@
1
+{% extends 'baseTemplate.html' %} {% block title %}Mot de passe changé !{% endblock %}{% block content %}
2
+<div class="container">
3
+    <div class="row">
4
+        <div class="text-center">
5
+            <h1>SeumBook™</h1>
6
+        </div>
7
+    </div>
8
+    <div class="row">
9
+        <div class="panel panel-success">
10
+            <div class="panel-heading">
11
+                <h2 class="panel-title">Victoire !</h2>
12
+            </div>
13
+            <div class=" panel-body">
14
+                <p>Ça y est tu as réinitialisé ton mot de passe ! Du coup tu peux aller remettre ton compteur à zéro.</p>
15
+                <div class="text-center">
16
+                    <a href="{% url 'home' %}" type="submit" class="btn btn-default btn-success">Retour à l'accueil</a>
17
+                </div>
18
+            </div>
19
+        </div>
20
+    </div>
21
+</div>
22
+{% endblock %}

+ 55 - 0
counter/templates/passwordResetConfirm.html

@@ -0,0 +1,55 @@
1
+{% extends 'baseTemplate.html' %} {% block title %}Changement du mot de passe{% endblock %}{% block content %}
2
+<div class="container">
3
+    <div class="row">
4
+        <div class="text-center">
5
+            <h1>SeumBook™</h1>
6
+        </div>
7
+    </div>
8
+    <div class="row">
9
+        {% if validlink %}
10
+        <div class="panel panel-primary">
11
+            <div class="panel-heading">
12
+                <h2 class="panel-title">Change ton mot de passe du seum !</h2>
13
+            </div>
14
+            <div class=" panel-body">
15
+                <form class='' method="POST">
16
+                    {% csrf_token %}
17
+                    <div class="form-group">
18
+                        <label for="id_new_password1">Nouveau mot de passe</label>
19
+                        <input id="id_new_password1" type="password" class="form-control" name="new_password1" required />
20
+                    </div>
21
+                    <div class="form-group">
22
+                        <label for="id_new_password2">Confirmer le nouveau mot de passe</label>
23
+                        <input id="id_new_password2" type="password" class="form-control" name="new_password2" required />
24
+                    </div>
25
+                    <div class="text-center">
26
+                        <button type="submit" class="btn btn-default btn-success">Changer le mot de passe</button>
27
+                    </div>
28
+                </form>
29
+            </div>
30
+        </div>
31
+    </div>
32
+    {% if form.errors %}
33
+    <div class="row">
34
+        <div class="panel panel-danger">
35
+            <div class="panel-heading">
36
+                <h2 class="panel-title">Erreur</h2>
37
+            </div>
38
+            <div class=" panel-body">
39
+                <p>T'arrives même pas à changer ton mot de passe, seum.</p>
40
+            </div>
41
+        </div>
42
+    </div>
43
+    {% endif %} {% else %}
44
+    <div class="row">
45
+        <div class="panel panel-danger">
46
+            <div class="panel-heading">
47
+                <h2 class="panel-title">Erreur</h2>
48
+            </div>
49
+            <div class=" panel-body">
50
+                <p>T'as le seum, le lien qui t'as été donné pour visiter cette page est déjà utilisé.</p>
51
+            </div>
52
+        </div>
53
+    </div>
54
+    {% endif %} {% endblock %}
55
+</div>

+ 15 - 0
counter/templates/resetEmail.txt

@@ -0,0 +1,15 @@
1
+{% autoescape off %}
2
+T'as perdu ton mot de passe et t'as le seum.
3
+
4
+Please go to the following page and choose a new password:
5
+{% block reset_link %}
6
+{{ protocol }}://{{ domain }}{% url 'password_reset_confirm' uidb64=uid token=token %}
7
+{% endblock %}
8
+
9
+Ton trigramme c'est {{ user.username }} au cas où tu l'aurais oublié aussi.
10
+
11
+--
12
+SeumBook™ - http://seum.merigoux.ovh
13
+
14
+P.S. : Pour ne plus recevoir ces messages, envoie un mail à denis.merigoux@gmail.com
15
+{% endautoescape %}

+ 0 - 0
counter/templates/seumEmail.txt


+ 1 - 0
counter/templates/subjectEmail.txt

@@ -0,0 +1 @@
1
+[SeumBook] Réinitialisation du mot de passe

+ 27 - 7
counter/urls.py

@@ -1,18 +1,38 @@
1 1
 from django.conf.urls import url
2 2
 from counter.rss import SeumFeed
3 3
 from django.contrib.auth import views as auth_views
4
+from django.views.generic.base import RedirectView
4 5
 
5 6
 from . import views
6 7
 
7 8
 urlpatterns = [
8 9
     url(r'^$', views.home, name="home"),
9
-    url(r'^reset-counter', views.resetCounter, name="reset-counter"),
10
-    url(r'^counter/(?P<id_counter>\d+)$', views.counter, name="counter"),
11
-    url(r'^rss', SeumFeed()),
12
-    url(r'^login', auth_views.login,
10
+    url(r'^reset-counter/$', views.resetCounter, name="reset-counter"),
11
+    url(r'^counter/(?P<id_counter>\d+)/$', views.counter, name="counter"),
12
+    url(r'^rss/$', SeumFeed()),
13
+    url(r'^login/$', auth_views.login,
13 14
         {'template_name': 'login.html'},
14 15
         name="login"),
15
-    url(r'^logout', auth_views.logout,
16
-        {'next_page': 'login'},
17
-        name='logout')
16
+    url(r'^logout/$', auth_views.logout_then_login,
17
+        name='logout'),
18
+    url(r'^password/change/$', auth_views.password_change,
19
+        {'template_name': 'passwordChange.html'},
20
+        name="password_change"),
21
+    url(r'^password/change/done∕$', auth_views.password_change_done,
22
+        {'template_name': 'passwordChangeDone.html'},
23
+        name="password_change_done"),
24
+    url(r'^password/reset/$', auth_views.password_reset,
25
+        {'template_name': 'passwordReset.html',
26
+         'email_template_name': 'resetEmail.txt',
27
+         'subject_template_name': 'subjectEmail.txt'},
28
+        name="password_reset"),
29
+    url(r'^password/reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$',
30
+        auth_views.password_reset_confirm,
31
+        {'template_name': 'passwordResetConfirm.html'},
32
+        name="password_reset_confirm"),
33
+    url(r'^password/reset/complete/$',
34
+        auth_views.password_reset_complete,
35
+        {'template_name': 'passwordResetComplete.html'},
36
+        name="password_reset_complete"),
37
+    url(r'^', RedirectView.as_view(pattern_name='home')),
18 38
 ]

+ 2 - 1
counter/views.py

@@ -6,6 +6,7 @@ from django import forms
6 6
 from django.http import HttpResponseRedirect
7 7
 from django.core.mail import EmailMessage
8 8
 from django.contrib.auth.decorators import login_required
9
+from django.core.urlresolvers import reverse
9 10
 from graphos.renderers import gchart
10 11
 from graphos.sources.simple import SimpleDataSource
11 12
 from graphos.sources.model import ModelDataSource
@@ -46,7 +47,7 @@ def home(request):
46 47
         myCounter.lastReset.formatted_delta = format_timedelta(
47 48
             myCounter.lastReset.delta, locale='fr', threshold=1)
48 49
     except Counter.DoesNotExist:
49
-        return HttpResponseRedirect('login')
50
+        return HttpResponseRedirect(reverse('login'))
50 51
 
51 52
     # Building data for counters display
52 53
     counters = Counter.objects.all()

+ 4 - 21
seum/settings.py.default

@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/1.9/ref/settings/
11 11
 """
12 12
 
13 13
 import os
14
+from django.core.urlresolvers import reverse_lazy
14 15
 
15 16
 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16 17
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -86,25 +87,6 @@ DATABASES = {
86 87
 }
87 88
 
88 89
 
89
-# Password validation
90
-# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
91
-
92
-AUTH_PASSWORD_VALIDATORS = [
93
-    {
94
-        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
95
-    },
96
-    {
97
-        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
98
-    },
99
-    {
100
-        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
101
-    },
102
-    {
103
-        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
104
-    },
105
-]
106
-
107
-
108 90
 # Internationalization
109 91
 # https://docs.djangoproject.com/en/1.9/topics/i18n/
110 92
 
@@ -133,5 +115,6 @@ EMAIL_HOST_PASSWORD = ''
133 115
 EMAIL_USE_TLS = False
134 116
 DEFAULT_FROM_EMAIL = 'SeumMan <seum@merigoux.ovh>'
135 117
 
136
-LOGIN_URL = 'login'
137
-LOGIN_REDIRECT_URL = 'home'
118
+#login
119
+LOGIN_URL = reverse_lazy('login')
120
+LOGIN_REDIRECT_URL = reverse_lazy('home')