mirror of
https://github.com/jazzband/django-defender.git
synced 2026-03-16 22:10:32 +00:00
Merge branch 'jazzband:master' into master
This commit is contained in:
commit
7239548951
10 changed files with 83 additions and 14 deletions
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
|
|
@ -9,7 +9,7 @@ jobs:
|
|||
fail-fast: false
|
||||
max-parallel: 5
|
||||
matrix:
|
||||
python-version: ['3.6', '3.7', '3.8', '3.9', '3.10', 'pypy-3.8-v7.3.7']
|
||||
python-version: ['3.7', '3.8', '3.9', '3.10', 'pypy-3.8']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
|
|
|||
15
CHANGES.rst
15
CHANGES.rst
|
|
@ -2,9 +2,24 @@
|
|||
Changes
|
||||
=======
|
||||
|
||||
0.9.4
|
||||
-----
|
||||
|
||||
- Remove port number from IP address string when behind reverse proxy [@ndrsn]
|
||||
|
||||
0.9.3
|
||||
-----
|
||||
|
||||
- Drop Python 3.6 support from package specifiers.
|
||||
|
||||
0.9.2
|
||||
-----
|
||||
|
||||
- Drop Python 3.6 support.
|
||||
- Drop Django 3.1 support.
|
||||
- Confirm support for Django 4.0
|
||||
- Confirm support for Python 3.10
|
||||
- Drop Django 2.2 support.
|
||||
|
||||
0.9.1
|
||||
-----
|
||||
|
|
|
|||
|
|
@ -108,8 +108,8 @@ Admin pages
|
|||
Requirements
|
||||
------------
|
||||
|
||||
* Python: 3.6, 3.7, 3.8, 3.9, 3.10, PyPy
|
||||
* Django: 2.2, 3.x, 4.x
|
||||
* Python: 3.7, 3.8, 3.9, 3.10, PyPy
|
||||
* Django: 3.x, 4.x
|
||||
* Redis
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
VERSION = (0, 9, 1)
|
||||
VERSION = (0, 9, 4)
|
||||
|
||||
__version__ = ".".join((map(str, VERSION)))
|
||||
|
|
|
|||
|
|
@ -45,12 +45,11 @@ TEMPLATES = [
|
|||
"django.template.context_processors.static",
|
||||
"django.template.context_processors.tz",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
"django.template.context_processors.request",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
if django.VERSION >= (3, 2):
|
||||
TEMPLATES[0]["OPTIONS"]["context_processors"].append("django.template.context_processors.request")
|
||||
|
||||
SECRET_KEY = os.environ.get("SECRET_KEY", "too-secret-for-test")
|
||||
|
||||
|
|
|
|||
|
|
@ -41,12 +41,11 @@ TEMPLATES = [
|
|||
"django.template.context_processors.static",
|
||||
"django.template.context_processors.tz",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
"django.template.context_processors.request",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
if django.VERSION >= (3, 2):
|
||||
TEMPLATES[0]["OPTIONS"]["context_processors"].append("django.template.context_processors.request")
|
||||
|
||||
SECRET_KEY = os.environ.get("SECRET_KEY", "too-secret-for-test")
|
||||
|
||||
|
|
|
|||
|
|
@ -1075,3 +1075,27 @@ class TestUtils(DefenderTestCase):
|
|||
|
||||
utils.add_login_attempt_to_db(request, True, username=username)
|
||||
self.assertEqual(AccessAttempt.objects.filter(username=username).count(), 1)
|
||||
|
||||
def test_ip_address_strip_port_number(self):
|
||||
""" Test the strip_port_number() method """
|
||||
# IPv4 with/without port
|
||||
self.assertEqual(utils.strip_port_number("192.168.1.1"), "192.168.1.1")
|
||||
self.assertEqual(utils.strip_port_number(
|
||||
"192.168.1.1:8000"), "192.168.1.1")
|
||||
|
||||
# IPv6 with/without port
|
||||
self.assertEqual(utils.strip_port_number(
|
||||
"2001:db8:85a3:0:0:8a2e:370:7334"), "2001:db8:85a3:0:0:8a2e:370:7334")
|
||||
self.assertEqual(utils.strip_port_number(
|
||||
"[2001:db8:85a3:0:0:8a2e:370:7334]:123456"), "2001:db8:85a3:0:0:8a2e:370:7334")
|
||||
|
||||
@patch("defender.config.BEHIND_REVERSE_PROXY", True)
|
||||
def test_get_ip_strips_port_number(self):
|
||||
""" make sure the IP address is stripped of its port number """
|
||||
req = HttpRequest()
|
||||
req.META["HTTP_X_FORWARDED_FOR"] = "1.2.3.4:123456"
|
||||
self.assertEqual(utils.get_ip(req), "1.2.3.4")
|
||||
|
||||
req = HttpRequest()
|
||||
req.META["HTTP_X_FORWARDED_FOR"] = "[2001:db8::1]:123456"
|
||||
self.assertEqual(utils.get_ip(req), "2001:db8::1")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
import re
|
||||
|
||||
from django.http import HttpResponse
|
||||
from django.http import HttpResponseRedirect
|
||||
|
|
@ -43,15 +44,51 @@ def get_ip_address_from_request(request):
|
|||
return "127.0.0.1"
|
||||
|
||||
|
||||
ipv4_with_port = re.compile(r"^(\d+\.\d+\.\d+\.\d+):\d+")
|
||||
ipv6_with_port = re.compile(r"^\[([^\]]+)\]:\d+")
|
||||
|
||||
|
||||
def strip_port_number(ip_address_string):
|
||||
""" strips port number from IPv4 or IPv6 address """
|
||||
ip_address = None
|
||||
|
||||
if ipv4_with_port.match(ip_address_string):
|
||||
match = ipv4_with_port.match(ip_address_string)
|
||||
ip_address = match[1]
|
||||
elif ipv6_with_port.match(ip_address_string):
|
||||
match = ipv6_with_port.match(ip_address_string)
|
||||
ip_address = match[1]
|
||||
|
||||
"""
|
||||
If it's not a valid IP address, we prefer to return
|
||||
the string as-is instead of returning a potentially
|
||||
corrupted string:
|
||||
"""
|
||||
if is_valid_ip(ip_address):
|
||||
return ip_address
|
||||
|
||||
return ip_address_string
|
||||
|
||||
|
||||
def get_ip(request):
|
||||
""" get the ip address from the request """
|
||||
if config.BEHIND_REVERSE_PROXY:
|
||||
ip_address = request.META.get(config.REVERSE_PROXY_HEADER, "")
|
||||
ip_address = ip_address.split(",", 1)[0].strip()
|
||||
|
||||
if ip_address == "":
|
||||
ip_address = get_ip_address_from_request(request)
|
||||
else:
|
||||
"""
|
||||
Some reverse proxies will include a port number with the
|
||||
IP address; as this port may change from request to request,
|
||||
and thus make it appear to be different IP addresses, we'll
|
||||
want to remove the port number, if present:
|
||||
"""
|
||||
ip_address = strip_port_number(ip_address)
|
||||
else:
|
||||
ip_address = get_ip_address_from_request(request)
|
||||
|
||||
return ip_address
|
||||
|
||||
|
||||
|
|
|
|||
3
setup.py
3
setup.py
|
|
@ -31,7 +31,6 @@ setup(
|
|||
classifiers=[
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Framework :: Django",
|
||||
"Framework :: Django :: 2.2",
|
||||
"Framework :: Django :: 3.2",
|
||||
"Framework :: Django :: 4.0",
|
||||
"Intended Audience :: Developers",
|
||||
|
|
@ -40,8 +39,6 @@ setup(
|
|||
"Programming Language :: Python",
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3 :: Only',
|
||||
"Programming Language :: Python :: 3.5",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
"Programming Language :: Python :: 3.7",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
|
|
|
|||
4
tox.ini
4
tox.ini
|
|
@ -1,13 +1,12 @@
|
|||
[tox]
|
||||
envlist =
|
||||
# list of supported Django/Python versions:
|
||||
py{36,37,38,39,py3}-dj{22,32}
|
||||
py{37,38,39,py3}-dj{32}
|
||||
py{38,39,310}-dj{40,main}
|
||||
py38-{lint,docs}
|
||||
|
||||
[gh-actions]
|
||||
python =
|
||||
3.6: py36
|
||||
3.7: py37
|
||||
3.8: py38
|
||||
3.9: py39
|
||||
|
|
@ -17,7 +16,6 @@ python =
|
|||
[testenv]
|
||||
deps =
|
||||
-rrequirements.txt
|
||||
dj22: django>=2.2,<2.3
|
||||
dj32: django>=3.2,<4.0
|
||||
dj40: django>=4.0,<4.1
|
||||
djmain: https://github.com/django/django/archive/main.tar.gz
|
||||
|
|
|
|||
Loading…
Reference in a new issue