password reset: Fix error message for invalid realm.

This is a lot cleaner than the previous model.

Basically rewritten by Vishnu Ks to actually work :).
This commit is contained in:
Tim Abbott 2017-11-17 18:30:07 -08:00
parent 10fbafa13e
commit c8edbae21c
5 changed files with 34 additions and 41 deletions

View File

@ -12,7 +12,7 @@
<p>Forgot your password? No problem, we'll send a link to reset your password to the email you signed up with.</p>
<form method="post" class="form-horizontal" action="{{ url('django.contrib.auth.views.password_reset') }}">
<form method="post" class="form-horizontal" action="{{ url('zerver.views.auth.password_reset') }}">
{{ csrf_input }}
<div class="new-style">
<div class="input-box horizontal moving-label">

View File

@ -210,8 +210,6 @@ class ZulipPasswordResetForm(PasswordResetForm):
subdomain = get_subdomain(request)
realm = get_realm(subdomain)
if realm is None:
raise ValidationError("Invalid realm")
if not email_auth_enabled(realm):
logging.info("Password reset attempted for %s even though password auth is disabled." % (email,))

View File

@ -227,19 +227,11 @@ class PasswordResetTest(ZulipTestCase):
def test_wrong_subdomain(self):
# type: () -> None
email = self.example_email("hamlet")
string_id = 'hamlet'
name = 'Hamlet'
do_create_realm(
string_id,
name,
restricted_to_domain=False,
invite_required=False
)
with patch('zerver.forms.get_subdomain', return_value=string_id):
# start the password reset process by supplying an email address
result = self.client_post(
'/accounts/password/reset/', {'email': email})
# start the password reset process by supplying an email address
result = self.client_post(
'/accounts/password/reset/', {'email': email},
subdomain="zephyr")
# check the redirect link telling you to check mail for password reset link
self.assertEqual(result.status_code, 302)
@ -258,31 +250,22 @@ class PasswordResetTest(ZulipTestCase):
self.assertIn("hamlet@zulip.com does not have an active account in\nhttp://zephyr.testserver",
message.body)
def test_correct_subdomain(self):
def test_invalid_subdomain(self):
# type: () -> None
email = self.example_email("hamlet")
string_id = 'zulip'
with patch('zerver.forms.get_subdomain', return_value=string_id):
# start the password reset process by supplying an email address
result = self.client_post(
'/accounts/password/reset/', {'email': email})
# start the password reset process by supplying an email address
result = self.client_post(
'/accounts/password/reset/', {'email': email},
subdomain="invalid")
# check the redirect link telling you to check mail for password reset link
self.assertEqual(result.status_code, 302)
self.assertTrue(result["Location"].endswith(
"/accounts/password/reset/done/"))
result = self.client_get(result["Location"])
self.assert_in_response("Check your email to finish the process.", result)
self.assertEqual(result.status_code, 200)
self.assert_in_success_response(["There is no Zulip organization hosted at this subdomain."],
result)
from django.core.mail import outbox
self.assertEqual(len(outbox), 1)
message = outbox.pop()
self.assertIn("Zulip Account Security", message.from_email)
self.assertIn(FromAddress.NOREPLY, message.from_email)
self.assertIn("Psst. Word on the street is that you",
message.body)
self.assertEqual(len(outbox), 0)
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',
'zproject.backends.ZulipDummyBackend'))

View File

@ -5,6 +5,7 @@ from django.core.validators import validate_email
from django.contrib.auth import authenticate, get_backends
from django.contrib.auth.views import login as django_login_page, \
logout_then_login as django_logout_then_login
from django.contrib.auth.views import password_reset as django_password_reset
from django.core.urlresolvers import reverse
from zerver.decorator import authenticated_json_post_view, require_post, \
process_client, do_login, log_view_func
@ -22,7 +23,7 @@ from typing import Any, Dict, List, Optional, Tuple, Text
from confirmation.models import Confirmation, create_confirmation_link
from zerver.context_processors import zulip_default_context, get_realm_from_request
from zerver.forms import HomepageForm, OurAuthenticationForm, \
WRONG_SUBDOMAIN_ERROR
WRONG_SUBDOMAIN_ERROR, ZulipPasswordResetForm
from zerver.lib.mobile_auth_otp import is_valid_otp, otp_encrypt_api_key
from zerver.lib.request import REQ, has_request_variables, JsonableError
from zerver.lib.response import json_success, json_error
@ -760,3 +761,17 @@ def api_fetch_google_client_id(request):
def logout_then_login(request, **kwargs):
# type: (HttpRequest, **Any) -> HttpResponse
return django_logout_then_login(request, kwargs)
def password_reset(request: HttpRequest, **kwargs: Any) -> HttpResponse:
realm = get_realm(get_subdomain(request))
if realm is None:
# If trying to get to password reset on a subdomain that
# doesn't exist, just go to find_account.
redirect_url = reverse('zerver.views.registration.find_account')
return HttpResponseRedirect(redirect_url)
return django_password_reset(request,
template_name='zerver/reset.html',
password_reset_form=ZulipPasswordResetForm,
post_reset_redirect='/accounts/password/reset/done/')

View File

@ -13,8 +13,8 @@ from zerver.lib.integrations import WEBHOOK_INTEGRATIONS
from zerver.webhooks import github_dispatcher
from django.contrib.auth.views import (login, password_reset,
password_reset_done, password_reset_confirm, password_reset_complete)
from django.contrib.auth.views import (login, password_reset_done,
password_reset_confirm, password_reset_complete)
import zerver.tornado.views
import zerver.views
@ -367,11 +367,8 @@ i18n_urls = [
zerver.views.zephyr.webathena_kerberos_login,
name='zerver.views.zephyr.webathena_kerberos_login'),
url(r'^accounts/password/reset/$', password_reset,
{'post_reset_redirect': '/accounts/password/reset/done/',
'template_name': 'zerver/reset.html',
'password_reset_form': zerver.forms.ZulipPasswordResetForm,
}, name='django.contrib.auth.views.password_reset'),
url(r'^accounts/password/reset/$', zerver.views.auth.password_reset,
name='zerver.views.auth.password_reset'),
url(r'^accounts/password/reset/done/$', password_reset_done,
{'template_name': 'zerver/reset_emailed.html'}),
url(r'^accounts/password/reset/(?P<uidb64>[0-9A-Za-z]+)/(?P<token>.+)/$',