mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
views: Drop use of private Django utility
We are currently using django.utils.http.is_safe_url which is a private method and may break API anytime. Replace it with similar but limited implementation. Tests: - Unit tests. - Dismiss a notification and the redirect to the same page happens properly. - Logout, goto to home page or login page. Change the language and it will redirect back to home page or login page appropriately. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
5a126e62a8
commit
6f30e12cd7
31
plinth/tests/test_views.py
Normal file
31
plinth/tests/test_views.py
Normal file
@ -0,0 +1,31 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
"""
|
||||
Tests for common FreedomBox views.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from plinth.views import is_safe_url
|
||||
|
||||
|
||||
@pytest.mark.parametrize('url', [
|
||||
'/plinth/login/',
|
||||
'/',
|
||||
'safe',
|
||||
])
|
||||
def test_is_safe_url_valid_url(url):
|
||||
"""Test valid URLs for safe URL checks."""
|
||||
assert is_safe_url(url)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('url', [
|
||||
'',
|
||||
None,
|
||||
'\\plinth',
|
||||
'///plinth',
|
||||
'https://example.com/plinth/login/',
|
||||
'https:///plinth/login',
|
||||
])
|
||||
def test_is_safe_url_invalid_url(url):
|
||||
"""Test invalid URLs for safe URL checks."""
|
||||
assert not is_safe_url(url)
|
||||
@ -4,13 +4,13 @@ Main FreedomBox views.
|
||||
"""
|
||||
|
||||
import time
|
||||
import urllib.parse
|
||||
|
||||
from django.contrib import messages
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.http import Http404, HttpResponseBadRequest, HttpResponseRedirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.urls import reverse
|
||||
from django.utils.http import is_safe_url
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.views.generic import TemplateView
|
||||
from django.views.generic.edit import FormView
|
||||
@ -26,11 +26,35 @@ from . import forms, frontpage
|
||||
REDIRECT_FIELD_NAME = 'next'
|
||||
|
||||
|
||||
def is_safe_url(url):
|
||||
"""Check if the URL is safe to redirect to.
|
||||
|
||||
Based on Django internal utility.
|
||||
|
||||
"""
|
||||
if url is not None:
|
||||
url = url.strip()
|
||||
|
||||
if not url:
|
||||
return False
|
||||
|
||||
if '\\' in url or url.startswith('///'):
|
||||
return False
|
||||
|
||||
result = urllib.parse.urlparse(url)
|
||||
|
||||
# Only accept URLs to the same site and scheme.
|
||||
if result.scheme or result.netloc:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _get_redirect_url_from_param(request):
|
||||
"""Return the redirect URL from 'next' GET/POST param."""
|
||||
redirect_to = request.GET.get(REDIRECT_FIELD_NAME, '')
|
||||
redirect_to = request.POST.get(REDIRECT_FIELD_NAME, redirect_to)
|
||||
if is_safe_url(url=redirect_to, allowed_hosts={request.get_host()}):
|
||||
if is_safe_url(redirect_to):
|
||||
return redirect_to
|
||||
|
||||
return reverse('index')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user