mirror of
https://github.com/zulip/zulip.git
synced 2025-10-23 04:52:12 +00:00
signup: Prevent unauthorized signup for realms without EmailAuthBackend.
Zulip supports a configuration where account creation is limited solely by being able to authenticate with a single-sign on authentication backend, such as Google Authentication, SAML, or LDAP (i.e., the organization places no restrictions on email address domains or invitations being required to join, but has disabled the EmailAuthBackend that is used for email/password authentication). A bug in the Zulip server meant that Zulip allowed users to create an account in such organizations by confirming their email address, without having an account with the SSO authentication backend. Co-authored-by: Tim Abbott <tabbott@zulip.com>
This commit is contained in:
committed by
Tim Abbott
parent
2429157498
commit
c4bb6509dd
@@ -41,7 +41,12 @@ from zerver.models.realms import (
|
||||
get_realm,
|
||||
)
|
||||
from zerver.models.users import get_user_by_delivery_email, is_cross_realm_bot_email
|
||||
from zproject.backends import check_password_strength, email_auth_enabled, email_belongs_to_ldap
|
||||
from zproject.backends import (
|
||||
check_password_strength,
|
||||
email_auth_enabled,
|
||||
email_belongs_to_ldap,
|
||||
password_auth_enabled,
|
||||
)
|
||||
|
||||
# We don't mark this error for translation, because it's displayed
|
||||
# only to MIT users.
|
||||
@@ -248,6 +253,7 @@ class HomepageForm(forms.Form):
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
||||
self.realm = kwargs.pop("realm", None)
|
||||
self.from_multiuse_invite = kwargs.pop("from_multiuse_invite", False)
|
||||
self.require_password_backend = kwargs.pop("require_password_backend", False)
|
||||
self.invited_as = kwargs.pop("invited_as", None)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -267,12 +273,17 @@ class HomepageForm(forms.Form):
|
||||
)
|
||||
)
|
||||
|
||||
if not from_multiuse_invite and realm.invite_required:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"Please request an invite for {email} from the organization administrator."
|
||||
).format(email=email)
|
||||
)
|
||||
if not from_multiuse_invite:
|
||||
if realm.invite_required:
|
||||
raise ValidationError(
|
||||
_(
|
||||
"Please request an invite for {email} from the organization administrator."
|
||||
).format(email=email)
|
||||
)
|
||||
if self.require_password_backend and not password_auth_enabled(realm):
|
||||
raise ValidationError(
|
||||
_("Can't join the organization: password authentication is not enabled.")
|
||||
)
|
||||
|
||||
try:
|
||||
email_allowed_for_realm(email, realm)
|
||||
|
@@ -1028,7 +1028,7 @@ class LoginTest(ZulipTestCase):
|
||||
# to sending messages, such as getting the welcome bot, looking up
|
||||
# the alert words for a realm, etc.
|
||||
with (
|
||||
self.assert_database_query_count(93),
|
||||
self.assert_database_query_count(95),
|
||||
self.assert_memcached_count(18),
|
||||
self.captureOnCommitCallbacks(execute=True),
|
||||
):
|
||||
@@ -3147,6 +3147,39 @@ class UserSignUpTest(ZulipTestCase):
|
||||
result = self.client_get("/register", subdomain="", follow=True)
|
||||
self.assert_in_success_response(["Find your Zulip accounts"], result)
|
||||
|
||||
@override_settings(
|
||||
AUTHENTICATION_BACKENDS=(
|
||||
"zproject.backends.SAMLAuthBackend",
|
||||
"zproject.backends.ZulipDummyBackend",
|
||||
)
|
||||
)
|
||||
def test_cant_obtain_confirmation_email_when_email_backend_disabled(self) -> None:
|
||||
"""
|
||||
When a realm disables EmailAuthBackend while keeping invite_required set to False,
|
||||
users must not be allowed to generate a confirmation email to themselves by POSTing
|
||||
it to the registration endpoints - as that would allow them to sign up and obtain
|
||||
a logged in session in the realm without actually having to go through the
|
||||
allowed authentication methods.
|
||||
"""
|
||||
realm = get_realm("zulip")
|
||||
self.assertEqual(realm.invite_required, False)
|
||||
|
||||
from django.core.mail import outbox
|
||||
|
||||
email = "newuser@zulip.com"
|
||||
original_outbox_length = len(outbox)
|
||||
result = self.client_post("/register/", {"email": email})
|
||||
self.assert_not_in_success_response(["check your email"], result)
|
||||
self.assert_in_success_response(["Sign up with"], result)
|
||||
|
||||
self.assertEqual(original_outbox_length, len(outbox))
|
||||
|
||||
result = self.client_post("/accounts/home/", {"email": email})
|
||||
self.assert_not_in_success_response(["check your email"], result)
|
||||
self.assert_in_success_response(["Sign up with"], result)
|
||||
|
||||
self.assertEqual(original_outbox_length, len(outbox))
|
||||
|
||||
@override_settings(
|
||||
AUTHENTICATION_BACKENDS=(
|
||||
"zproject.backends.ZulipLDAPAuthBackend",
|
||||
|
@@ -1069,6 +1069,7 @@ def accounts_home(
|
||||
form = HomepageForm(
|
||||
request.POST,
|
||||
realm=realm,
|
||||
require_password_backend=True,
|
||||
from_multiuse_invite=from_multiuse_invite,
|
||||
invited_as=invited_as,
|
||||
)
|
||||
|
Reference in New Issue
Block a user