Browse Source

tested backend credentials change

Rafał Pitoń 9 years ago
parent
commit
73c16f3156

+ 1 - 0
misago/templates/misago/options/credentials_error.html

@@ -16,6 +16,7 @@
 
       <div class="message-body">
         <p class="lead">{% trans "Change confirmation link is invalid." %}</p>
+        <p>{% trans "The confirmation link belongs to other user, was already used, or has expired." %}</p>
         <p>
           <a href="{% url 'misago:options_form' form_name='sign-in-credentials' %}">
             Request another activation link.

+ 1 - 1
misago/users/tests/test_decorators.py

@@ -24,7 +24,7 @@ class DenyGuestsTests(UserTestCase):
         self.login_user(self.get_authenticated_user())
 
         response = self.client.post(reverse('misago:options'))
-        self.assertEqual(response.status_code, 302)
+        self.assertEqual(response.status_code, 200)
 
     def test_fail(self):
         """deny_guests decorator blocked guest request"""

+ 78 - 2
misago/users/tests/test_options_views.py

@@ -1,3 +1,4 @@
+from django.core import mail
 from django.core.urlresolvers import reverse
 from misago.users.testutils import AuthenticatedUserTestCase
 
@@ -6,11 +7,86 @@ class OptionsViewsTests(AuthenticatedUserTestCase):
     def test_lander_view_returns_200(self):
         """/options has no show stoppers"""
         response = self.client.get(reverse('misago:options'))
-        self.assertEqual(response.status_code, 302)
+        self.assertEqual(response.status_code, 200)
 
     def test_form_view_returns_200(self):
         """/options/some-form has no show stoppers"""
         response = self.client.get(reverse('misago:options_form', kwargs={
             'form_name': 'some-fake-form'
         }))
-        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.status_code, 200)
+
+
+class ConfirmChangeEmailTests(AuthenticatedUserTestCase):
+    def setUp(self):
+        super(ConfirmChangeEmailTests, self).setUp()
+        link = '/api/users/%s/change-email/' % self.user.pk
+
+        response = self.client.post(link, data={
+            'new_email': 'n3w@email.com',
+            'password': self.USER_PASSWORD
+        })
+        self.assertEqual(response.status_code, 200)
+
+        for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
+            if line.startswith('http://'):
+                self.link = line.strip()
+                break
+
+    def test_invalid_token(self):
+        """invalid token is rejected"""
+        response = self.client.get(
+            reverse('misago:options_confirm_email_change', kwargs={
+                'token': 'invalid'
+            }))
+
+        self.assertEqual(response.status_code, 400)
+        self.assertIn("Change confirmation link is invalid.", response.content)
+
+    def test_change_email(self):
+        """valid token changes email"""
+        response = self.client.get(self.link)
+
+        self.assertEqual(response.status_code, 200)
+        self.assertIn("your e-mail has been changed", response.content)
+
+        self.reload_user()
+        self.assertEqual(self.user.email, 'n3w@email.com')
+
+
+class ConfirmChangePasswordTests(AuthenticatedUserTestCase):
+    def setUp(self):
+        super(ConfirmChangePasswordTests, self).setUp()
+        link = '/api/users/%s/change-password/' % self.user.pk
+
+        response = self.client.post(link, data={
+            'new_password': 'n3wp4ssword',
+            'password': self.USER_PASSWORD
+        })
+        self.assertEqual(response.status_code, 200)
+
+        for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
+            if line.startswith('http://'):
+                self.link = line.strip()
+                break
+
+    def test_invalid_token(self):
+        """invalid token is rejected"""
+        response = self.client.get(
+            reverse('misago:options_confirm_password_change', kwargs={
+                'token': 'invalid'
+            }))
+
+        self.assertEqual(response.status_code, 400)
+        self.assertIn("Change confirmation link is invalid.", response.content)
+
+    def test_change_password(self):
+        """valid token changes password"""
+        response = self.client.get(self.link)
+
+        self.assertEqual(response.status_code, 200)
+        self.assertIn("your password has been changed", response.content)
+
+        self.reload_user()
+        self.assertFalse(self.user.check_password(self.USER_PASSWORD))
+        self.assertTrue(self.user.check_password('n3wp4ssword'))

+ 0 - 45
misago/users/tests/test_user_changeemail_api.py

@@ -32,12 +32,6 @@ class UserChangeEmailTests(AuthenticatedUserTestCase):
         else:
             self.fail("E-mail sent didn't contain confirmation url")
 
-        response = self.client.post(self.link, data={'token': token})
-        self.assertEqual(response.status_code, 200)
-
-        self.reload_user()
-        self.assertEqual(self.user.email, 'new@email.com')
-
     def test_invalid_password(self):
         """api errors correctly for invalid password"""
         response = self.client.post(self.link, data={
@@ -74,42 +68,3 @@ class UserChangeEmailTests(AuthenticatedUserTestCase):
         })
         self.assertEqual(response.status_code, 400)
         self.assertIn('not available', response.content)
-
-    def test_invalid_token(self):
-        """api handles invalid token"""
-        response = self.client.post(self.link, data={
-            'new_email': 'new@email.com',
-            'password': self.USER_PASSWORD
-        })
-        self.assertEqual(response.status_code, 200)
-
-        response = self.client.post(self.link, data={'token': 'invalid-token'})
-        self.assertEqual(response.status_code, 400)
-
-        self.reload_user()
-        self.assertTrue(self.user.email != 'new@email.com')
-
-    def test_expired_token(self):
-        """api handles invalid token"""
-        response = self.client.post(self.link, data={
-            'new_email': 'new@email.com',
-            'password': self.USER_PASSWORD
-        })
-        self.assertEqual(response.status_code, 200)
-
-        for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
-            if line.startswith('http://'):
-                token = line.rstrip('/').split('/')[-1]
-                break
-        else:
-            self.fail("E-mail sent didn't contain confirmation url")
-
-        self.user.set_password('L0lN0p3!')
-        self.user.save()
-        self.login_user(self.user, 'L0lN0p3!')
-
-        response = self.client.post(self.link, data={'token': 'invalid-token'})
-        self.assertEqual(response.status_code, 400)
-
-        self.reload_user()
-        self.assertTrue(self.user.email != 'new@email.com')

+ 0 - 44
misago/users/tests/test_user_changepassword_api.py

@@ -32,12 +32,6 @@ class UserChangePasswordTests(AuthenticatedUserTestCase):
         else:
             self.fail("E-mail sent didn't contain confirmation url")
 
-        response = self.client.post(self.link, data={'token': token})
-        self.assertEqual(response.status_code, 200)
-
-        self.reload_user()
-        self.assertTrue(self.user.check_password('N3wP@55w0rd'))
-
     def test_invalid_password(self):
         """api errors correctly for invalid password"""
         response = self.client.post(self.link, data={
@@ -63,41 +57,3 @@ class UserChangePasswordTests(AuthenticatedUserTestCase):
         })
         self.assertEqual(response.status_code, 400)
         self.assertIn('password must be', response.content)
-
-    def test_invalid_token(self):
-        """api handles invalid token"""
-        response = self.client.post(self.link, data={
-            'new_password': 'N3wP@55w0rd',
-            'password': self.USER_PASSWORD
-        })
-        self.assertEqual(response.status_code, 200)
-
-        response = self.client.post(self.link, data={'token': 'invalid-token'})
-        self.assertEqual(response.status_code, 400)
-
-        self.reload_user()
-        self.assertFalse(self.user.check_password('N3wP@55w0rd'))
-
-    def test_expired_token(self):
-        """api handles invalid token"""
-        response = self.client.post(self.link, data={
-            'new_password': 'N3wP@55w0rd',
-            'password': self.USER_PASSWORD
-        })
-        self.assertEqual(response.status_code, 200)
-
-        for line in [l.strip() for l in mail.outbox[0].body.splitlines()]:
-            if line.startswith('http://'):
-                token = line.rstrip('/').split('/')[-1]
-                break
-        else:
-            self.fail("E-mail sent didn't contain confirmation url")
-
-        self.user.set_email('new@email.com')
-        self.user.save()
-
-        response = self.client.post(self.link, data={'token': 'invalid-token'})
-        self.assertEqual(response.status_code, 400)
-
-        self.reload_user()
-        self.assertFalse(self.user.check_password('N3wP@55w0rd'))

+ 15 - 13
misago/users/views/options.py

@@ -1,7 +1,10 @@
+from django.contrib.auth import update_session_auth_hash
 from django.core.urlresolvers import reverse
+from django.db import IntegrityError
 from django.shortcuts import render
 from django.utils.translation import ugettext as _
 
+from misago.users.credentialchange import read_new_credential
 from misago.users.decorators import deny_guests
 
 
@@ -42,41 +45,40 @@ def confirm_change_view(f):
         try:
             return f(request, token)
         except ChangeError as e:
-            return render(request, 'misago/options/credentials_error.html', {
-                'message': e.args[0],
-            }, status=400)
+            return render(request, 'misago/options/credentials_error.html',
+                status=400)
     return decorator
 
 
 @confirm_change_view
 def confirm_email_change(request, token):
-    new_credentials = get_new_credentials(request.user, token)
-    if not (new_credentials and new_credentials.get('email')):
-        raise ChangeError(_("Confirmation link is invalid."))
+    new_credential = read_new_credential(request, 'email', token)
+    if not new_credential:
+        raise ChangeError()
 
     try:
-        request.user.set_email(new_credentials['email'])
-        request.user.save(update_fields=['email', 'email_hash']])
+        request.user.set_email(new_credential)
+        request.user.save(update_fields=['email', 'email_hash'])
     except IntegrityError:
         raise ChangeError()
 
     message = _("%(user)s, your e-mail has been changed.")
     return render(request, 'misago/options/credentials_changed.html', {
-            'message': message % {'user': inactive_user.username},
+            'message': message % {'user': request.user.username},
         })
 
 
 @confirm_change_view
 def confirm_password_change(request, token):
-    new_credentials = get_new_credentials(request.user, token)
-    if not (new_credentials and new_credentials.get('password')):
+    new_credential = read_new_credential(request, 'password', token)
+    if not new_credential:
         raise ChangeError()
 
-    request.user.password = new_credentials['password']
+    request.user.set_password(new_credential)
     update_session_auth_hash(request, request.user)
     request.user.save(update_fields=['password'])
 
     message = _("%(user)s, your password has been changed.")
     return render(request, 'misago/options/credentials_changed.html', {
-            'message': message % {'user': inactive_user.username},
+            'message': message % {'user': request.user.username},
         })