Browse Source

Closes #92: Ensure and test webdav digest is updated when create or update password

Bastien Sevajol (Algoo) 8 years ago
parent
commit
bee69c2d86

+ 2 - 0
tracim/tracim/command/user.py View File

@@ -106,6 +106,7 @@ class UserCommand(AppContextCommand):
106 106
 
107 107
         try:
108 108
             user = User(email=login, password=password, **kwargs)
109
+            user.update_webdav_digest_auth(password)
109 110
             self._session.add(user)
110 111
             self._session.flush()
111 112
         except IntegrityError:
@@ -117,6 +118,7 @@ class UserCommand(AppContextCommand):
117 118
     def _update_password_for_login(self, login, password):
118 119
         user = self._user_api.get_one_by_email(login)
119 120
         user.password = password
121
+        user.update_webdav_digest_auth(password)
120 122
         self._session.flush()
121 123
         transaction.commit()
122 124
 

+ 1 - 0
tracim/tracim/controllers/admin/user.py View File

@@ -210,6 +210,7 @@ class UserPasswordAdminRestController(TIMRestController):
210 210
             tg.redirect(next_url)
211 211
 
212 212
         user.password = new_password1
213
+        user.update_webdav_digest_auth(new_password1)
213 214
         pm.DBSession.flush()
214 215
 
215 216
         tg.flash(_('The password has been changed'), CST.STATUS_OK)

+ 4 - 21
tracim/tracim/controllers/user.py View File

@@ -1,33 +1,16 @@
1 1
 # -*- coding: utf-8 -*-
2
-from webob.exc import HTTPForbidden
3
-
4
-from tracim import model  as pm
5 2
 
6
-from sprox.tablebase import TableBase
7
-from sprox.formbase import EditableForm, AddRecordForm
8
-from sprox.fillerbase import TableFiller, EditFormFiller
9
-from tw2 import forms as tw2f
10 3
 import tg
11 4
 from tg import tmpl_context
12
-from tg.i18n import ugettext as _, lazy_ugettext as l_
13
-
14
-from sprox.widgets import PropertyMultipleSelectField
15
-from sprox._compat import unicode_text
16
-
17
-from formencode import Schema
18
-from formencode.validators import FieldsMatch
5
+from tg.i18n import ugettext as _
6
+from webob.exc import HTTPForbidden
19 7
 
20 8
 from tracim.controllers import TIMRestController
21
-from tracim.lib import helpers as h
22 9
 from tracim.lib.user import UserApi
23
-from tracim.lib.group import GroupApi
24
-from tracim.lib.user import UserStaticApi
25
-from tracim.lib.userworkspace import RoleApi
26 10
 from tracim.lib.workspace import WorkspaceApi
27 11
 
28
-from tracim.model import DBSession
29
-from tracim.model.auth import Group, User
30 12
 from tracim.model.serializers import Context, CTX, DictLikeClass
13
+from tracim import model as pm
31 14
 
32 15
 
33 16
 class UserWorkspaceRestController(TIMRestController):
@@ -123,7 +106,7 @@ class UserPasswordRestController(TIMRestController):
123 106
             tg.redirect(redirect_url)
124 107
 
125 108
         current_user.password = new_password1
126
-        current_user.webdav_left_digest_response_hash = '%s:/:%s' % (current_user.email, new_password1)
109
+        current_user.update_webdav_digest_auth(new_password1)
127 110
         pm.DBSession.flush()
128 111
 
129 112
         tg.flash(_('Your password has been changed'))

+ 8 - 1
tracim/tracim/model/auth.py View File

@@ -14,7 +14,6 @@ import os
14 14
 from datetime import datetime
15 15
 import time
16 16
 from hashlib import sha256
17
-from slugify import slugify
18 17
 from sqlalchemy.ext.hybrid import hybrid_property
19 18
 from tg.i18n import lazy_ugettext as l_
20 19
 from hashlib import md5
@@ -218,6 +217,14 @@ class User(DeclarativeBase):
218 217
                                                descriptor=property(_get_hash_digest,
219 218
                                                                     _set_hash_digest))
220 219
 
220
+    def update_webdav_digest_auth(self, password) -> None:
221
+        self.webdav_left_digest_response_hash \
222
+            = '{username}:/:{password}'.format(
223
+                username=self.email,
224
+                password=password,
225
+            )
226
+
227
+
221 228
     def validate_password(self, password):
222 229
         """
223 230
         Check the password against existing credentials.

+ 20 - 2
tracim/tracim/tests/command/user.py View File

@@ -11,16 +11,34 @@ class TestUserCommand(TestCommand):
11 11
 
12 12
     def test_create(self):
13 13
         self._create_user('new-user@algoo.fr', 'toor')
14
+        # Check webdav digest exist for this user
15
+        user = DBSession.query(User)\
16
+            .filter(User.email == 'new-user@algoo.fr').one()
17
+        ok_(user.webdav_left_digest_response_hash)
14 18
 
15 19
     def test_update_password(self):
16 20
         self._create_user('new-user@algoo.fr', 'toor')
21
+
22
+        # Grab webdav digest
23
+        user = DBSession.query(User) \
24
+            .filter(User.email == 'new-user@algoo.fr').one()
25
+        webdav_digest = user.webdav_left_digest_response_hash
26
+
17 27
         self._execute_command(
18
-            CreateUserCommand,
28
+            UpdateUserCommand,
19 29
             'gearbox user update',
20 30
             ['-l', 'new-user@algoo.fr', '-p', 'new_password']
21 31
         )
22 32
         user = DBSession.query(User).filter(User.email == 'new-user@algoo.fr').one()
23
-        user.validate_password('new_password')
33
+        ok_(user.validate_password('new_password'))
34
+
35
+        # Grab new webdav digest to compare it
36
+        user = DBSession.query(User) \
37
+            .filter(User.email == 'new-user@algoo.fr').one()
38
+        ok_(
39
+            webdav_digest != user.webdav_left_digest_response_hash,
40
+            msg='Webdav digest should be different',
41
+        )
24 42
 
25 43
     def test_create_with_group(self):
26 44
         more_args = ['--add-to-group', 'managers', '--add-to-group', 'administrators']

+ 88 - 0
tracim/tracim/tests/functional/test_admin.py View File

@@ -0,0 +1,88 @@
1
+# -*- coding: utf-8 -*-
2
+from collections import OrderedDict
3
+
4
+from nose.tools import eq_
5
+from nose.tools import ok_
6
+
7
+from tracim.model import DBSession
8
+from tracim.model import User
9
+from tracim.tests import TracimTestController
10
+
11
+
12
+class TestAuthentication(TracimTestController):
13
+    application_under_test = 'main'
14
+
15
+    def test_create_user(self):
16
+        self._connect_user(
17
+            'admin@admin.admin',
18
+            'admin@admin.admin',
19
+        )
20
+
21
+        user_count = DBSession.query(User) \
22
+            .filter(User.email == 'an-other-email@test.local').count()
23
+        eq_(0, user_count, 'User should not exist yet')
24
+
25
+        # Create a new user
26
+        try_post_user = self.app.post(
27
+            '/admin/users',
28
+            OrderedDict([
29
+                ('name', 'TEST'),
30
+                ('email', 'an-other-email@test.local'),
31
+                ('password', 'password'),
32
+                ('is_tracim_manager', 'off'),
33
+                ('is_tracim_admin', 'off'),
34
+                ('send_email', 'off'),
35
+            ])
36
+        )
37
+
38
+        eq_(try_post_user.status_code, 302,
39
+            "Code should be 302, but is %d" % try_post_user.status_code)
40
+
41
+        user = DBSession.query(User) \
42
+            .filter(User.email == 'an-other-email@test.local').one()
43
+        ok_(user, msg="User should exist now")
44
+        ok_(user.validate_password('password'))
45
+
46
+        # User must have webdav digest
47
+        ok_(user.webdav_left_digest_response_hash)
48
+
49
+    def test_update_user_password(self):
50
+        self._connect_user(
51
+            'admin@admin.admin',
52
+            'admin@admin.admin',
53
+        )
54
+
55
+        # Create a new user (tested in test_create_user)
56
+        self.app.post(
57
+            '/admin/users',
58
+            OrderedDict([
59
+                ('name', 'TEST'),
60
+                ('email', 'an-other-email@test.local'),
61
+                ('password', 'an-other-email@test.local'),
62
+                ('is_tracim_manager', 'off'),
63
+                ('is_tracim_admin', 'off'),
64
+                ('send_email', 'off'),
65
+            ])
66
+        )
67
+
68
+        user = DBSession.query(User) \
69
+            .filter(User.email == 'an-other-email@test.local').one()
70
+        webdav_digest = user.webdav_left_digest_response_hash
71
+
72
+        self.app.post(
73
+            '/admin/users/{user_id}/password?_method=PUT'.format(
74
+                user_id=user.user_id
75
+            ),
76
+            OrderedDict([
77
+                ('new_password1', 'new-password'),
78
+                ('new_password2', 'new-password'),
79
+            ])
80
+        )
81
+
82
+        user = DBSession.query(User) \
83
+            .filter(User.email == 'an-other-email@test.local').one()
84
+        ok_(user.validate_password('new-password'))
85
+        ok_(
86
+            webdav_digest != user.webdav_left_digest_response_hash,
87
+            msg='Webdav digest should be updated',
88
+        )

+ 46 - 0
tracim/tracim/tests/functional/test_user.py View File

@@ -0,0 +1,46 @@
1
+# -*- coding: utf-8 -*-
2
+from collections import OrderedDict
3
+
4
+from nose.tools import eq_
5
+from nose.tools import ok_
6
+
7
+from tracim.model import DBSession
8
+from tracim.model import User
9
+from tracim.tests import TracimTestController
10
+from tracim.fixtures.users_and_groups import Test as TestFixture
11
+
12
+
13
+class TestAuthentication(TracimTestController):
14
+    application_under_test = 'main'
15
+    fixtures = [TestFixture]
16
+
17
+    def test_update_password(self):
18
+        self._connect_user(
19
+            'lawrence-not-real-email@fsf.local',
20
+            'foobarbaz',
21
+        )
22
+
23
+        user = DBSession.query(User) \
24
+            .filter(User.email == 'lawrence-not-real-email@fsf.local').one()
25
+        webdav_digest = user.webdav_left_digest_response_hash
26
+
27
+        try_post_user = self.app.post(
28
+            '/user/{user_id}/password?_method=PUT'.format(
29
+                user_id=user.user_id
30
+            ),
31
+            OrderedDict([
32
+                ('current_password', 'foobarbaz'),
33
+                ('new_password1', 'new-password'),
34
+                ('new_password2', 'new-password'),
35
+            ])
36
+        )
37
+        eq_(try_post_user.status_code, 302,
38
+            "Code should be 302, but is %d" % try_post_user.status_code)
39
+
40
+        user = DBSession.query(User) \
41
+            .filter(User.email == 'lawrence-not-real-email@fsf.local').one()
42
+        ok_(user.validate_password('new-password'))
43
+        ok_(
44
+            webdav_digest != user.webdav_left_digest_response_hash,
45
+            msg='Webdav digest should be updated',
46
+        )