[Zope] zope3, browser:addMenuItem, ZCML factory => ForbiddenAttribute: ('__call__', <...>)
KLEIN Stéphane
stephane at harobed.org
Fri Sep 19 19:30:21 EDT 2008
Hi,
I had some difficulty to use "browser:addMenuItem" ZCML directive :
<browser:addMenuItem
factory="myproject.MyContent"
title="MyContent"
permission="zope.ManageContent"
/>
with my Factory :
<utility
factory=".mycontent.MyContentFactory"
name="myproject.MyContent"
permission="zope.Public"
/>
mycontent.py file :
from zope.component.interfaces import IFactory
...
class MyContentFactory(object):
implements(IFactory)
title = u"Create a new MyContent"
description = u"This factory instantiates new MyContent"
def __call__(self):
return MyContent()
def getInterfaces(self):
return implementedBy(MyContent)
Now, if I try to append a MyContent object through ZMI I've this error :
File "/home/harobed/buildout-eggs/zope.app.container-3.6.0-py2.4-linux-
i686.egg/zope/app/container/browser/adding.py", line 145, in action
content = factory()
File "/home/harobed/buildout-eggs/zope.security-3.5.2-py2.4-linux-
i686.egg/zope/security/checker.py", line 463, in check
self._checker2.check(object, name)
ForbiddenAttribute: ('__call__', <myproject.mycontent.MyContentFactory
object at 0x93f5b0c>)
Well, if I look in zope/app/container/browser/adding.py, in Adding.action
method I see this comment :
# TODO: If the factory wrapped by LocationProxy is already a
Proxy,
# then ProxyFactory does not do the right thing and the
# original's checker info gets lost. No factory that was
# registered via ZCML and was used via addMenuItem worked
# here. (SR)
I think "No factory that was registered via ZCML and was used via
addMenuItem worked here" speak about my issue ?
I've looked in zope.app.container browser test and I found this tip :
mycontent.py file fixed with the tip :
from zope.component.interfaces import IFactory
import zope.security.checker
...
class MyContentFactory(object):
implements(IFactory)
title = u"Create a new MyContent"
description = u"This factory instantiates new MyContent"
def __init__(self):
self.__Security_checker__ = zope.security.checker.NamesChecker
(['__call__'])
def __call__(self):
return MyContent()
def getInterfaces(self):
return implementedBy(MyContent)
With this __Security_checker__ property my issue is fixed, now I can add
a MyContent object through ZMI.
Now, I've some comment and question about it :
* I think this tip isn't "developer friendly", what is the good method ?
* Philipp von Weitershausen's book (Web Component Development with Zope
3) give first version of my example (without __Security_checker__ tip)
and its example didn't working with zope 3.4 (zopeproject use). Why this
compatibility breaking ?
Regards,
Stephane
More information about the Zope
mailing list