For a while now, people have had to contend with two ways of doing
certain things, depending on whether the code they are working with is
in "Zope 2 land" or "Zope 3 land". We're getting closer to a world where
people don't need to be so intimately aware of the differences,
especially since the __parent__ pointer work was merged, and some of the
unification of page templates. However, we still have to do a lot of
explaining in the realm of permissions.
Five installs a Zope 3 security checker that checks against Zope 2
security. It does so by treating the title of a Zope 3 style IPermission
utility as a Zope 2 permission string. This works well, and has allowed
us to create valid Zope 3 permissions for the core Zope 2 and CMF
permissions (e.g. zope2.View, cmf.ModifyPortalContent) for use in views
and the like. However, it's not clear to new users where to use the Zope
3 style dotted name and where to use the Zope 2 permission string. As a
rule of thumb, the rules are something like:
- In ZCML (or a grok.require() directive) use the Zope 3 name
- In code, e.g. when doing a checkPermission() call, use the Zope 2 name
- With GenericSetup's rolemap.xml, use the Zope 2 name
The waters are muddied further by components that require a permission
to be listed or provided explicitly. Some use the Zope 2 name, some use
the Zope 3 name.
The other problem is that a <permission /> ZCML directive does not
actually register a Zope 2 style permission, it merely maps an existing
permission to a new name. Since Zope 2 permissions spring into existence
in difficult-to-explain ways, that causes a lot of confusion.
Finally, there is not total parity between Zope 2 security and Zope 3
security. Zope 2 cannot protect 'property set', for example. To this
end, Five throws exceptions if you use a ZCML <class /> directive with
set_attributes or or set_schema. Whilst this makes sense, it makes it
harder to re-use existing packages that do have that kind of protection
in place. Since the concept does not exist in Zope 2, I think it makes
sense to ignore this with a warning, rather than error.
So, here is what I'd like to propose, ideally for Zope 2.12:
1) Use an event handler to ensure that any <permission /> declared in
ZCML actually creates a valid, Zope 2 permission. I have working code
for this here which we could put in Products.Five with ease.
Benefits: Creating new permissions becomes more predictable.
Risks: None obvious. The event handler will not override permissions
that already exist.
2) Emit a warning instead of an error in Five's handler for the <class
/> directive when set_attributes or set_schema are used.
Benefits: Easier to re-use existing packages
Risks: The attributes won't actually be protected. However, since Zope 2
doesn't have the concept of protecting 'set' (or security proxies) then
I'm not sure there's a problem of expectation.
3) Change the Permission class in AccessControl so that it tries to
look up an IPermission utility and use the title of that utility as the
permission name, falling back on the current behaviour of using the
passed permission name directly.
Benefits: Should transparently allow any invocation of the Zope 2 API to
use Zope 3 permission names, allowing us to document that the dotted
permission name is the canonical name everywhere.
Risks: Performance overhead of doing utility lookups. May result in name
clashes, but since the permission name is a dotted name and the Zope 2
permission name isn't, I think it's extremely unlikely that this would
actually happen in practice.
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book
Zope-Dev maillist - Zope-Dev@zope.org
** No cross posts or HTML encoding! **
(Related lists -