auth: Accept next as POST parameter in POST requests.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg
2020-05-14 19:13:33 -07:00
committed by Tim Abbott
parent 83380b4296
commit 620e98860e
4 changed files with 36 additions and 19 deletions

View File

@@ -15,13 +15,14 @@ page can be easily identified in it's respective JavaScript file -->
{% endif %}
<p class="devlogin_subheader">(Or visit the <a href="/login/">normal login page</a>.)</p>
<form name="direct_login_form" id="direct_login_form" method="post" class="login-form">
<input type="hidden" name="next" value="{{ next }}" />
<div class="control-group">
<div class="controls">
<div class="group">
<h2>{{ _('Administrators') }}</h2>
{% if direct_admins %}
{% for direct_admin in direct_admins %}
<p><input type="submit" formaction="{{ direct_admin.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}?next={{ next }}"
<p><input type="submit" formaction="{{ direct_admin.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}"
name="direct_email" class="btn-direct btn-admin" value="{{ direct_admin.delivery_email }}" /></p>
{% endfor %}
{% else %}
@@ -30,7 +31,7 @@ page can be easily identified in it's respective JavaScript file -->
<h2>{{ _('Guest users') }}</h2>
{% if guest_users %}
{% for guest_user in guest_users %}
<p><input type="submit" formaction="{{ guest_user.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}?next={{ next }}"
<p><input type="submit" formaction="{{ guest_user.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}"
name="direct_email" class="btn-direct btn-admin" value="{{ guest_user.delivery_email }}" /></p>
{% endfor %}
{% else %}
@@ -42,7 +43,7 @@ page can be easily identified in it's respective JavaScript file -->
<h2>{{ _('Normal users') }}</h2>
{% if direct_users %}
{% for direct_user in direct_users %}
<p><input type="submit" formaction="{{ direct_user.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}?next={{ next }}"
<p><input type="submit" formaction="{{ direct_user.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}"
name="direct_email" class="btn-direct btn-admin" value="{{ direct_user.delivery_email }}" /></p>
{% endfor %}
{% else %}

View File

@@ -41,7 +41,8 @@ page can be easily identified in it's respective JavaScript file. -->
{% else %}
{% if password_auth_enabled %}
<form name="login_form" id="login_form" method="post" class="login-form"
action="{{ url('django.contrib.auth.views.login') }}?next={{ next }}">
action="{{ url('django.contrib.auth.views.login') }}">
<input type="hidden" name="next" value="{{ next }}">
{% if two_factor_authentication_enabled %}
{{ wizard.management_form }}

View File

@@ -2108,7 +2108,7 @@ class TestDevAuthBackend(ZulipTestCase):
with self.settings(TWO_FACTOR_AUTHENTICATION_ENABLED=True):
result = self.client_post('/accounts/login/local/', data)
self.assertEqual(result.status_code, 302)
self.assertEqual(result.url, 'http://zulip.testserver')
self.assertEqual(result.url, 'http://zulip.testserver/')
self.assert_logged_in_user_id(user_profile.id)
self.assertIn('otp_device_id', list(self.client.session.keys()))
@@ -2120,7 +2120,7 @@ class TestDevAuthBackend(ZulipTestCase):
res = do_local_login('/accounts/login/local/')
self.assertEqual(res.status_code, 302)
self.assertEqual(res.url, 'http://zulip.testserver')
self.assertEqual(res.url, 'http://zulip.testserver/')
res = do_local_login('/accounts/login/local/?next=/user_uploads/path_to_image')
self.assertEqual(res.status_code, 302)

View File

@@ -251,8 +251,11 @@ def login_or_register_remote_user(request: HttpRequest, remote_username: str,
@log_view_func
@has_request_variables
def remote_user_sso(request: HttpRequest,
mobile_flow_otp: Optional[str]=REQ(default=None)) -> HttpResponse:
def remote_user_sso(
request: HttpRequest,
mobile_flow_otp: Optional[str] = REQ(default=None),
next: str = REQ(default="/"),
) -> HttpResponse:
subdomain = get_subdomain(request)
try:
realm = get_realm(subdomain) # type: Optional[Realm]
@@ -286,11 +289,9 @@ def remote_user_sso(request: HttpRequest,
else:
user_profile = authenticate(remote_user=remote_user, realm=realm)
redirect_to = request.GET.get('next', '')
return login_or_register_remote_user(request, remote_user, user_profile,
mobile_flow_otp=mobile_flow_otp,
redirect_to=redirect_to)
redirect_to=next)
@csrf_exempt
@log_view_func
@@ -338,9 +339,15 @@ def remote_user_jwt(request: HttpRequest) -> HttpResponse:
return login_or_register_remote_user(request, email, user_profile, remote_user)
def oauth_redirect_to_root(request: HttpRequest, url: str,
sso_type: str, is_signup: bool=False,
extra_url_params: Dict[str, str]={}) -> HttpResponse:
@has_request_variables
def oauth_redirect_to_root(
request: HttpRequest,
url: str,
sso_type: str,
is_signup: bool=False,
extra_url_params: Dict[str, str]={},
next: Optional[str] = REQ(default=None),
) -> HttpResponse:
main_site_uri = settings.ROOT_DOMAIN_URI + url
if settings.SOCIAL_AUTH_SUBDOMAIN is not None and sso_type == 'social':
main_site_uri = (settings.EXTERNAL_URI_SCHEME +
@@ -363,7 +370,6 @@ def oauth_redirect_to_root(request: HttpRequest, url: str,
raise JsonableError(_("Invalid OTP"))
params['mobile_flow_otp'] = mobile_flow_otp
next = request.GET.get('next')
if next:
params['next'] = next
@@ -588,7 +594,9 @@ class TwoFactorLoginView(BaseTwoFactorLoginView):
realm = get_realm_from_request(self.request)
redirect_to = realm.uri if realm else '/'
context['next'] = self.request.GET.get('next', redirect_to)
context['next'] = self.request.POST.get(
'next', self.request.GET.get('next', redirect_to),
)
return context
def done(self, form_list: List[Form], **kwargs: Any) -> HttpResponse:
@@ -609,7 +617,10 @@ class TwoFactorLoginView(BaseTwoFactorLoginView):
with patch.object(settings, 'LOGIN_REDIRECT_URL', realm_uri):
return super().done(form_list, **kwargs)
def login_page(request: HttpRequest, **kwargs: Any) -> HttpResponse:
@has_request_variables
def login_page(
request: HttpRequest, next: str = REQ(default="/"), **kwargs: Any,
) -> HttpResponse:
# 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.
@@ -630,6 +641,7 @@ def login_page(request: HttpRequest, **kwargs: Any) -> HttpResponse:
return redirect_to_deactivation_notice()
extra_context = kwargs.pop('extra_context', {})
extra_context["next"] = next
if dev_auth_enabled() and kwargs.get("template_name") == "zerver/dev_login.html":
if 'new_realm' in request.POST:
try:
@@ -701,7 +713,11 @@ def start_two_factor_auth(request: HttpRequest,
return two_fa_view(request, **kwargs)
@csrf_exempt
def dev_direct_login(request: HttpRequest, **kwargs: Any) -> HttpResponse:
@has_request_variables
def dev_direct_login(
request: HttpRequest,
next: str = REQ(default="/"),
) -> HttpResponse:
# This function allows logging in without a password and should only be called
# in development environments. It may be called if the DevAuthBackend is included
# in settings.AUTHENTICATION_BACKENDS
@@ -717,7 +733,6 @@ def dev_direct_login(request: HttpRequest, **kwargs: Any) -> HttpResponse:
return HttpResponseRedirect(reverse('dev_not_supported'))
do_login(request, user_profile)
next = request.GET.get('next', '')
redirect_to = get_safe_redirect_to(next, user_profile.realm.uri)
return HttpResponseRedirect(redirect_to)