The artist formerly known as CreatePostView is a little more generic now and outsources its ban check to a new util method, is_banned. Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
48 lines
1.4 KiB
Python
48 lines
1.4 KiB
Python
from typing import TYPE_CHECKING
|
|
from django.utils import timezone
|
|
import ipaddress
|
|
|
|
from board.models import Ban, RangeBan
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
from board.models import Board
|
|
|
|
|
|
def get_client_ip(request):
|
|
"Get the IP address of a client-side request. Shamelessly copy/pasted from StackOverflow."
|
|
x_forwarded_for = request.META.get("HTTP_X_FORWARDED_FOR")
|
|
if x_forwarded_for:
|
|
ip = x_forwarded_for.split(",")[0]
|
|
else:
|
|
ip = request.META.get("REMOTE_ADDR")
|
|
return ip
|
|
|
|
|
|
def get_ip_bans(ip: str) -> list:
|
|
bans = list(Ban.objects.filter(ip=ip))
|
|
|
|
ip_addr = ipaddress.ip_address(ip)
|
|
for rangeban in RangeBan.objects.all():
|
|
start = ipaddress.ip_address(rangeban.start)
|
|
end = ipaddress.ip_address(rangeban.end)
|
|
if ip_addr.version != start.version or ip_addr.version != end.version:
|
|
continue
|
|
if start <= ip_addr <= end: # type: ignore
|
|
bans += [rangeban]
|
|
return bans
|
|
|
|
|
|
def is_banned(ip: str, board: "Board" | None) -> bool:
|
|
now = timezone.now()
|
|
bans = [ban for ban in get_ip_bans(ip) if ban.board == board or not ban.board]
|
|
if bans:
|
|
active = [ban for ban in bans if ban.expires > now]
|
|
expired = [ban for ban in bans if ban.expires <= now]
|
|
# Delete expired bans
|
|
for ban in expired:
|
|
ban.delete()
|
|
return bool(active)
|
|
else:
|
|
return False
|