[Zope3-dev] Form framework, adapters and pau

Dominik Huber dominik.huber at projekt01.ch
Wed Apr 20 18:02:40 EDT 2005


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



More information about the Zope3-dev mailing list