From 91f25b6ea1a5f84ac515a8a2f6246fa52ee5b290 Mon Sep 17 00:00:00 2001 From: Anand Chitipothu Date: Wed, 2 Feb 2011 15:18:39 +0530 Subject: [PATCH] refactor: moved permisison check into PermissionEngine class. Now it will be possible to overwrite the permisison check mechanism. --- infogami/infobase/writequery.py | 102 +++++++++++++++++++------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/infogami/infobase/writequery.py b/infogami/infobase/writequery.py index 9c52d514..188b2b25 100644 --- a/infogami/infobase/writequery.py +++ b/infogami/infobase/writequery.py @@ -11,11 +11,68 @@ def get_thing(store, key, revision=None): key = unicode(key) json = store.get(key, revision) return json and common.Thing.from_json(store, key, json) + +class PermissionEngine: + """Engine to check if a user has permission to modify a document. + """ + def __init__(self): + self.things = {} + + def get_thing(self, key): + try: + return self.things[key] + except KeyError: + t = get_thing(self.store, key) + self.things[key] = t + return t + + def has_permission(self, author, key): + # admin user can modify everything + if author and author.key == account.get_user_root() + 'admin': + return True + + permission = self.get_permission(key) + if permission is None: + return True + else: + groups = permission.get('writers') or [] + # admin users can edit anything + groups = groups + [self.get_thing('/usergroup/admin')] + for group in groups: + if group.key == '/usergroup/everyone': + return True + elif author is not None: + members = [m.key for m in group.get('members', [])] + if group.key == '/usergroup/allusers' or author.key in members: + return True + else: + return False + + def get_permission(self, key): + """Returns permission for the specified key.""" + def parent(key): + if key == "/": + return None + else: + return key.rsplit('/', 1)[0] or "/" + + def _get_permission(key, child_permission=False): + if key is None: + return None + thing = self.get_thing(key) + if child_permission: + permission = thing and (thing.get("child_permission") or thing.get("permission")) + else: + permission = thing and thing.get("permission") + return permission or _get_permission(parent(key), child_permission=True) + + return _get_permission(key) class SaveProcessor: def __init__(self, store, author): self.store = store self.author = author + self.permission_engine = PermissionEngine() self.things = {} @@ -137,6 +194,9 @@ def _process(self, key, data, prev_data=None): return None else: return data + + def has_permission(self, author, key): + return self.permission_engine.has_permission(author, key) def get_property(self, type, name): if name == 'type': @@ -221,48 +281,6 @@ def process_value(self, value, property, prefix=""): raise common.BadData(message='expected %s, found %s' % (property.expected_type.key, type_found), at=at, value=value) return value - def has_permission(self, author, key): - # admin user can modify everything - if author and author.key == account.get_user_root() + 'admin': - return True - - permission = self.get_permission(key) - if permission is None: - return True - else: - groups = permission.get('writers') or [] - # admin users can edit anything - groups = groups + [self.get_thing('/usergroup/admin')] - for group in groups: - if group.key == '/usergroup/everyone': - return True - elif author is not None: - members = [m.key for m in group.get('members', [])] - if group.key == '/usergroup/allusers' or author.key in members: - return True - else: - return False - - def get_permission(self, key): - """Returns permission for the specified key.""" - def parent(key): - if key == "/": - return None - else: - return key.rsplit('/', 1)[0] or "/" - - def _get_permission(key, child_permission=False): - if key is None: - return None - thing = self.get_thing(key) - if child_permission: - permission = thing and (thing.get("child_permission") or thing.get("permission")) - else: - permission = thing and thing.get("permission") - return permission or _get_permission(parent(key), child_permission=True) - - return _get_permission(key) - class WriteQueryProcessor: def __init__(self, store, author):