Jim Fulton wrote:

It is not generally the case that you need to use separate security
declarations with trusted adapters.

I declare those additional class directive all the time if I'm using trusted adapters.
IMO this kind of registration is the common pattern


For example stephan richter uses this pattern within the wiki:

 <adapter
     factory=".wikipage.WikiPageHierarchyAdapter"
     provides=".interfaces.IWikiPageHierarchy"
     for=".interfaces.IWikiPage"
     trusted="true" />

 <class class=".wikipage.WikiPageHierarchyAdapter">
   <require
       permission="zwiki.ViewWikiPage"
       attributes="parents path findChildren"
       />
   <require
       permission="zwiki.ReparentWikiPage"
       attributes="reparent"
       set_attributes="parents"
       />
 </class>


This isn't a pattern I've used.  I think that there are
lots of other, and perhaps better ways to do things.

We have the use case that we adapt a lot of additional functionalities to a pretty stupid content.
Each additional functionality has differentiated permission-sets comparable to regular content objects. For example different permissions for reading and setting attributes of the provided interface.

Sure, but I would use different adapters to different functions.

How can you handle the set and read aspects of a schema-based interface in two different adapters? The permission is not a discriminator within the adapter directive.
That's a bureaucratic solution ;)


So at the moment I do not see any another possibility to set those permissions than using an additional <class.. directive.

All 'bugs' related to this issue (that I'm aware of) including the zwiki-bug that was reported uses the above pattern and breaks.
The reason for my branch was to solve this kind problem :)

But your original fix caused other problems.

Only if somebody is memorizing (and pickle) adapters. Please be honest, that's not the most ordinary application.
(at least there were definitely more application using the above pattern. ;)


But the permission declaration within the adapter directive defines the permission that is nessecary to invoke the adapter factory.

> > It's implict to asume that the instance by a certain factory desires > the same permissions like the invocationg of the factory. > > It's implict to asume that the instance by a certain factory desires > the same permissions like the invocationg of the factory.

Aaaaah.

You missunderstand.  The permission is not the permission to
to create the adapter. It's the permission necessary to use
the provided interface on the adapter.

Ok, missleading naming _protectedFactory within the adapter handler ;) But what happens in the following case? 1. the resulting adapter requires any.Permission

If the permission is other than zope.Public, it gets a location. This can be a documented feature of the directive.

2. the resulting adapter requires the permission defined by <class..

 <adapter
     factory=".wikipage.MailSubscriptions"
     provides=".interfaces.IMailSubscriptions"
     for=".interfaces.IWiki"
     *permission="any.Permission"*
     trusted="true"
     />

 <class class=".wikipage.MailSubscriptions">
   <require
       permission="zwiki.EditWikiPage"
       attributes="getSubscriptions"
       />
   <require
       permission="zwiki.EditWikiPage"
       attributes="addSubscriptions removeSubscriptions"
       />
 </class>

IMO case 2. happens (experimental verification only, I do not understand all magics within _protectedFactory).
The status-quo is pretty implicit too. I looking forward to explain such stuff to newbies ;)

In this case, the designer needs to do one of:

- Make their adapter class a location

- Factor their adapter into separate adapters that each
  do one thing and need a single permission.

We missed us.

Question: What should the precedence be if I use the sample zwiki registration (modified example above)?

At the moment (trunk) the permission attribute of the <adapter... is ignored and the permission-set of the <class... is invoked
(experimental verification only).


Here's what I want:

The adapter directive grows a new feature. If the adapter directive has
a permission directive with a permission other than zope.Public and the
adapter adapts one or more objects, then we provide a factory that:


  - Adds a location proxy if it doesn't provide ILocation, and

  - Sets the __parent__ if the existing value is not None

Dis you implement this?

I tried to implement your solution [Revision 30053], but then I noticed the following problems:


1. no permission (None) and zope.Public within a trusted adapter registration provokes different behavior (example below KeyReferenceToPersistent)

2. the zwiki bug and my related implementations bugs still exists, because regularly folks that registering trusted adapters using <adapter... and <class...do not set
any permission within <adapter.., but only within <class.... (That kind of permission declaration causes the invocation of the regular-trusted-adapter-factory.)


Therefore I reverted 'your' solution back to the first implementation [Revision 30059, 30060]. I assumed that it will be less evil
to do without two different trusted adapters factories (regular (zope.Public and None) and the locating one (other permission)).
+ we can fix the zwiki bug and related implementations bugs easily
+ we can omit the unclear permission-precedence if the <adapter... <class... pattern is used for trusted adapters
o the untrusted adapters with no location get only location-proxied if permission is not None or zope.Public
- we have to derive the KeyReferenceToPersistent adapter from Location to omit the pickle error


Just now I added some optimization [30067]:
Trusted adapters get regularly only protected if the adapted object is protected. Therefore we can omit the location proxy in cases where the trusted adapters get not protected.
I wrote an other adapter factory (PartiallyLocatingTrustedAdapterFactory) which is only using location proxies if the adapter is protected and does not provide ILocation.
If ILocation is provided the parent is still set if None.


Within the current branch there are the three adapter factories:
- PartiallyLocatingTrustedAdapterFactory
- LocatingTrustedAdapterFactory
- TrustedAdapterFactory
You can easily switch them within adapter() directive handler and look for the optimum.


After all I would prefer the current solution. But I know the decision is up to you.

P.S. Also the key reference uses the common-trusted-adapter-registration-pattern :)

 <adapter
     for="persistent.interfaces.IPersistent"
     provides=".interfaces.IKeyReference"
     factory=".persistent.KeyReferenceToPersistent"
     trusted="y"
     />

<class class=".persistent.KeyReferenceToPersistent">
<require permission="zope.Public" interface=".interfaces.IKeyReference" />
</class>


Except that the key-reference adapter is public.

If we would set zope.Public explicitly within the adapter directive an exception is raised:

 <adapter
     for="persistent.interfaces.IPersistent"
     provides=".interfaces.IKeyReference"
     factory=".persistent.KeyReferenceToPersistent"
     permission="zope.Public"
     trusted="y"
     />

<class class=".persistent.KeyReferenceToPersistent">
<require permission="zope.Public" interface=".interfaces.IKeyReference" />
</class>


File "E:\dev\amadeus_trunk\src\ZODB\serialize.py", line 330, in serialize
return self._dump(meta, obj.__getstate__())
File "E:\dev\amadeus_trunk\src\ZODB\serialize.py", line 339, in _dump
self._p.dump(state)
File "D:\Python23\lib\copy_reg.py", line 69, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle Checker objects


Yup, I'm aware of that.

Regards, Dominik

_______________________________________________
Zope3-dev mailing list
Zope3-dev@zope.org
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com



Reply via email to