auth: Change the look of SOCIAL_AUTH_SUBDOMAIN when directly opened.

SOCIAL_AUTH_SUBDOMAIN was potentially very confusing when opened by a
user, as it had various Login/Signup buttons as if there was a realm on
it. Instead, we want to display a more informative page to the user
telling them they shouldn't even be there. If possible, we just redirect
them to the realm they most likely came from.
To make this possible, we have to exclude the subdomain from
ROOT_SUBDOMAIN_ALIASES - so that we can give it special behavior.
This commit is contained in:
Mateusz Mandera
2021-08-23 15:14:05 +02:00
committed by Tim Abbott
parent cf2302b272
commit fb3864ea3c
7 changed files with 71 additions and 7 deletions

View File

@@ -0,0 +1,25 @@
{% extends "zerver/portico.html" %}
{% block portico_content %}
<div class="error_page">
<div class="container">
<div class="row-fluid">
<img src="/static/images/500art.svg" alt=""/>
<div class="errorbox">
<div class="errorcontent">
<h1 class="lead">Authentication subdomain</h1>
<p>
It appears you ended up here by accident. This site
is meant to be an intermediate step in the authentication process
and shouldn't be accessed manually. If you came here directly,
you probably got the address wrong. If you got stuck here while trying
to log in, this is most likely a server bug or misconfiguration.
</p>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -576,7 +576,10 @@ class HostDomainMiddleware(MiddlewareMixin):
return None
subdomain = get_subdomain(request)
if subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN:
if (
subdomain != Realm.SUBDOMAIN_FOR_ROOT_DOMAIN
and subdomain != settings.SOCIAL_AUTH_SUBDOMAIN
):
request_notes = RequestNotes.get_notes(request)
try:
request_notes.realm = get_realm(subdomain)

View File

@@ -5290,6 +5290,27 @@ class TestLoginPage(ZulipTestCase):
response,
)
@patch("django.http.HttpRequest.get_host", return_value="auth.testserver")
def test_social_auth_subdomain_login_page(self, mock_get_host: MagicMock) -> None:
result = self.client_get("http://auth.testserver/login/")
self.assertEqual(result.status_code, 400)
self.assert_in_response("Authentication subdomain", result)
zulip_realm = get_realm("zulip")
session = self.client.session
session["subdomain"] = "zulip"
session.save()
result = self.client_get("http://auth.testserver/login/")
self.assertEqual(result.status_code, 302)
self.assertEqual(result.url, zulip_realm.uri)
session = self.client.session
session["subdomain"] = "invalid"
session.save()
result = self.client_get("http://auth.testserver/login/")
self.assertEqual(result.status_code, 400)
self.assert_in_response("Authentication subdomain", result)
class TestFindMyTeam(ZulipTestCase):
def test_template(self) -> None:

View File

@@ -731,6 +731,9 @@ def login_page(
next: str = REQ(default="/"),
**kwargs: Any,
) -> HttpResponse:
if settings.SOCIAL_AUTH_SUBDOMAIN == get_subdomain(request):
return social_auth_subdomain_login_page(request)
# To support previewing the Zulip login pages, we have a special option
# that disables the default behavior of redirecting logged-in users to the
# logged-in app.
@@ -794,6 +797,18 @@ def login_page(
return template_response
def social_auth_subdomain_login_page(request: HttpRequest) -> HttpResponse:
origin_subdomain = request.session.get("subdomain")
if origin_subdomain is not None:
try:
origin_realm = get_realm(origin_subdomain)
return HttpResponseRedirect(origin_realm.uri)
except Realm.DoesNotExist:
pass
return render(request, "zerver/auth_subdomain.html", status=400)
def start_two_factor_auth(
request: HttpRequest, extra_context: ExtraContext = None, **kwargs: Any
) -> HttpResponse:

View File

@@ -49,6 +49,7 @@ from .configured_settings import (
REMOTE_POSTGRES_HOST,
REMOTE_POSTGRES_PORT,
REMOTE_POSTGRES_SSLMODE,
ROOT_SUBDOMAIN_ALIASES,
SENDFILE_BACKEND,
SENTRY_DSN,
SOCIAL_AUTH_APPLE_APP_ID,
@@ -59,6 +60,7 @@ from .configured_settings import (
SOCIAL_AUTH_GOOGLE_KEY,
SOCIAL_AUTH_SAML_ENABLED_IDPS,
SOCIAL_AUTH_SAML_SECURITY_CONFIG,
SOCIAL_AUTH_SUBDOMAIN,
STATSD_HOST,
TORNADO_PORTS,
USING_PGROONGA,
@@ -1066,6 +1068,9 @@ SOCIAL_AUTH_FIELDS_STORED_IN_SESSION = [
]
SOCIAL_AUTH_LOGIN_ERROR_URL = "/login/"
if SOCIAL_AUTH_SUBDOMAIN in ROOT_SUBDOMAIN_ALIASES:
ROOT_SUBDOMAIN_ALIASES.remove(SOCIAL_AUTH_SUBDOMAIN)
# CLIENT is required by PSA's internal implementation. We name it
# SERVICES_ID to make things more readable in the configuration
# and our own custom backend code.

View File

@@ -338,8 +338,7 @@ LOGIN_LINK_DISABLED = False
FIND_TEAM_LINK_DISABLED = True
# What domains to treat like the root domain
# "auth" is by default a reserved subdomain for the use by python-social-auth.
ROOT_SUBDOMAIN_ALIASES = ["www", "auth"]
ROOT_SUBDOMAIN_ALIASES = ["www"]
# Whether the root domain is a landing page or can host a realm.
ROOT_DOMAIN_LANDING_PAGE = False

View File

@@ -336,10 +336,6 @@ AUTH_LDAP_USER_ATTR_MAP = {
## organization. The default recommendation, `auth`, is a reserved
## subdomain; if you're using this setting, the "Callback URL" should be e.g.:
## https://auth.zulip.example.com/complete/github/
##
## If you end up using a subdomain other then the default
## recommendation, you must also set the 'ROOT_SUBDOMAIN_ALIASES' list
## to include this subdomain.
#
# SOCIAL_AUTH_SUBDOMAIN = 'auth'