diff --git a/static/js/setup.js b/static/js/setup.js index 37bb877939..b77576441c 100644 --- a/static/js/setup.js +++ b/static/js/setup.js @@ -32,6 +32,8 @@ $(function () { } }); - // zxcvbn.js is pretty big, and is only needed on password change, so load it asynchronously. - $.getScript('/static/third/zxcvbn/zxcvbn.js'); + if (page_params.password_auth_enabled !== false) { + // zxcvbn.js is pretty big, and is only needed on password change, so load it asynchronously. + $.getScript('/static/third/zxcvbn/zxcvbn.js'); + } }); diff --git a/static/js/ui.js b/static/js/ui.js index 5f91962824..bfb691414c 100644 --- a/static/js/ui.js +++ b/static/js/ui.js @@ -950,20 +950,22 @@ $(function () { $("form.your-account-settings").expectOne().ajaxForm({ dataType: 'json', // This seems to be ignored. We still get back an xhr. beforeSubmit: function (arr, form, options) { - // FIXME: Check that the two password fields match - // FIXME: Use the same jQuery validation plugin as the signup form? - var new_pw = $('#new_password').val(); - if (new_pw !== '') { - var password_ok = password_quality(new_pw); - if (password_ok === undefined) { - // zxcvbn.js didn't load, for whatever reason. - settings_change_error( - 'An internal error occurred; try reloading the page. ' + - 'Sorry for the trouble!'); - return false; - } else if (!password_ok) { - settings_change_error('New password is too weak'); - return false; + if (page_params.password_auth_enabled !== false) { + // FIXME: Check that the two password fields match + // FIXME: Use the same jQuery validation plugin as the signup form? + var new_pw = $('#new_password').val(); + if (new_pw !== '') { + var password_ok = password_quality(new_pw); + if (password_ok === undefined) { + // zxcvbn.js didn't load, for whatever reason. + settings_change_error( + 'An internal error occurred; try reloading the page. ' + + 'Sorry for the trouble!'); + return false; + } else if (!password_ok) { + settings_change_error('New password is too weak'); + return false; + } } } return true; diff --git a/templates/zerver/settings.html b/templates/zerver/settings.html index 998287628b..6f2c8b8c18 100644 --- a/templates/zerver/settings.html +++ b/templates/zerver/settings.html @@ -20,6 +20,7 @@ + {% if password_auth_enabled %} + {% endif %}
diff --git a/zerver/context_processors.py b/zerver/context_processors.py index 6f051bd5a2..ae8ba7c0f3 100644 --- a/zerver/context_processors.py +++ b/zerver/context_processors.py @@ -2,12 +2,14 @@ from __future__ import absolute_import from django.conf import settings import ujson +from zproject.backends import password_auth_enabled def add_settings(request): return { 'full_navbar': settings.FULL_NAVBAR, 'local_server': settings.LOCAL_SERVER, 'zulip_admin': settings.ZULIP_ADMINISTRATOR, + 'password_auth_enabled': password_auth_enabled(), } def add_metrics(request): diff --git a/zerver/tests.py b/zerver/tests.py index 930a3abc65..566f55cfe9 100644 --- a/zerver/tests.py +++ b/zerver/tests.py @@ -2248,20 +2248,15 @@ class ChangeSettingsTest(AuthedTestCase): def test_missing_params(self): """ - full_name, old_password, and new_password are all required POST - parameters for json_change_settings. (enable_desktop_notifications is - false by default) + full_name is a required POST parameter for json_change_settings. + (enable_desktop_notifications is false by default, and password is + only required if you are changing it) """ self.login("hamlet@zulip.com") - required_params = (("full_name", "Foo Bar"), - ("old_password", initial_password("hamlet@zulip.com")), - ("new_password", initial_password("hamlet@zulip.com")), - ("confirm_password", initial_password("hamlet@zulip.com"))) - for i in range(len(required_params)): - post_params = dict(required_params[:i] + required_params[i + 1:]) - result = self.client.post("/json/settings/change", post_params) - self.assert_json_error(result, - "Missing '%s' argument" % (required_params[i][0],)) + + result = self.client.post("/json/settings/change", {}) + self.assert_json_error(result, + "Missing '%s' argument" % ("full_name",)) def test_mismatching_passwords(self): """ diff --git a/zerver/views/__init__.py b/zerver/views/__init__.py index 4fe9ab9b2e..382d398fed 100644 --- a/zerver/views/__init__.py +++ b/zerver/views/__init__.py @@ -66,6 +66,7 @@ from zerver.lib.unminify import SourceMap from zerver.lib.queue import queue_json_publish from zerver.lib.utils import statsd, generate_random_token, statsd_key from zerver import tornado_callbacks +from zproject.backends import password_auth_enabled from django.db import connection from confirmation.models import Confirmation @@ -665,6 +666,7 @@ def home(request): debug_mode = settings.DEBUG, test_suite = settings.TEST_SUITE, poll_timeout = settings.POLL_TIMEOUT, + password_auth_enabled = password_auth_enabled(), have_initial_messages = user_has_messages, stream_list = register_ret['subscriptions'], unsubbed_info = register_ret['unsubscribed'], @@ -1698,9 +1700,9 @@ def get_subscribers_backend(request, user_profile, stream_name=REQ('stream')): @has_request_variables def json_change_settings(request, user_profile, full_name=REQ, - old_password=REQ, - new_password=REQ, - confirm_password=REQ): + old_password=REQ(default=""), + new_password=REQ(default=""), + confirm_password=REQ(default="")): if new_password != "" or confirm_password != "": if new_password != confirm_password: return json_error("New password must match confirmation password!") diff --git a/zproject/backends.py b/zproject/backends.py index 0bedd1a892..f1222ce075 100644 --- a/zproject/backends.py +++ b/zproject/backends.py @@ -1,11 +1,19 @@ from __future__ import absolute_import from django.contrib.auth.backends import RemoteUserBackend +import django.contrib.auth + from zerver.models import UserProfile, get_user_profile_by_id, \ get_user_profile_by_email, remote_user_to_email from openid.consumer.consumer import SUCCESS +def password_auth_enabled(): + for backend in django.contrib.auth.get_backends(): + if isinstance(backend, EmailAuthBackend): + return True + return False + class ZulipAuthMixin(object): def get_user(self, user_profile_id): """ Get a UserProfile object from the user_profile_id. """