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 %}
@@ -64,6 +65,7 @@
+ {% 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. """