middleware: allow CIDR blocks in maintenance passthrough IPs (#71555)

This commit is contained in:
Paul Marillonnet 2022-11-22 13:53:52 +01:00
parent 1c6b5ac6ee
commit f46f421cf7
2 changed files with 22 additions and 0 deletions

View File

@ -14,6 +14,8 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from ipaddress import ip_address, ip_network
from django.conf import settings
from django.template.response import TemplateResponse
from django.utils.translation import ugettext as _
@ -25,6 +27,13 @@ def pass_through(request):
pass_through_ips = getattr(settings, 'MAINTENANCE_PASS_THROUGH_IPS', [])
if remote_addr in pass_through_ips:
return True
else:
for network in [x for x in pass_through_ips if '/' in x]:
try:
if ip_address(remote_addr) in ip_network(network, strict=False):
return True
except ValueError: # bad remote_addr or network syntax
pass
pass_through_header = getattr(settings, 'MAINTENANCE_PASS_THROUGH_HEADER', '')
if pass_through_header and pass_through_header in request.headers:
return True

View File

@ -25,8 +25,21 @@ def test_maintenance_middleware(app, admin_user, db, monkeypatch, settings):
resp = app.get('/')
assert resp.status_code == 200
settings.MAINTENANCE_PASS_THROUGH_IPS = ['127.0.0.100', '127.0.0.0/16']
resp = app.get('/')
assert resp.status_code == 200
settings.MAINTENANCE_PASS_THROUGH_IPS = ['127.0.0.1/4'] # lenient ipaddress.ip_network parsing
app.get('/')
assert resp.status_code == 200
settings.MAINTENANCE_PASS_THROUGH_IPS = ['128.0.0.0/24']
resp = app.get('/', status=503)
assert 'foobar' in resp.text
settings.MAINTENANCE_PASS_THROUGH_IPS = []
resp = app.get('/', status=503)
assert 'foobar' in resp.text
settings.MAINTENANCE_PASS_THROUGH_HEADER = 'X-Entrouvert'
resp = app.get('/', headers={'X-Entrouvert': 'yes'})