Skip to content

Commit a642e7a

Browse files
committed
GH-32: Fix the setting mixing case
1 parent 706163b commit a642e7a

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

src/django_forbid/skills/__init__.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,59 @@ def permitted(cls, attribute_type):
5050
"""Checks if the type is permitted."""
5151
return not cls.forbidden(attribute_type)
5252

53+
@staticmethod
54+
def getattr(attribute_type):
55+
"""Checks if the type has an attribute and parses it."""
56+
matching_attribute = re.match(r"^!(\w+):\w+$", attribute_type)
57+
return matching_attribute.group(1) if matching_attribute else None
58+
5359
def grants(self, attribute_type):
5460
# Creates a regular expression in the following form:
5561
# ^(?=PERMITTED_ATTRIBUTES)(?:(?!FORBIDDEN_ATTRIBUTES)\w+(?::\w+)?)$
5662
# where the list of forbidden and permitted attributes is determined
5763
# by filtering the particular setting attributes by the "!" prefix.
5864
permit = r"|".join(filter(self.permitted, self.attributes))
65+
permit = r"\w+" if any(filter(self.getattr, self.attributes)) else permit
5966
forbid = r"|".join(map(self.normalize, filter(self.forbidden, self.attributes)))
6067
forbid = r"(?!" + forbid + r")" if forbid else ""
6168
regexp = r"^(?=" + permit + r")(?:" + forbid + r"\w+(?::\w+)?)$"
6269

6370
# Regexp designed to match the permitted attributes.
6471
return re.match(regexp, attribute_type)
72+
73+
74+
continents_codes = {
75+
'AF': ['AS'], 'AL': ['EU'], 'AQ': ['AN'], 'DZ': ['AF'], 'AS': ['OC'], 'AD': ['EU'], 'AO': ['AF'], 'AG': ['NA'],
76+
'AZ': ['EU', 'AS'], 'AR': ['SA'], 'AU': ['OC'], 'AT': ['EU'], 'BS': ['NA'], 'BH': ['AS'], 'BD': ['AS'],
77+
'AM': ['EU', 'AS'], 'BB': ['NA'], 'BE': ['EU'], 'BM': ['NA'], 'BT': ['AS'], 'BO': ['SA'], 'BA': ['EU'],
78+
'BW': ['AF'], 'BV': ['AN'], 'BR': ['SA'], 'BZ': ['NA'], 'IO': ['AS'], 'SB': ['OC'], 'VG': ['NA'], 'BN': ['AS'],
79+
'BG': ['EU'], 'MM': ['AS'], 'BI': ['AF'], 'BY': ['EU'], 'KH': ['AS'], 'CM': ['AF'], 'CA': ['NA'], 'CV': ['AF'],
80+
'KY': ['NA'], 'CF': ['AF'], 'LK': ['AS'], 'TD': ['AF'], 'CL': ['SA'], 'CN': ['AS'], 'TW': ['AS'], 'CX': ['AS'],
81+
'CC': ['AS'], 'CO': ['SA'], 'KM': ['AF'], 'YT': ['AF'], 'CG': ['AF'], 'CD': ['AF'], 'CK': ['OC'], 'CR': ['NA'],
82+
'HR': ['EU'], 'CU': ['NA'], 'CY': ['EU', 'AS'], 'CZ': ['EU'], 'BJ': ['AF'], 'DK': ['EU'], 'DM': ['NA'],
83+
'DO': ['NA'], 'EC': ['SA'], 'SV': ['NA'], 'GQ': ['AF'], 'ET': ['AF'], 'ER': ['AF'], 'EE': ['EU'], 'FO': ['EU'],
84+
'FK': ['SA'], 'GS': ['AN'], 'FJ': ['OC'], 'FI': ['EU'], 'AX': ['EU'], 'FR': ['EU'], 'GF': ['SA'], 'PF': ['OC'],
85+
'TF': ['AN'], 'DJ': ['AF'], 'GA': ['AF'], 'GE': ['EU', 'AS'], 'GM': ['AF'], 'PS': ['AS'], 'DE': ['EU'],
86+
'GH': ['AF'], 'GI': ['EU'], 'KI': ['OC'], 'GR': ['EU'], 'GL': ['NA'], 'GD': ['NA'], 'GP': ['NA'], 'GU': ['OC'],
87+
'GT': ['NA'], 'GN': ['AF'], 'GY': ['SA'], 'HT': ['NA'], 'HM': ['AN'], 'VA': ['EU'], 'HN': ['NA'], 'HK': ['AS'],
88+
'HU': ['EU'], 'IS': ['EU'], 'IN': ['AS'], 'ID': ['AS'], 'IR': ['AS'], 'IQ': ['AS'], 'IE': ['EU'], 'IL': ['AS'],
89+
'IT': ['EU'], 'CI': ['AF'], 'JM': ['NA'], 'JP': ['AS'], 'KZ': ['EU', 'AS'], 'JO': ['AS'], 'KE': ['AF'],
90+
'KP': ['AS'], 'KR': ['AS'], 'KW': ['AS'], 'KG': ['AS'], 'LA': ['AS'], 'LB': ['AS'], 'LS': ['AF'], 'LV': ['EU'],
91+
'LR': ['AF'], 'LY': ['AF'], 'LI': ['EU'], 'LT': ['EU'], 'LU': ['EU'], 'MO': ['AS'], 'MG': ['AF'], 'MW': ['AF'],
92+
'MY': ['AS'], 'MV': ['AS'], 'ML': ['AF'], 'MT': ['EU'], 'MQ': ['NA'], 'MR': ['AF'], 'MU': ['AF'], 'MX': ['NA'],
93+
'MC': ['EU'], 'MN': ['AS'], 'MD': ['EU'], 'ME': ['EU'], 'MS': ['NA'], 'MA': ['AF'], 'MZ': ['AF'], 'OM': ['AS'],
94+
'NA': ['AF'], 'NR': ['OC'], 'NP': ['AS'], 'NL': ['EU'], 'AN': ['NA'], 'CW': ['NA'], 'AW': ['NA'], 'SX': ['NA'],
95+
'BQ': ['NA'], 'NC': ['OC'], 'VU': ['OC'], 'NZ': ['OC'], 'NI': ['NA'], 'NE': ['AF'], 'NG': ['AF'], 'NU': ['OC'],
96+
'NF': ['OC'], 'NO': ['EU'], 'MP': ['OC'], 'UM': ['OC', 'NA'], 'FM': ['OC'], 'MH': ['OC'], 'PW': ['OC'],
97+
'PK': ['AS'], 'PA': ['NA'], 'PG': ['OC'], 'PY': ['SA'], 'PE': ['SA'], 'PH': ['AS'], 'PN': ['OC'], 'PL': ['EU'],
98+
'PT': ['EU'], 'GW': ['AF'], 'TL': ['AS'], 'PR': ['NA'], 'QA': ['AS'], 'RE': ['AF'], 'RO': ['EU'], 'RW': ['AF'],
99+
'RU': ['EU', 'AS'], 'BL': ['NA'], 'SH': ['AF'], 'KN': ['NA'], 'AI': ['NA'], 'LC': ['NA'], 'MF': ['NA'],
100+
'PM': ['NA'], 'VC': ['NA'], 'SM': ['EU'], 'ST': ['AF'], 'SA': ['AS'], 'SN': ['AF'], 'RS': ['EU'], 'SC': ['AF'],
101+
'SL': ['AF'], 'SG': ['AS'], 'SK': ['EU'], 'VN': ['AS'], 'SI': ['EU'], 'SO': ['AF'], 'ZA': ['AF'], 'ZW': ['AF'],
102+
'ES': ['EU'], 'SS': ['AF'], 'EH': ['AF'], 'SD': ['AF'], 'SR': ['SA'], 'SJ': ['EU'], 'SZ': ['AF'], 'SE': ['EU'],
103+
'CH': ['EU'], 'SY': ['AS'], 'TJ': ['AS'], 'TH': ['AS'], 'TG': ['AF'], 'TK': ['OC'], 'TO': ['OC'], 'TT': ['NA'],
104+
'AE': ['AS'], 'TN': ['AF'], 'TR': ['EU', 'AS'], 'TM': ['AS'], 'TC': ['NA'], 'TV': ['OC'], 'UG': ['AF'],
105+
'UA': ['EU'], 'MK': ['EU'], 'EG': ['AF'], 'GB': ['EU'], 'GG': ['EU'], 'JE': ['EU'], 'IM': ['EU'], 'TZ': ['AF'],
106+
'US': ['NA'], 'VI': ['NA'], 'BF': ['AF'], 'UY': ['SA'], 'UZ': ['AS'], 'VE': ['SA'], 'WF': ['OC'], 'WS': ['OC'],
107+
'YE': ['AS'], 'ZM': ['AF'], 'XX': ['OC'], 'XE': ['AS'], 'XD': ['AS'], 'XS': ['AS']
108+
}

src/django_forbid/skills/forbid_location.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import itertools
2+
13
from django.conf import settings
24
from django.contrib.gis.geoip2 import GeoIP2
35
from django.http import HttpResponseForbidden
@@ -6,6 +8,7 @@
68

79
from . import Access
810
from . import Settings
11+
from . import continents_codes
912

1013

1114
class ForbidLocationMiddleware:
@@ -32,6 +35,13 @@ def __call__(self, request):
3235
territories = Settings.get("TERRITORIES", [])
3336
country_state_code = city.get("region")
3437
country_identifier = city.get("country_code")
38+
39+
if territories:
40+
# Adds the continent codes of the countries that are forbidden partially.
41+
territories = list({*territories, *itertools.chain.from_iterable(
42+
map(continents_codes.__getitem__, filter(bool, map(Access.getattr, countries)))
43+
)})
44+
3545
if country_state_code:
3646
country_identifier += ":%s" % country_state_code
3747
granted = all([

0 commit comments

Comments
 (0)