blob: 7fc6a0244eb16b9fef3fc837e2393cb03bf54e22 [file] [log] [blame]
from fnmatch import fnmatch
class AccessControlList:
def __init__(self, aclText=None):
self.rules = []
if aclText:
self.import_text(aclText)
def import_text(self, aclText):
# allow either newline or ';' to separate rules
aclText = aclText.replace("\n", ";")
for line in aclText.split(";"):
line = line.strip()
if line.startswith("#"):
continue
if line=="":
continue
parts = line.split()
if len(parts)==2 and (parts[1]=="all"):
# "allow all" has no pattern
parts = (parts[0], parts[1], "")
if len(parts)!=3:
raise ACLValidationError(line)
(action, object, pattern) = parts
if action not in ["allow", "deny"]:
raise ACLValidationError(line)
if object not in ["site", "user", "all"]:
raise ACLValidationError(line)
self.rules.append( (action, object, pattern) )
def __str__(self):
lines = []
for rule in self.rules:
lines.append( " ".join(rule) )
return ";\n".join(lines)
def test(self, user):
for rule in self.rules:
if self.match_rule(rule, user):
return rule[0]
return "deny"
def match_rule(self, rule, user):
(action, object, pattern) = rule
if (object == "site"):
if fnmatch(user.site.name, pattern):
return True
elif (object == "user"):
if fnmatch(user.email, pattern):
return True
elif (object == "all"):
return True
return False
if __name__ == '__main__':
class fakesite:
def __init__(self, siteName):
self.name = siteName
class fakeuser:
def __init__(self, email, siteName):
self.email = email
self.site = fakesite(siteName)
u_scott = fakeuser("scott@onlab.us", "ON.Lab")
u_bill = fakeuser("bill@onlab.us", "ON.Lab")
u_andy = fakeuser("acb@cs.princeton.edu", "Princeton")
u_john = fakeuser("jhh@cs.arizona.edu", "Arizona")
u_hacker = fakeuser("somehacker@foo.com", "Not A Real Site")
# check the "deny all" rule
acl = AccessControlList("deny all")
assert(acl.test(u_scott) == "deny")
# a blank ACL results in "deny all"
acl = AccessControlList("")
assert(acl.test(u_scott) == "deny")
# check the "allow all" rule
acl = AccessControlList("allow all")
assert(acl.test(u_scott) == "allow")
# allow only one site
acl = AccessControlList("allow site ON.Lab")
assert(acl.test(u_scott) == "allow")
assert(acl.test(u_andy) == "deny")
# some complicated ACL
acl = AccessControlList("""allow site Princeton
allow user *@cs.arizona.edu
deny site Arizona
deny user scott@onlab.us
allow site ON.Lab""")
assert(acl.test(u_scott) == "deny")
assert(acl.test(u_bill) == "allow")
assert(acl.test(u_andy) == "allow")
assert(acl.test(u_john) == "allow")
assert(acl.test(u_hacker) == "deny")
print acl