diff --git a/seahub/settings.py b/seahub/settings.py index c32f012212..9f766cefc5 100644 --- a/seahub/settings.py +++ b/seahub/settings.py @@ -265,6 +265,9 @@ USER_PASSWORD_STRENGTH_LEVEL = 3 # when True, check password strength level, STRONG(or above) is allowed USER_STRONG_PASSWORD_REQUIRED = False +# Force user to change password when admin add/reset a user. +FORCE_PASSWORD_CHANGE = True + # Using server side crypto by default, otherwise, let user choose crypto method. FORCE_SERVER_CRYPTO = True @@ -631,6 +634,7 @@ CONSTANCE_CONFIG = { 'ENABLE_ENCRYPTED_LIBRARY': (ENABLE_ENCRYPTED_LIBRARY,''), 'REPO_PASSWORD_MIN_LENGTH': (REPO_PASSWORD_MIN_LENGTH,''), 'ENABLE_REPO_HISTORY_SETTING': (ENABLE_REPO_HISTORY_SETTING,''), + 'FORCE_PASSWORD_CHANGE': (FORCE_PASSWORD_CHANGE, ''), 'USER_STRONG_PASSWORD_REQUIRED': (USER_STRONG_PASSWORD_REQUIRED,''), 'USER_PASSWORD_MIN_LENGTH': (USER_PASSWORD_MIN_LENGTH,''), diff --git a/seahub/templates/sysadmin/settings.html b/seahub/templates/sysadmin/settings.html index 3e5e4040e3..6825b53686 100644 --- a/seahub/templates/sysadmin/settings.html +++ b/seahub/templates/sysadmin/settings.html @@ -49,6 +49,10 @@ {% include "snippets/web_settings_form.html" %} {% endwith %} + {% with type="checkbox" setting_display_name="force password change" help_tip="Force user to change password when account is newly added or reset by admin" setting_name="FORCE_PASSWORD_CHANGE" setting_val=config_dict.FORCE_PASSWORD_CHANGE %} + {% include "snippets/web_settings_form.html" %} + {% endwith %} + {% with type="input" setting_display_name="password minimum length" help_tip="The least number of characters an account password should include." setting_name="USER_PASSWORD_MIN_LENGTH" setting_val=config_dict.USER_PASSWORD_MIN_LENGTH %} {% include "snippets/web_settings_form.html" %} {% endwith %} diff --git a/seahub/views/sysadmin.py b/seahub/views/sysadmin.py index 6db1e3a8f3..58b66773aa 100644 --- a/seahub/views/sysadmin.py +++ b/seahub/views/sysadmin.py @@ -1238,7 +1238,8 @@ def user_reset(request, email): user.save() clear_token(user.username) - UserOptions.objects.set_force_passwd_change(user.username) + if config.FORCE_PASSWORD_CHANGE: + UserOptions.objects.set_force_passwd_change(user.username) if IS_EMAIL_CONFIGURED: if SEND_EMAIL_ON_RESETTING_USER_PASSWD: @@ -1311,7 +1312,8 @@ def user_add(request): if user: User.objects.update_role(email, role) - UserOptions.objects.set_force_passwd_change(email) + if config.FORCE_PASSWORD_CHANGE: + UserOptions.objects.set_force_passwd_change(email) if request.user.org: org_id = request.user.org.org_id @@ -2160,7 +2162,7 @@ def sys_settings(request): 'ENABLE_REPO_HISTORY_SETTING', 'USER_STRONG_PASSWORD_REQUIRED', 'ENABLE_ENCRYPTED_LIBRARY', 'USER_PASSWORD_MIN_LENGTH', 'USER_PASSWORD_STRENGTH_LEVEL', 'SHARE_LINK_PASSWORD_MIN_LENGTH', - 'ENABLE_USER_CREATE_ORG_REPO' + 'ENABLE_USER_CREATE_ORG_REPO', 'FORCE_PASSWORD_CHANGE' ) STRING_WEB_SETTINGS = ('SERVICE_URL', 'FILE_SERVER_ROOT',) diff --git a/tests/seahub/views/sysadmin/test_sysadmin.py b/tests/seahub/views/sysadmin/test_sysadmin.py index 375d2cce93..bb57104210 100644 --- a/tests/seahub/views/sysadmin/test_sysadmin.py +++ b/tests/seahub/views/sysadmin/test_sysadmin.py @@ -45,26 +45,6 @@ class UserToggleStatusTest(BaseTestCase): assert u.enc_password == old_passwd -class UserResetTest(BaseTestCase): - def setUp(self): - self.login_as(self.admin) - - def test_can_reset(self): - assert len(UserOptions.objects.filter( - email=self.user.username, option_key=KEY_FORCE_PASSWD_CHANGE)) == 0 - - old_passwd = self.user.enc_password - resp = self.client.post( - reverse('user_reset', args=[self.user.email]) - ) - self.assertEqual(302, resp.status_code) - - u = User.objects.get(email=self.user.username) - assert u.enc_password != old_passwd - assert UserOptions.objects.get( - email=self.user.username, - option_key=KEY_FORCE_PASSWD_CHANGE).option_val == VAL_FORCE_PASSWD_CHANGE - class BatchUserMakeAdminTest(BaseTestCase): def setUp(self): self.login_as(self.admin) @@ -103,29 +83,6 @@ class BatchUserMakeAdminTest(BaseTestCase): # assert u.enc_password == old_passwd -class UserAddTest(BaseTestCase): - def setUp(self): - self.new_user = 'new_user@test.com' - self.login_as(self.admin) - self.remove_user(self.new_user) - - def test_can_add(self): - assert len(UserOptions.objects.filter( - email=self.new_user, option_key=KEY_FORCE_PASSWD_CHANGE)) == 0 - - resp = self.client.post( - reverse('user_add',), { - 'email': self.new_user, - 'password1': '123', - 'password2': '123', - }, HTTP_X_REQUESTED_WITH='XMLHttpRequest' - ) - - self.assertEqual(200, resp.status_code) - assert UserOptions.objects.get( - email=self.new_user, - option_key=KEY_FORCE_PASSWD_CHANGE).option_val == VAL_FORCE_PASSWD_CHANGE - class UserRemoveTest(BaseTestCase): def setUp(self): self.login_as(self.admin) diff --git a/tests/seahub/views/sysadmin/test_user_add.py b/tests/seahub/views/sysadmin/test_user_add.py new file mode 100644 index 0000000000..0c3ea9640c --- /dev/null +++ b/tests/seahub/views/sysadmin/test_user_add.py @@ -0,0 +1,52 @@ +from django.core.urlresolvers import reverse +from constance import config + +from seahub.options.models import (UserOptions, KEY_FORCE_PASSWD_CHANGE, + VAL_FORCE_PASSWD_CHANGE) +from seahub.test_utils import BaseTestCase + + +class UserAddTest(BaseTestCase): + def setUp(self): + self.clear_cache() + + self.new_user = 'new_user@test.com' + self.login_as(self.admin) + self.remove_user(self.new_user) + + def test_can_add_when_pwd_change_required(self): + config.FORCE_PASSWORD_CHANGE = 1 + + assert len(UserOptions.objects.filter( + email=self.new_user, option_key=KEY_FORCE_PASSWD_CHANGE)) == 0 + + resp = self.client.post( + reverse('user_add',), { + 'email': self.new_user, + 'password1': '123', + 'password2': '123', + }, HTTP_X_REQUESTED_WITH='XMLHttpRequest' + ) + + self.assertEqual(200, resp.status_code) + assert UserOptions.objects.get( + email=self.new_user, + option_key=KEY_FORCE_PASSWD_CHANGE).option_val == VAL_FORCE_PASSWD_CHANGE + + def test_can_add_when_pwd_change_not_required(self): + config.FORCE_PASSWORD_CHANGE = 0 + + assert len(UserOptions.objects.filter( + email=self.new_user, option_key=KEY_FORCE_PASSWD_CHANGE)) == 0 + + resp = self.client.post( + reverse('user_add',), { + 'email': self.new_user, + 'password1': '123', + 'password2': '123', + }, HTTP_X_REQUESTED_WITH='XMLHttpRequest' + ) + + self.assertEqual(200, resp.status_code) + assert len(UserOptions.objects.filter( + email=self.new_user, option_key=KEY_FORCE_PASSWD_CHANGE)) == 0 diff --git a/tests/seahub/views/sysadmin/test_user_reset.py b/tests/seahub/views/sysadmin/test_user_reset.py new file mode 100644 index 0000000000..cc4d7558a2 --- /dev/null +++ b/tests/seahub/views/sysadmin/test_user_reset.py @@ -0,0 +1,50 @@ +from django.core.urlresolvers import reverse +from constance import config + +from seahub.base.accounts import User +from seahub.options.models import (UserOptions, KEY_FORCE_PASSWD_CHANGE, + VAL_FORCE_PASSWD_CHANGE) +from seahub.test_utils import BaseTestCase + + +class UserResetTest(BaseTestCase): + def setUp(self): + self.clear_cache() + + self.login_as(self.admin) + + def test_can_reset_when_pwd_change_required(self): + config.FORCE_PASSWORD_CHANGE = 1 + + assert len(UserOptions.objects.filter( + email=self.user.username, option_key=KEY_FORCE_PASSWD_CHANGE)) == 0 + + old_passwd = self.user.enc_password + resp = self.client.post( + reverse('user_reset', args=[self.user.email]) + ) + self.assertEqual(302, resp.status_code) + + u = User.objects.get(email=self.user.username) + assert u.enc_password != old_passwd + assert UserOptions.objects.get( + email=self.user.username, + option_key=KEY_FORCE_PASSWD_CHANGE).option_val == VAL_FORCE_PASSWD_CHANGE + + def test_can_reset_when_pwd_change_not_required(self): + config.FORCE_PASSWORD_CHANGE = 0 + + assert len(UserOptions.objects.filter( + email=self.user.username, option_key=KEY_FORCE_PASSWD_CHANGE)) == 0 + + old_passwd = self.user.enc_password + resp = self.client.post( + reverse('user_reset', args=[self.user.email]) + ) + self.assertEqual(302, resp.status_code) + + u = User.objects.get(email=self.user.username) + assert u.enc_password != old_passwd + + assert len(UserOptions.objects.filter( + email=self.user.username, option_key=KEY_FORCE_PASSWD_CHANGE)) == 0