xbackend/utils/casbin/util/builtin_operators.py
2021-05-15 15:38:02 +08:00

138 lines
3.1 KiB
Python

import fnmatch
import re
import ipaddress
KEY_MATCH2_PATTERN = re.compile(r'(.*?):[^\/]+(.*?)')
KEY_MATCH3_PATTERN = re.compile(r'(.*?){[^\/]+}(.*?)')
def key_match(key1, key2):
"""determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
For example, "/foo/bar" matches "/foo/*"
"""
i = key2.find("*")
if i == -1:
return key1 == key2
if len(key1) > i:
return key1[:i] == key2[:i]
return key1 == key2[:i]
def key_match_func(*args):
"""The wrapper for key_match.
"""
name1 = args[0]
name2 = args[1]
return key_match(name1, name2)
def key_match2(key1, key2):
"""determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
For example, "/foo/bar" matches "/foo/*", "/resource1" matches "/:resource"
"""
key2 = key2.replace("/*", "/.*")
key2 = KEY_MATCH2_PATTERN.sub(r'\g<1>[^\/]+\g<2>', key2, 0)
return regex_match(key1, "^" + key2 + "$")
def key_match2_func(*args):
name1 = args[0]
name2 = args[1]
return key_match2(name1, name2)
def key_match3(key1, key2):
"""determines determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *.
For example, "/foo/bar" matches "/foo/*", "/resource1" matches "/{resource}"
"""
key2 = key2.replace("/*", "/.*")
key2 = KEY_MATCH3_PATTERN.sub(r'\g<1>[^\/]+\g<2>', key2, 0)
return regex_match(key1, "^" + key2 + "$")
def key_match3_func(*args):
name1 = args[0]
name2 = args[1]
return key_match3(name1, name2)
def regex_match(key1, key2):
"""determines whether key1 matches the pattern of key2 in regular expression."""
res = re.match(key2, key1)
if res:
return True
else:
return False
def regex_match_func(*args):
"""the wrapper for RegexMatch."""
name1 = args[0]
name2 = args[1]
return regex_match(name1, name2)
def glob_match(string, pattern):
"""determines whether string matches the pattern in glob expression."""
return fnmatch.fnmatch(string, pattern)
def glob_match_func(*args):
"""the wrapper for globMatch."""
string = args[0]
pattern = args[1]
return glob_match(string, pattern)
def ip_match(ip1, ip2):
"""IPMatch determines whether IP address ip1 matches the pattern of IP address ip2, ip2 can be an IP address or a CIDR pattern.
For example, "192.168.2.123" matches "192.168.2.0/24"
"""
ip1 = ipaddress.ip_address(ip1)
try:
network = ipaddress.ip_network(ip2, strict=False)
return ip1 in network
except ValueError:
return ip1 == ip2
def ip_match_func(*args):
"""the wrapper for IPMatch."""
ip1 = args[0]
ip2 = args[1]
return ip_match(ip1, ip2)
def generate_g_function(rm):
"""the factory method of the g(_, _) function."""
def f(*args):
name1 = args[0]
name2 = args[1]
if not rm:
return name1 == name2
elif 2 == len(args):
return rm.has_link(name1, name2)
else:
domain = str(args[2])
return rm.has_link(name1, name2, domain)
return f