mirror of https://github.com/zulip/zulip.git
portico: Add page for redirecting to a realm subdomain.
This commit is contained in:
parent
815388b023
commit
788b98d041
|
@ -641,6 +641,18 @@ button.login-google-button {
|
|||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
#find-account-section {
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
font-size: 0.8em;
|
||||
line-height: 1.5;
|
||||
vertical-align: top;
|
||||
|
||||
#find-account-link {
|
||||
color: hsl(164, 100%, 23%);
|
||||
}
|
||||
}
|
||||
|
||||
.split-view .actions a,
|
||||
.back-to-login {
|
||||
color: hsl(164, 100%, 23%);
|
||||
|
|
|
@ -2178,3 +2178,33 @@ input.new-organization-button {
|
|||
margin-top: 20px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#realm_redirect_subdomain {
|
||||
text-align: right;
|
||||
position: relative;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
#realm_redirect_external_host {
|
||||
font-size: 20px;
|
||||
top: 13px;
|
||||
left: 5px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#realm_redirect_description {
|
||||
top: 15px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.realm-redirect-form #find-account-link {
|
||||
color: hsl(165, 100.0%, 14.7%);
|
||||
}
|
||||
|
||||
.realm-redirect-form #find-account-section {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.realm-redirect-form #enter-realm-button {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
{% extends "zerver/portico.html" %}
|
||||
|
||||
{% block portico_content %}
|
||||
|
||||
<div class="app find-account-page flex full-page">
|
||||
<div class="inline-block new-style">
|
||||
<div class="lead">
|
||||
<h1 class="get-started">{{ _("Log in to your organization") }}</h1>
|
||||
</div>
|
||||
|
||||
<div class="app-main find-account-page-container white-box">
|
||||
<div class="realm-redirect-form">
|
||||
<form class="form-inline" name="realm_redirect_form"
|
||||
action="/accounts/go/?{{ request.GET.urlencode() }}" method="post">
|
||||
{{ csrf_input }}
|
||||
<div class="input-box moving-label horizontal">
|
||||
<div class="inline-block relative">
|
||||
<p id="realm_redirect_description">{{ _("Enter your organization URL:") }}</p>
|
||||
<input
|
||||
type="text" value="{% if form.subdomain.value() %}{{ form.subdomain.value() }}{% endif %}"
|
||||
placeholder="{{ _('your-organization-url') }}" autofocus id="realm_redirect_subdomain" name="subdomain"
|
||||
autocomplete="off" required/>
|
||||
<span id="realm_redirect_external_host">.{{external_host}}</span>
|
||||
</div>
|
||||
<div id="errors">
|
||||
{% if form.subdomain.errors %}
|
||||
{% for error in form.subdomain.errors %}
|
||||
<div class="alert alert-error">{{ error }}</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<button id="enter-realm-button" type="submit">{{ _('Next') }}</button>
|
||||
<p id="find-account-section">
|
||||
{{ _("Can't remember your organization URL?") }}
|
||||
<a target="_blank" id="find-account-link" href="/accounts/find/">{{ _("Find your account.") }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -128,6 +128,8 @@ IGNORED_PHRASES = [
|
|||
r"GIF",
|
||||
# Emoji name placeholder
|
||||
r"leafy green vegetable",
|
||||
# Subdomain placeholder
|
||||
r"your-organization-url",
|
||||
]
|
||||
|
||||
# Sort regexes in descending order of their lengths. As a result, the
|
||||
|
|
|
@ -349,3 +349,12 @@ class FindMyTeamForm(forms.Form):
|
|||
raise forms.ValidationError(_("Please enter at most 10 emails."))
|
||||
|
||||
return emails
|
||||
|
||||
class RealmRedirectForm(forms.Form):
|
||||
subdomain = forms.CharField(max_length=Realm.MAX_REALM_SUBDOMAIN_LENGTH, required=True)
|
||||
|
||||
def clean_subdomain(self) -> str:
|
||||
subdomain = self.cleaned_data['subdomain']
|
||||
if get_realm(subdomain) is None:
|
||||
raise ValidationError(_("We couldn't find that Zulip organization."))
|
||||
return subdomain
|
||||
|
|
|
@ -3150,3 +3150,23 @@ class TwoFactorAuthTest(ZulipTestCase):
|
|||
class NameRestrictionsTest(ZulipTestCase):
|
||||
def test_whitelisted_disposable_domains(self) -> None:
|
||||
self.assertFalse(is_disposable_domain('OPayQ.com'))
|
||||
|
||||
class RealmRedirectTest(ZulipTestCase):
|
||||
def test_realm_redirect_without_next_param(self) -> None:
|
||||
result = self.client_get("/accounts/go/")
|
||||
self.assert_in_success_response(["Enter your organization URL"], result)
|
||||
|
||||
result = self.client_post("/accounts/go/", {"subdomain": "zephyr"})
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertEqual(result["Location"], "http://zephyr.testserver")
|
||||
|
||||
result = self.client_post("/accounts/go/", {"subdomain": "invalid"})
|
||||
self.assert_in_success_response(["We couldn't find that Zulip organization."], result)
|
||||
|
||||
def test_realm_redirect_with_next_param(self) -> None:
|
||||
result = self.client_get("/accounts/go/?next=billing")
|
||||
self.assert_in_success_response(['Enter your organization URL', 'action="/accounts/go/?next=billing"'], result)
|
||||
|
||||
result = self.client_post("/accounts/go/?next=billing", {"subdomain": "lear"})
|
||||
self.assertEqual(result.status_code, 302)
|
||||
self.assertEqual(result["Location"], "http://lear.testserver/billing")
|
||||
|
|
|
@ -9,6 +9,7 @@ from django.conf import settings
|
|||
from django.test import override_settings
|
||||
from django.template import Template, Context
|
||||
from django.template.loader import get_template
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from zerver.lib.test_helpers import get_all_templates
|
||||
from zerver.lib.test_classes import (
|
||||
|
@ -183,6 +184,8 @@ class TemplateTestCase(ZulipTestCase):
|
|||
terms=get_form_value(True),
|
||||
email=get_form_value(email),
|
||||
emails=get_form_value(email),
|
||||
subdomain=get_form_value("zulip"),
|
||||
next_param=get_form_value("billing")
|
||||
),
|
||||
current_url=lambda: 'www.zulip.com',
|
||||
integrations_dict={},
|
||||
|
@ -202,6 +205,7 @@ class TemplateTestCase(ZulipTestCase):
|
|||
api_uri_context={},
|
||||
cloud_annual_price=80,
|
||||
seat_count=8,
|
||||
request=RequestFactory().get("/")
|
||||
)
|
||||
|
||||
context.update(kwargs)
|
||||
|
|
|
@ -23,7 +23,7 @@ from zerver.lib.actions import do_change_password, do_change_full_name, do_chang
|
|||
email_not_system_bot, validate_email_for_realm, \
|
||||
do_set_user_display_setting, lookup_default_stream_groups, bulk_add_subscriptions
|
||||
from zerver.forms import RegistrationForm, HomepageForm, RealmCreationForm, \
|
||||
CreateUserForm, FindMyTeamForm
|
||||
CreateUserForm, FindMyTeamForm, RealmRedirectForm
|
||||
from django_auth_ldap.backend import LDAPBackend, _LDAPUser
|
||||
from zerver.decorator import require_post, has_request_variables, \
|
||||
JsonableError, REQ, do_login
|
||||
|
@ -34,9 +34,9 @@ from zerver.lib.subdomains import get_subdomain, is_root_domain_available
|
|||
from zerver.lib.timezone import get_all_timezones
|
||||
from zerver.lib.users import get_accounts_for_email
|
||||
from zerver.lib.zephyr import compute_mit_user_fullname
|
||||
from zerver.views.auth import create_preregistration_user, \
|
||||
redirect_and_log_into_subdomain, \
|
||||
redirect_to_deactivation_notice
|
||||
from zerver.views.auth import create_preregistration_user, redirect_and_log_into_subdomain, \
|
||||
redirect_to_deactivation_notice, get_safe_redirect_to
|
||||
|
||||
from zproject.backends import ldap_auth_enabled, password_auth_enabled, ZulipLDAPAuthBackend, \
|
||||
ZulipLDAPException, email_auth_enabled
|
||||
|
||||
|
@ -515,3 +515,16 @@ def find_account(request: HttpRequest) -> HttpResponse:
|
|||
'zerver/find_account.html',
|
||||
context={'form': form, 'current_url': lambda: url,
|
||||
'emails': emails},)
|
||||
|
||||
def realm_redirect(request: HttpRequest) -> HttpResponse:
|
||||
if request.method == 'POST':
|
||||
form = RealmRedirectForm(request.POST)
|
||||
if form.is_valid():
|
||||
subdomain = form.cleaned_data['subdomain']
|
||||
realm = get_realm(subdomain)
|
||||
redirect_to = get_safe_redirect_to(request.GET.get("next", ""), realm.uri)
|
||||
return HttpResponseRedirect(redirect_to)
|
||||
else:
|
||||
form = RealmRedirectForm()
|
||||
|
||||
return render(request, 'zerver/realm_redirect.html', context={'form': form})
|
||||
|
|
|
@ -452,6 +452,10 @@ i18n_urls = [
|
|||
url(r'^accounts/find/$', zerver.views.registration.find_account,
|
||||
name='zerver.views.registration.find_account'),
|
||||
|
||||
# Go to organization subdomain
|
||||
url(r'^accounts/go/$', zerver.views.registration.realm_redirect,
|
||||
name='zerver.views.registration.realm_redirect'),
|
||||
|
||||
# Realm Creation
|
||||
url(r'^new/$', zerver.views.registration.create_realm,
|
||||
name='zerver.views.create_realm'),
|
||||
|
|
Loading…
Reference in New Issue