Kaynağa Gözat

Fix broken URL regex for resetting password

With complete webtest for password resetting story.
master
David Winterbottom 13 yıl önce
ebeveyn
işleme
64a3e4e74d

+ 6
- 4
oscar/app.py Dosyayı Görüntüle

@@ -14,7 +14,7 @@ from oscar.apps.dashboard.app import application as dashboard_app
14 14
 
15 15
 class Shop(Application):
16 16
     name = None
17
-    
17
+
18 18
     catalogue_app = catalogue_app
19 19
     customer_app = customer_app
20 20
     basket_app = basket_app
@@ -23,7 +23,7 @@ class Shop(Application):
23 23
     search_app = search_app
24 24
     dashboard_app = dashboard_app
25 25
     offer_app = offer_app
26
-    
26
+
27 27
     def get_urls(self):
28 28
         urlpatterns = patterns('',
29 29
             (r'^products/', include(self.catalogue_app.urls)),
@@ -39,12 +39,14 @@ class Shop(Application):
39 39
             # from working.
40 40
             url(r'^password-reset/$', auth_views.password_reset, name='password-reset'),
41 41
             url(r'^password-reset/done/$', auth_views.password_reset_done, name='password-reset-done'),
42
-            url(r'^password-reset/confirm/$', auth_views.password_reset_confirm, name='password-reset-confirm'),
42
+            url(r'^password-reset/confirm/(?P<uidb36>[0-9A-Za-z]{1,13})-(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
43
+                auth_views.password_reset_confirm, name='password-reset-confirm'),
43 44
             url(r'^password-reset/complete/$', auth_views.password_reset_complete, name='password-reset-complete'),
44 45
 
45 46
             (r'', include(self.promotions_app.urls)),
46 47
         )
47 48
         return urlpatterns
48
-    
49
+
50
+
49 51
 # 'shop' kept for legacy projects - 'application' is a better name
50 52
 shop = application = Shop()

+ 1
- 0
oscar/templates/oscar/customer/login_registration.html Dosyayı Görüntüle

@@ -24,6 +24,7 @@
24 24
             <h2>{% trans 'Log In' %}</h2>
25 25
             {% csrf_token %}
26 26
             {% include "partials/form_fields.html" with form=login_form %}
27
+			<p><a href="{% url password-reset %}">{% trans "I've forgotten my password" %}</a></p>
27 28
             <button name="login_submit" type="submit" value="Log In" class="btn btn-large btn-primary">{% trans 'Log In' %}</button>
28 29
         </form>
29 30
     </div>

+ 1
- 1
oscar/templates/oscar/dashboard/layout.html Dosyayı Görüntüle

@@ -8,7 +8,7 @@
8 8
 	<link rel="stylesheet" href="{{ STATIC_URL }}oscar/css/dashboard.css" />
9 9
 {% endblock %}
10 10
 
11
-{% block extrahead %} {%endblock extrahead %}
11
+{% block extrahead %} {% endblock extrahead %}
12 12
 
13 13
 {% block title %}
14 14
 {% trans "Dashboard" %} | {{ block.super }}

+ 1
- 1
oscar/templates/oscar/layout.html Dosyayı Görüntüle

@@ -18,7 +18,7 @@
18 18
             {% include "partials/nav_primary.html" %}
19 19
         {% endblock %}
20 20
     </header>
21
-    <div class="container-fluid page">
21
+	<div class="container-fluid page">
22 22
         {% block header %}{% endblock %}
23 23
         <div class="page_inner">
24 24
             {% block breadcrumbs %}{% endblock %}

+ 11
- 1
oscar/templates/oscar/registration/password_reset_complete.html Dosyayı Görüntüle

@@ -3,8 +3,18 @@
3 3
 
4 4
 {% block title %}{% trans 'Password reset complete' %} | {{ block.super }}{% endblock %}
5 5
 
6
+{% block breadcrumbs %}
7
+<ul class="breadcrumb">
8
+    <li>
9
+        <a href="{% url promotions:home %}">{% trans 'Home' %}</a>
10
+        <span class="divider">/</span>
11
+    </li>
12
+	<li class="active"><a href=".">{% trans 'Password reset complete' %}</a></li>
13
+</ul>
14
+{% endblock %}
15
+
6 16
 {% block content %}
7 17
 	<h1>{% trans 'Password reset complete' %}</h1>
8 18
 	<p>{% trans "Your password has been set.  You may go ahead and log in now." %}</p>
9
-	<p><a href="{{ login_url }}">{% trans 'Log in' %}</a></p>
19
+	<p><a href="{{ login_url }}" class="btn btn-large btn-primary">{% trans 'Log in' %}</a></p>
10 20
 {% endblock %}

+ 12
- 2
oscar/templates/oscar/registration/password_reset_confirm.html Dosyayı Görüntüle

@@ -3,6 +3,16 @@
3 3
 
4 4
 {% block title %}{% trans 'Password reset confirm' %} | {{ block.super }}{% endblock %}
5 5
 
6
+{% block breadcrumbs %}
7
+<ul class="breadcrumb">
8
+    <li>
9
+        <a href="{% url promotions:home %}">{% trans 'Home' %}</a>
10
+        <span class="divider">/</span>
11
+    </li>
12
+	<li class="active"><a href=".">{% trans 'Enter new password' %}</a></li>
13
+</ul>
14
+{% endblock %}
15
+
6 16
 {% block content %}
7 17
 
8 18
 {% if validlink %}
@@ -11,12 +21,12 @@
11 21
 
12 22
 <p>{% trans "Please enter your new password twice so we can verify you typed it in correctly." %}</p>
13 23
 
14
-<form action="" method="post">{% csrf_token %}
24
+<form id="password_reset_form" action="" method="post">{% csrf_token %}
15 25
 {{ form.new_password1.errors }}
16 26
 <p class="aligned wide"><label for="id_new_password1">{% trans 'New password:' %}</label>{{ form.new_password1 }}</p>
17 27
 {{ form.new_password2.errors }}
18 28
 <p class="aligned wide"><label for="id_new_password2">{% trans 'Confirm password:' %}</label>{{ form.new_password2 }}</p>
19
-<p><input type="submit" value="{% trans 'Change my password' %}" /></p>
29
+<p><button class="btn btn-primary btn-large" type="submit">{% trans 'Change my password' %}</button></p>
20 30
 </form>
21 31
 
22 32
 {% else %}

+ 10
- 0
oscar/templates/oscar/registration/password_reset_done.html Dosyayı Görüntüle

@@ -3,6 +3,16 @@
3 3
 
4 4
 {% block title %}{% trans 'Password reset successful' %} | {{ block.super }}{% endblock %}
5 5
 
6
+{% block breadcrumbs %}
7
+<ul class="breadcrumb">
8
+    <li>
9
+        <a href="{% url promotions:home %}">{% trans 'Home' %}</a>
10
+        <span class="divider">/</span>
11
+    </li>
12
+	<li class="active"><a href=".">{% trans 'Password reset sent' %}</a></li>
13
+</ul>
14
+{% endblock %}
15
+
6 16
 {% block content %}
7 17
 
8 18
     <h1>{% trans 'Password reset successful' %}</h1>

+ 11
- 1
oscar/templates/oscar/registration/password_reset_form.html Dosyayı Görüntüle

@@ -3,13 +3,23 @@
3 3
 
4 4
 {% block title %}{% trans 'Password reset' %} | {{ block.super }}{% endblock %}
5 5
 
6
+{% block breadcrumbs %}
7
+<ul class="breadcrumb">
8
+    <li>
9
+        <a href="{% url promotions:home %}">{% trans 'Home' %}</a>
10
+        <span class="divider">/</span>
11
+    </li>
12
+	<li class="active"><a href=".">{% trans 'Password reset' %}</a></li>
13
+</ul>
14
+{% endblock %}
15
+
6 16
 {% block content %}
7 17
 
8 18
     <div class="sub-header">
9 19
         <h2>{% trans "Password reset" %}</h2>
10 20
     </div>
11 21
 
12
-    <form action="" method="post" class="form-stacked well">
22
+    <form id="password_reset_form" action="" method="post" class="form-stacked well">
13 23
     {% csrf_token %}
14 24
 
15 25
         <p>{% trans "Forgotten your password? Enter your e-mail address below, and we'll e-mail instructions for setting a new one." %}</p>

+ 0
- 0
tests/functional/customer/__init__.py Dosyayı Görüntüle


+ 49
- 0
tests/functional/customer/auth_tests.py Dosyayı Görüntüle

@@ -0,0 +1,49 @@
1
+import re
2
+
3
+from django.contrib.auth import models
4
+from django.core.urlresolvers import reverse
5
+from django.core import mail
6
+
7
+from django_webtest import WebTest
8
+
9
+
10
+class TestAUserWhoseForgottenHerPassword(WebTest):
11
+
12
+    def test_can_reset_her_password(self):
13
+        username, email, password = 'lucy', 'lucy@example.com', 'password'
14
+        models.User.objects.create_user(
15
+            username, email, password
16
+        )
17
+
18
+        # Fill in password reset form
19
+        page = self.app.get(reverse('password-reset'))
20
+        form = page.forms['password_reset_form']
21
+        form['email'] = email
22
+        response = form.submit()
23
+
24
+        # Response should be a redirect and an email should have been sent
25
+        self.assertEqual(302, response.status_code)
26
+        self.assertEqual(1, len(mail.outbox))
27
+
28
+        # Extract URL from email
29
+        email_body = mail.outbox[0].body
30
+        urlfinder = re.compile(r"http://example.com(?P<path>[-A-Za-z0-9\/\._]+)")
31
+        matches = urlfinder.search(email_body, re.MULTILINE)
32
+        self.assertTrue('path' in matches.groupdict())
33
+        path = matches.groupdict()['path']
34
+
35
+        # Reset password and check we get redirect
36
+        reset_page = self.app.get(path)
37
+        form = reset_page.forms['password_reset_form']
38
+        form['new_password1'] = 'monkey'
39
+        form['new_password2'] = 'monkey'
40
+        response = form.submit()
41
+        self.assertEqual(302, response.status_code)
42
+
43
+        # Now attempt to login with new password
44
+        url = reverse('customer:login')
45
+        form = self.app.get(url).forms['login_form']
46
+        form['login-username'] = email
47
+        form['login-password'] = 'monkey'
48
+        response = form.submit('login_submit')
49
+        self.assertEqual(302, response.status_code)

Loading…
İptal
Kaydet