HI, list:

I am new to z3c.form. In my first AddForm, I encountered the following problem:

When the form is submitted which contains some input error, like
missing required fields, the rendering of the error message causes an
system error. The traceback:

...
  File 
"/usr/lib/python2.5/site-packages/zope.app.pagetemplate-3.4.0b1dev_r75616-py2.5.egg/zope/app/pagetemplate/engine.py",
line 68, in __call__
    request=request)
  File 
"/usr/lib/python2.5/site-packages/zope.traversing-3.5.0a1.dev_r78730-py2.5.egg/zope/traversing/adapters.py",
line 164, in traversePathElement
    return traversable.traverse(nm, further_path)
   - __traceback_info__: (<ErrorViewSnippet for RequiredMissing>, 'widget')
  File 
"/usr/lib/python2.5/site-packages/zope.traversing-3.5.0a1.dev_r78730-py2.5.egg/zope/traversing/adapters.py",
line 52, in traverse
    raise TraversalError(subject, name)
   - __traceback_info__: (<ErrorViewSnippet for RequiredMissing>, 'widget', [])
TraversalError: (<ErrorViewSnippet for RequiredMissing>, 'widget')

After a little debugging, I was able to find that the chain leading to
the error is as follows:

1. div-form.pt in the z3c.formui package contains the following error
presentation:

  <li tal:repeat="error view/widgets/errors">
    <tal:block condition="error/widget">
      <span tal:replace="error/widget/label" />:
    </tal:block>
    <span tal:replace="structure error/render">Error Type</span>
  </li>

error/widget is accessed here, with error being an ErrorViewSnippet object.

2. The ErrorViewSnipped is created in field.py using:

  view = zope.component.getMultiAdapter(
      (error, self.request, widget, widget.field,
       self.form, self.content), interfaces.IErrorViewSnippet)

As in my application, self.content is a custom ISite folder, which is
security proxied, the getMultiAdapter method returns a security
proxied ErrorViewSnippet object.

3. Access to ErrorViewSnippet is defined in z3c.form/configure.zcml as:

  <adapter
      factory=".error.ErrorViewSnippet"
      trusted="True"
      permission="zope.Public"
      />

The IErrorViewSnippet interface contains only 3 attributes: error,
update, render. Those are accessible to everyone. But there is no
security declaration for the 'widget' attribute, so access to it is
denied:

(Pdb) snippet
<ErrorViewSnippet for RequiredMissing>
(Pdb) type(snippet)
<type 'zope.security._proxy._Proxy'>
(Pdb) from zope.security.proxy import getChecker
(Pdb) getChecker(snippet).get_permissions
{'update': Global(CheckerPublic,zope.security.checker), 'render':
Global(CheckerPublic,zope.security.checker), 'error':
Global(CheckerPublic,zope.security.checker)}
(Pdb) from zope.security import canAccess
(Pdb) canAccess(snippet, 'widget')
*** ForbiddenAttribute: ('widget', <ErrorViewSnippet for RequiredMissing>)

So it seems the default z3c.form security declaration only allows
access to 'update', 'error' and 'render' attributes of an
ErrorViewSnippet object. I tried to work this around the by adding the
'widget' attribute to the IErrorViewSnippet interface and the system
error is no longer raised. However, this time, another exception is
raised saying the 'label' property of the widget is not accessible.

How can I setup my security properly to use z3c.form smoothly?
Shouldn't 'widget'  not be in IErrorViewSnippet since it is evidently
externally used in the rendering template?

Thanks for suggestions.

-- 
Hong Yuan

大管家网上建材超市
装修装潢建材一站式购物
http://www.homemaster.cn
_______________________________________________
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users

Reply via email to