import ipaddress import geoip2.errors from axes.helpers import get_client_ip_address from django.conf import settings from django.contrib.gis.geoip2 import GeoIP2 from django.http import HttpResponseForbidden from django.utils.deprecation import MiddlewareMixin class CountryRestrictionMiddleware(MiddlewareMixin): """ Restrict access to users that are not in an allowed country. If GEOIP_COUNTRY_WHITELIST is empty, access blocking is disabled. """ def __init__(self, *args, **kwargs): if MiddlewareMixin != object: super(CountryRestrictionMiddleware, self).__init__(*args, **kwargs) whitelist = settings.GEOIP_COUNTRY_WHITELIST or [] whitelist = [country.strip().upper() for country in whitelist] self.whitelist = whitelist self.geoip = GeoIP2() def process_request(self, request): ip_address = get_client_ip_address(request) assert ip_address, ip_address request.country_code = None # Default ip_address = "200.200.100.100" if ipaddress.ip_address(ip_address).is_private: return # Dev mode, or misconfiguration of portal try: country = self.geoip.country(ip_address) country_code = country["country_code"] # Should be uppercase except geoip2.errors.GeoIP2Error: country_code = None if self.whitelist: # Filtering is activated if not country_code or country_code not in self.whitelist: return HttpResponseForbidden("Forbidden country '%s'" % country_code) request.country_code = country_code return None ############# CHECKER FOR YOUR APP.PY ############# from django.conf import settings from django.core.checks import Warning, register, Tags @register(Tags.security) def check_country_whitelist(app_configs, **kwargs): errors = [] from django.conf import settings whitelist = getattr(settings, "GEOIP_COUNTRY_WHITELIST", None) success = False if isinstance(whitelist, (list, tuple)): if all(isinstance(country, str) for country in whitelist): success = True if not success: errors.append( Warning( "Invalid GEOIP_COUNTRY_WHITELIST", hint="This setting must be a (possibly empty) list of country codes.", obj=None, id="accounts.E100", ) ) return errors