From 788b98d041959bcdffa49db4c20a030d07b5c7c6 Mon Sep 17 00:00:00 2001 From: Vishnu Ks Date: Sat, 25 Aug 2018 12:06:17 +0000 Subject: [PATCH] portico: Add page for redirecting to a realm subdomain. --- static/styles/portico-signin.scss | 12 ++++++++ static/styles/portico.scss | 30 +++++++++++++++++++ templates/zerver/realm_redirect.html | 43 ++++++++++++++++++++++++++++ tools/lib/capitalization.py | 2 ++ zerver/forms.py | 9 ++++++ zerver/tests/test_signup.py | 20 +++++++++++++ zerver/tests/test_templates.py | 4 +++ zerver/views/registration.py | 21 +++++++++++--- zproject/urls.py | 4 +++ 9 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 templates/zerver/realm_redirect.html diff --git a/static/styles/portico-signin.scss b/static/styles/portico-signin.scss index 74f018b314..5cef764028 100644 --- a/static/styles/portico-signin.scss +++ b/static/styles/portico-signin.scss @@ -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%); diff --git a/static/styles/portico.scss b/static/styles/portico.scss index 86d72b8fd2..864ac08462 100644 --- a/static/styles/portico.scss +++ b/static/styles/portico.scss @@ -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; +} diff --git a/templates/zerver/realm_redirect.html b/templates/zerver/realm_redirect.html new file mode 100644 index 0000000000..e478ec1968 --- /dev/null +++ b/templates/zerver/realm_redirect.html @@ -0,0 +1,43 @@ +{% extends "zerver/portico.html" %} + +{% block portico_content %} + +
+
+
+

{{ _("Log in to your organization") }}

+
+ + +
+
+{% endblock %} diff --git a/tools/lib/capitalization.py b/tools/lib/capitalization.py index ce54c57c26..cb73f53ceb 100644 --- a/tools/lib/capitalization.py +++ b/tools/lib/capitalization.py @@ -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 diff --git a/zerver/forms.py b/zerver/forms.py index 185271efbc..33d40663a2 100644 --- a/zerver/forms.py +++ b/zerver/forms.py @@ -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 diff --git a/zerver/tests/test_signup.py b/zerver/tests/test_signup.py index 78da8be357..9ff0d26b16 100644 --- a/zerver/tests/test_signup.py +++ b/zerver/tests/test_signup.py @@ -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") diff --git a/zerver/tests/test_templates.py b/zerver/tests/test_templates.py index 430adb632c..4baf25a79f 100644 --- a/zerver/tests/test_templates.py +++ b/zerver/tests/test_templates.py @@ -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) diff --git a/zerver/views/registration.py b/zerver/views/registration.py index 0af01e30ac..fe8ee205f6 100644 --- a/zerver/views/registration.py +++ b/zerver/views/registration.py @@ -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}) diff --git a/zproject/urls.py b/zproject/urls.py index 5191209788..9b8483653f 100644 --- a/zproject/urls.py +++ b/zproject/urls.py @@ -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'),