auth.py: Make redirects to 'next' url work for dev environment.

This makes these redirects work for the local authentication
backend.
This commit is contained in:
Aditya Bansal
2018-03-12 16:55:50 +05:30
committed by Tim Abbott
parent 1d4e4d0411
commit 9a100b1f55
3 changed files with 28 additions and 3 deletions

View File

@@ -17,7 +17,7 @@
<h2>{{ _('Administrators') }}</h2> <h2>{{ _('Administrators') }}</h2>
{% if direct_admins %} {% if direct_admins %}
{% for direct_admin in direct_admins %} {% for direct_admin in direct_admins %}
<p><input type="submit" formaction="{{ direct_admin.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}" <p><input type="submit" formaction="{{ direct_admin.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}?next={{ next }}"
name="direct_email" class="btn-direct btn-admin" value="{{ direct_admin.email }}" /></p> name="direct_email" class="btn-direct btn-admin" value="{{ direct_admin.email }}" /></p>
{% endfor %} {% endfor %}
{% else %} {% else %}
@@ -29,7 +29,7 @@
<h2>{{ _('Normal users') }}</h2> <h2>{{ _('Normal users') }}</h2>
{% if direct_users %} {% if direct_users %}
{% for direct_user in direct_users %} {% for direct_user in direct_users %}
<p><input type="submit" formaction="{{ direct_user.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}" <p><input type="submit" formaction="{{ direct_user.realm.uri }}{{ url('zerver.views.auth.dev_direct_login') }}?next={{ next }}"
name="direct_email" class="btn-direct btn-admin" value="{{ direct_user.email }}" /></p> name="direct_email" class="btn-direct btn-admin" value="{{ direct_user.email }}" /></p>
{% endfor %} {% endfor %}
{% else %} {% else %}

View File

@@ -1459,6 +1459,20 @@ class TestDevAuthBackend(ZulipTestCase):
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
self.assertEqual(get_session_dict_user(self.client.session), user_profile.id) self.assertEqual(get_session_dict_user(self.client.session), user_profile.id)
def test_redirect_to_next_url(self) -> None:
def do_local_login(formaction: Text) -> HttpResponse:
user_email = self.example_email('hamlet')
data = {'direct_email': user_email}
return self.client_post(formaction, data)
res = do_local_login('/accounts/login/local/')
self.assertEqual(res.status_code, 302)
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)
self.assertEqual(res.url, 'http://zulip.testserver/user_uploads/path_to_image')
def test_login_with_subdomain(self) -> None: def test_login_with_subdomain(self) -> None:
user_profile = self.example_user('hamlet') user_profile = self.example_user('hamlet')
email = user_profile.email email = user_profile.email

View File

@@ -16,6 +16,7 @@ from django.shortcuts import redirect, render
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_GET from django.views.decorators.http import require_GET
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils.http import is_safe_url
from django.core import signing from django.core import signing
import urllib import urllib
from typing import Any, Dict, List, Optional, Tuple, Text from typing import Any, Dict, List, Optional, Tuple, Text
@@ -47,6 +48,13 @@ import requests
import time import time
import ujson import ujson
def get_safe_redirect_to(url: Text, redirect_host: Text) -> Text:
is_url_safe = is_safe_url(url=url, host=redirect_host)
if is_url_safe:
return urllib.parse.urljoin(redirect_host, url)
else:
return redirect_host
def create_preregistration_user(email: Text, request: HttpRequest, realm_creation: bool=False, def create_preregistration_user(email: Text, request: HttpRequest, realm_creation: bool=False,
password_required: bool=True) -> HttpResponse: password_required: bool=True) -> HttpResponse:
realm = None realm = None
@@ -591,7 +599,10 @@ def dev_direct_login(request: HttpRequest, **kwargs: Any) -> HttpResponse:
if user_profile is None: if user_profile is None:
return HttpResponseRedirect(reverse('dev_not_supported')) return HttpResponseRedirect(reverse('dev_not_supported'))
do_login(request, user_profile) do_login(request, user_profile)
return HttpResponseRedirect(user_profile.realm.uri)
next = request.GET.get('next', '')
redirect_to = get_safe_redirect_to(next, user_profile.realm.uri)
return HttpResponseRedirect(redirect_to)
@csrf_exempt @csrf_exempt
@require_post @require_post