You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by je...@apache.org on 2014/07/31 16:46:49 UTC

git commit: [#7585] ticket:624 Require password entry for changes to email settings

Repository: allura
Updated Branches:
  refs/heads/je/42cc_7585 [created] b16a60cfb


[#7585] ticket:624 Require password entry for changes to email settings


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/b16a60cf
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/b16a60cf
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/b16a60cf

Branch: refs/heads/je/42cc_7585
Commit: b16a60cfb77e6240c1b6fdb494ea4ac7ce077656
Parents: 84b1a1a
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 31 17:09:23 2014 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Jul 31 17:09:23 2014 +0300

----------------------------------------------------------------------
 Allura/allura/controllers/auth.py           | 10 ++++
 Allura/allura/templates/user_prefs.html     |  4 ++
 Allura/allura/tests/functional/test_auth.py | 71 ++++++++++++++++++++++++
 3 files changed, 85 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b16a60cf/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index 801bdf2..f05a0cc 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -413,6 +413,7 @@ class PreferencesController(BaseController):
             if not preferences.get('display_name'):
                 flash("Display Name cannot be empty.", 'error')
                 redirect('.')
+            provider = plugin.AuthenticationProvider.get(request)
             old = c.user.get_pref('display_name')
             c.user.set_pref('display_name', preferences['display_name'])
             if old != preferences['display_name']:
@@ -420,6 +421,9 @@ class PreferencesController(BaseController):
             for i, (old_a, data) in enumerate(zip(c.user.email_addresses, addr or [])):
                 obj = c.user.address_object(old_a)
                 if data.get('delete') or not obj:
+                    if not kw.get('password') or not provider.validate_password(c.user, kw.get('password')):
+                        flash('You must provide your current password to delete an email', 'error')
+                        redirect('.')
                     if primary_addr == c.user.email_addresses[i]:
                         if select_new_primary_addr(c.user, ignore_emails=primary_addr) is None \
                                 and asbool(config.get('auth.require_email_addr', False)):
@@ -434,6 +438,9 @@ class PreferencesController(BaseController):
                     if obj:
                         obj.delete()
             if new_addr.get('claim') or new_addr.get('addr'):
+                if not kw.get('password') or not provider.validate_password(c.user, kw.get('password')):
+                    flash('You must provide your current password to claim new email', 'error')
+                    redirect('.')
                 if M.EmailAddress.query.get(_id=new_addr['addr']):
                     flash('Email address already claimed', 'error')
                 elif mail_util.isvalid(new_addr['addr']):
@@ -449,6 +456,9 @@ class PreferencesController(BaseController):
                 primary_addr = select_new_primary_addr(c.user)
             if primary_addr:
                 if c.user.get_pref('email_address') != primary_addr:
+                    if not kw.get('password') or not provider.validate_password(c.user, kw.get('password')):
+                        flash('You must provide your current password to change primary address', 'error')
+                        redirect('.')
                     M.AuditLog.log_user(
                         'Primary email changed: %s => %s',
                         c.user.get_pref('email_address'),

http://git-wip-us.apache.org/repos/asf/allura/blob/b16a60cf/Allura/allura/templates/user_prefs.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/user_prefs.html b/Allura/allura/templates/user_prefs.html
index d921889..f76e9d6 100644
--- a/Allura/allura/templates/user_prefs.html
+++ b/Allura/allura/templates/user_prefs.html
@@ -108,6 +108,10 @@
           </table>
           <div class="grid-22">
             <p></p>
+            <label for="password">Current password:</label>
+            <input type="password" name="password">
+          </div>
+          <div class="grid-22">
             {{lib.submit_button('Save')}}
           </div>
           {{lib.csrf_token()}}

http://git-wip-us.apache.org/repos/asf/allura/blob/b16a60cf/Allura/allura/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index 58d824a..8af23ca 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -132,6 +132,7 @@ class TestAuth(TestController):
                 'new_addr.addr': 'test@example.com',
                 'new_addr.claim': 'Claim Address',
                 'primary_addr': 'test-admin@users.localhost',
+                'password': 'foo',
                 'preferences.email_format': 'plain'},
                 extra_environ=dict(username='test-admin'))
         r = self.app.get('/auth/preferences/')
@@ -148,6 +149,7 @@ class TestAuth(TestController):
                 'addr-2.ord': '2',
                 'new_addr.addr': '',
                 'primary_addr': 'test-admin@users.localhost',
+                'password': 'foo',
                 'preferences.email_format': 'plain'},
                 extra_environ=dict(username='test-admin'))
         r = self.app.get('/auth/preferences/')
@@ -163,6 +165,75 @@ class TestAuth(TestController):
                 extra_environ=dict(username='test-admin'))
 
     @td.with_user_project('test-admin')
+    def test_email_prefs_change_requires_password(self):
+        # Claim new email
+        new_email_params = {
+            'preferences.display_name': 'Test Admin',
+            'new_addr.addr': 'test@example.com',
+            'new_addr.claim': 'Claim Address',
+            'primary_addr': 'test-admin@users.localhost',
+        }
+        r = self.app.post('/auth/preferences/update', params=new_email_params,
+            extra_environ=dict(username='test-admin'))
+        assert_in('You must provide your current password to claim new email', self.webflash(r))
+        assert_not_in('test@example.com', r.follow())
+        new_email_params['password'] = 'bad pass'
+        r = self.app.post('/auth/preferences/update', params=new_email_params,
+            extra_environ=dict(username='test-admin'))
+        assert_in('You must provide your current password to claim new email', self.webflash(r))
+        assert_not_in('test@example.com', r.follow())
+        new_email_params['password'] = 'foo'  # valid password
+        r = self.app.post('/auth/preferences/update', params=new_email_params,
+            extra_environ=dict(username='test-admin'))
+        assert_not_in('You must provide your current password to claim new email', self.webflash(r))
+        assert_in('test@example.com', r.follow())
+
+        # Change primary address
+        change_primary_params = {
+            'preferences.display_name': 'Test Admin',
+            'new_addr.addr': '',
+            'primary_addr': 'test@example.com',
+        }
+        r = self.app.post('/auth/preferences/update', params=change_primary_params,
+            extra_environ=dict(username='test-admin'))
+        assert_in('You must provide your current password to change primary address', self.webflash(r))
+        assert_equal(M.User.by_username('test-admin').get_pref('email_address'), 'test-admin@users.localhost')
+        change_primary_params['password'] = 'bad pass'
+        r = self.app.post('/auth/preferences/update', params=change_primary_params,
+            extra_environ=dict(username='test-admin'))
+        assert_in('You must provide your current password to change primary address', self.webflash(r))
+        assert_equal(M.User.by_username('test-admin').get_pref('email_address'), 'test-admin@users.localhost')
+        change_primary_params['password'] = 'foo'  # valid password
+        r = self.app.post('/auth/preferences/update', params=change_primary_params,
+            extra_environ=dict(username='test-admin'))
+        assert_not_in('You must provide your current password to change primary address', self.webflash(r))
+        assert_equal(M.User.by_username('test-admin').get_pref('email_address'), 'test@example.com')
+
+        # Remove email
+        remove_email_params = {
+            'preferences.display_name': 'Test Admin',
+            'addr-1.ord': '1',
+            'addr-2.ord': '2',
+            'addr-2.delete': 'on',
+            'new_addr.addr': '',
+            'primary_addr': 'test-admin@users.localhost',
+        }
+        r = self.app.post('/auth/preferences/update', params=remove_email_params,
+            extra_environ=dict(username='test-admin'))
+        assert_in('You must provide your current password to delete an email', self.webflash(r))
+        assert_in('test@example.com', r.follow())
+        remove_email_params['password'] = 'bad pass'
+        r = self.app.post('/auth/preferences/update', params=remove_email_params,
+            extra_environ=dict(username='test-admin'))
+        assert_in('You must provide your current password to delete an email', self.webflash(r))
+        assert_in('test@example.com', r.follow())
+        remove_email_params['password'] = 'foo'  # vallid password
+        r = self.app.post('/auth/preferences/update', params=remove_email_params,
+            extra_environ=dict(username='test-admin'))
+        assert_not_in('You must provide your current password to delete an email', self.webflash(r))
+        assert_not_in('test@example.com', r.follow())
+
+    @td.with_user_project('test-admin')
     def test_prefs_subscriptions(self):
         r = self.app.get('/auth/subscriptions/',
                          extra_environ=dict(username='test-admin'))