If you're into Zope python product stuff, read on, otherwise don't bother.

Thanks to Brian Lloyd (Zope corp) and Florent Guillaume (Nuxeo) I now know how to set security declarations on a class outside the class. It doesn't work like a normal python class (new or old style) which was a bit of a surprise. This is how you do it in a "normal" python class:


class _Z:
  def __init__(self):
      self.z = "Z"
  def declareProtected(self, *a,**k):
      print "++declare something+"

def foo():
  print "I'm being called"
  return _Z()

class A:
  security=foo()
  def __init__(self):
      pass
A.security.declareProtected("foo")

When you import or run that it spits out:


I'm being called
++declare something+

Now imagine this python product class:


class MyProduct(OFS.Folder):
   security=ClassSecurityInfo()
   security.declareProtected('View', 'rss')
   def rss(self):

setattr(MyProduct, 'rss.xml', MyProduct.rss)
MyProduct.security.declareProtected('View', 'rss.xml')

Apart from the last line this should look very familiar to Zope python product developers. In principle it's the same as the dummy example above, but it doesn't work. You get an AttributeError on security on that last line.

As Florent explains:

"That's because for all classes deriving from ExtensionClass there's a magical call (indirectly) to InitializeClass as soon as they are defined. That's one of the numerous things Jim pioneered with ExtensionClasses, at a time where metaclasses didn't exist."

Thanks to Brians tips I've now found the correct way of doing it which is this:


class MyProduct(OFS.Folder):
   security=ClassSecurityInfo()
   security.declareProtected('View', 'rss')
   def rss(self):

setattr(MyProduct, 'rss.xml', MyProduct.rss)
#MyProduct.security.declareProtected('View', 'rss.xml')
security = ClassSecurityInfo()
security.declareProtected('View', 'rss.xml')
security.apply(MyProduct)

Worth remembering because with more recent version of Zope2 you get annoying warning messages if you declare security settings on methods that aren't defined until (perhaps in a loop) after the class has been defined.

Thanks for the advice guys!

Comments

xet7

Do you know how to use Zope:s Python code protection outside Zope? So that I could run restricted Python code? I only know about http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286134 Python recipe but I'd like to know if there's faster way.

Peter Bengtsson

I don't I'm afraid. Your first bet is to start looking at the Zope3 accesscontrol code which is I think is much more modular than that of Zope2.

Peter Bengtsson

You might want to look at setting decorators on methods and in the decorator code, do your ad hoc security checks. Look at how TurboGears does it maybe.

xet7

Ok, I'm reading http://trac.turbogears.org/turbogears/wiki/IdentityManagement and trying to figure out how it works...

bobpooch

This works great. The key is security.apply(), that was the piece I was missing.

Your email will never ever be published.

Related posts