always invoke caller_my_access_tag
[plcapi.git] / PLC / Accessors / Factory.py
index c6e87f3..b1ef299 100644 (file)
@@ -21,9 +21,6 @@ from PLC.SiteTags import SiteTags, SiteTag
 from PLC.Persons import Persons, Person
 from PLC.PersonTags import PersonTags, PersonTag
 
-# this is another story..
-#from PLC.Ilinks import Ilink
-
 # known classes : { class -> details }
 taggable_classes = { Node : {'table_class' : Nodes,
                              'joins_class' : NodeTags, 'join_class' : NodeTag,
@@ -40,7 +37,6 @@ taggable_classes = { Node : {'table_class' : Nodes,
                      Person: {'table_class' : Persons,
                              'joins_class': PersonTags, 'join_class': PersonTag,
                              'secondary_key':'email'},
-#                     Ilink : xxx
                      }
 
 # xxx probably defined someplace else
@@ -70,6 +66,9 @@ tech_roles = [ 'admin', 'pi', 'tech' ]
 # named min_role_id; this was redundant and confusing, it has been
 # removed, we now use set_roles to restrict access on the corresponding tag
 
+# the convention here is that methodsuffix should be mixed case, e.g. MyStuff
+# while tagname is expected to be lowercase
+# you then end up with e.g. GetPersonMyStuff
 def define_accessors (module, objclass, methodsuffix, tagname,
                       category, description,
                       get_roles=all_roles, set_roles=admin_roles, 
@@ -114,12 +113,14 @@ def define_accessors (module, objclass, methodsuffix, tagname,
     setattr(get_class,'roles',get_roles)
     setattr(get_class,'accepts',get_accepts)
     setattr(get_class,'returns', get_returns)
-    setattr(get_class,'skip_typecheck',True)
+# that was useful for legacy method only, but we now need type_checking
+#    setattr(get_class,'skip_type_check',True)
 
     setattr(set_class,'roles',set_roles)
     setattr(set_class,'accepts',set_accepts)
     setattr(set_class,'returns', set_returns)
-    setattr(set_class,'skip_typecheck',True)
+# that was useful for legacy method only, but we now need type_checking
+#    setattr(set_class,'skip_type_check',True)
 
     table_class = taggable_classes[objclass]['table_class']
     joins_class = taggable_classes[objclass]['joins_class']
@@ -140,7 +141,8 @@ def define_accessors (module, objclass, methodsuffix, tagname,
     def get_call (self, auth, id_or_name):
         # locate the tag, see above
         locator = getattr(Accessor,locator_name)
-        tag_type_id = locator(AccessorSingleton(self.api))
+        tag_type = locator(AccessorSingleton(self.api))
+        tag_type_id=tag_type['tag_type_id']
 
         filter = {'tag_type_id':tag_type_id}
         if isinstance (id_or_name,int):
@@ -164,16 +166,26 @@ def define_accessors (module, objclass, methodsuffix, tagname,
             filter={primary_key:id_or_name}
         else:
             filter={secondary_key:id_or_name}
-        objs = table_class(self.api, filter,[primary_key,secondary_key])
+# we need the full monty b/c of the permission system
+#        objs = table_class(self.api, filter,[primary_key,secondary_key])
+        objs = table_class(self.api, filter)
         if not objs:
             raise PLCInvalidArgument, "Cannot set tag on %s %r"%(objclass.__name__,id_or_name)
-        primary_id = objs[0][primary_key]
+        # the object being tagged
+        obj=objs[0]
+        primary_id = obj[primary_key]
 
         # locate the tag, see above
         locator = getattr(Accessor,locator_name)
-        tag_type_id = locator(AccessorSingleton(self.api))
+        tag_type = locator(AccessorSingleton(self.api))
+        tag_type_id = tag_type['tag_type_id']
+
+        # check authorization
+        if not hasattr(objclass,'caller_may_write_tag'):
+            raise PLCAuthenticationFailure, "class %s misses method caller_may_write_tag"%objclass.__name__
+        obj.caller_may_write_tag (self.api,self.caller,tag_type)
 
-        # locate the join object (e.g. NodeTag, SliceTag or InterfaceTag)
+        # locate the join object (e.g. NodeTag or similar)
         filter = {'tag_type_id':tag_type_id}
         if isinstance (id_or_name,int):
             filter[primary_key]=id_or_name