Explorar o código

Password recoevery and change

Denis Merigoux %!s(int64=9) %!d(string=hai) anos
pai
achega
609ddd6b07

+ 1 - 0
counter/templates/homeTemplate.html

131
 </div>
131
 </div>
132
 <div class="row text-center">
132
 <div class="row text-center">
133
 		<a href="{% url 'logout' %}" class="btn btn-danger">Se déconnecter</a>
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
 </div>
135
 </div>
135
 {% endblock %}
136
 {% endblock %}

+ 3 - 2
counter/templates/login.html

15
                     {% csrf_token %}
15
                     {% csrf_token %}
16
                     <div class="form-group">
16
                     <div class="form-group">
17
                         <label for="id_username">Trigramme</label>
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
                     </div>
19
                     </div>
20
                     <div class="form-group">
20
                     <div class="form-group">
21
                         <label for="id_username">Mot de passe</label>
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
                     </div>
23
                     </div>
24
                     <input type="hidden" name="next" value="{{ next }}" />
24
                     <input type="hidden" name="next" value="{{ next }}" />
25
                     <div class="text-center">
25
                     <div class="text-center">
26
                         <button type="submit" class="btn btn-default btn-success">Se connecter</button>
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
                     </div>
28
                     </div>
28
                 </form>
29
                 </form>
29
             </div>
30
             </div>

+ 48 - 0
counter/templates/passwordChange.html

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

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

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

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

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

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

1
+[SeumBook] Réinitialisation du mot de passe

+ 27 - 7
counter/urls.py

1
 from django.conf.urls import url
1
 from django.conf.urls import url
2
 from counter.rss import SeumFeed
2
 from counter.rss import SeumFeed
3
 from django.contrib.auth import views as auth_views
3
 from django.contrib.auth import views as auth_views
4
+from django.views.generic.base import RedirectView
4
 
5
 
5
 from . import views
6
 from . import views
6
 
7
 
7
 urlpatterns = [
8
 urlpatterns = [
8
     url(r'^$', views.home, name="home"),
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
         {'template_name': 'login.html'},
14
         {'template_name': 'login.html'},
14
         name="login"),
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
 from django.http import HttpResponseRedirect
6
 from django.http import HttpResponseRedirect
7
 from django.core.mail import EmailMessage
7
 from django.core.mail import EmailMessage
8
 from django.contrib.auth.decorators import login_required
8
 from django.contrib.auth.decorators import login_required
9
+from django.core.urlresolvers import reverse
9
 from graphos.renderers import gchart
10
 from graphos.renderers import gchart
10
 from graphos.sources.simple import SimpleDataSource
11
 from graphos.sources.simple import SimpleDataSource
11
 from graphos.sources.model import ModelDataSource
12
 from graphos.sources.model import ModelDataSource
46
         myCounter.lastReset.formatted_delta = format_timedelta(
47
         myCounter.lastReset.formatted_delta = format_timedelta(
47
             myCounter.lastReset.delta, locale='fr', threshold=1)
48
             myCounter.lastReset.delta, locale='fr', threshold=1)
48
     except Counter.DoesNotExist:
49
     except Counter.DoesNotExist:
49
-        return HttpResponseRedirect('login')
50
+        return HttpResponseRedirect(reverse('login'))
50
 
51
 
51
     # Building data for counters display
52
     # Building data for counters display
52
     counters = Counter.objects.all()
53
     counters = Counter.objects.all()

+ 4 - 21
seum/settings.py.default

11
 """
11
 """
12
 
12
 
13
 import os
13
 import os
14
+from django.core.urlresolvers import reverse_lazy
14
 
15
 
15
 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16
 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
16
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
17
 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
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
 # Internationalization
90
 # Internationalization
109
 # https://docs.djangoproject.com/en/1.9/topics/i18n/
91
 # https://docs.djangoproject.com/en/1.9/topics/i18n/
110
 
92
 
133
 EMAIL_USE_TLS = False
115
 EMAIL_USE_TLS = False
134
 DEFAULT_FROM_EMAIL = 'SeumMan <seum@merigoux.ovh>'
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')