Setting security declarations to Zope classes

02 February 2006   5 comments   Zope, Python

Powered by Fusion×

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.
Thank you for posting a comment

Your email will never ever be published


Related posts

Previous:
ReCSS a tool to reload the CSS without reloading the whole page 31 January 2006
Next:
Size comparison of Zope3, Django and TurboGears 04 February 2006