From 3d24ee2242cf6e3206836fc8377c4ff5ea6e4ef9 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 10 Jun 2012 21:46:00 +0200 Subject: [PATCH] Added a secure_attr() method to the base typeclass. This allows for system to access attributes with full access control (since it requires an accessing_obj as argument). This relies on (by default unused) lock types "readattr" (reading/listing the attr value), "editattr" (editing/deleting the attribute) and finally "createattr" for creating a new attribute. The first two checks are done directly on the Attribute class whereas the createattr check is done on the TypedObject on which the Attribute is to be stored. --- src/typeclasses/models.py | 63 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/typeclasses/models.py b/src/typeclasses/models.py index 0f3f32a766..5ce28f9954 100644 --- a/src/typeclasses/models.py +++ b/src/typeclasses/models.py @@ -1282,6 +1282,20 @@ class TypedObject(SharedMemoryModel): attrib_obj.value = new_value _ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name] = attrib_obj + def get_attribute_obj(self, attribute_name, default=None): + """ + Get the actual attribute object named attribute_name + """ + attrib_obj = _ATTRIBUTE_CACHE[_GA(self, "hashid")].get(attribute_name) + if not attrib_obj: + attrib_obj = _GA(self, "_attribute_class").objects.filter( + db_obj=self).filter(db_key__iexact=attribute_name) + if not attrib_obj: + return default + _ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name] = attrib_obj[0] #query is first evaluated here + return _ATTRIBUTE_CACHE[_GA(self, "hashid")][attribute_name] + return attrib_obj + def get_attribute(self, attribute_name, default=None): """ Returns the value of an attribute on an object. You may need to @@ -1384,6 +1398,55 @@ class TypedObject(SharedMemoryModel): # act as a setter self.set_attribute(attribute_name, value) + def secure_attr(self, accessing_object, attribute_name=None, value=None, delete=False, + default_access_read=True, default_access_edit=True, default_access_create=True): + """ + This is a version of attr that requires the accessing object + as input and will use that to check eventual access locks on + the Attribute before allowing any changes or reads. + + In the cases when this method wouldn't return, it will return + True for a successful operation, None otherwise. + + locktypes checked on the Attribute itself: + attrread - control access to reading the attribute value + attredit - control edit/delete access + locktype checked on the object on which the Attribute is/will be stored: + attrcreate - control attribute create access (this is checked *on the object* not on the Attribute!) + + default_access_* defines which access is assumed if no + suitable lock is defined on the Atttribute. + + """ + if attribute_name == None: + # act as list method, but check access + return [attr for attr in self.get_all_attributes() + if attr.access(accessing_object, "attread", default=default_access_read)] + elif delete == True: + # act as deleter + attr = self.get_attribute_obj(attribute_name) + if attr and attr.access(accessing_object, "attredit", default=default_access_edit): + self.del_attribute(attribute_name) + return True + elif value == None: + # act as getter + attr = self.get_attribute_obj(attribute_name) + if attr and attr.access(accessing_object, "attrread", default=default_access_read): + return attr.value + else: + # act as setter + attr = self.get_attribute_obj(attribute_name) + if attr: + # attribute already exists + if attr.access(accessing_object, "attredit", default=default_access_edit): + self.set_attribute(attribute_name, value) + return True + else: + # creating a new attribute - check access on storing object! + if self.access(accessing_object, "attrcreate", default=default_access_create): + self.set_attribute(attribute_name, value) + return True + #@property def __db_get(self): """