Permission problems with adapters

Recently I encountered a permission problem that I guess can be tipical when working with adapters based on marker interfaces (such as implementing IRatableItem with a class and adapting it to IRating).

The code is classic simplistic example of adaptation, using the IAnnotation to store a rating, with the adapter being something along these lines:

from interfaces import IRating
from zope.annotation.interfaces import IAnnotations
from zope.interface import implements

class RatingAdapter(object):
    implements(IRating)

    def __init__(self, context):
        self.context=context
        self.KEY="ratingAdapter.stage.12_0"
        try:
            rating=IAnnotations(self.context)[self.KEY]
        except KeyError:
            IAnnotations(self.context)[self.KEY]=0

    def getRating(self):
        return IAnnotations(self.context)[self.KEY]

    def setRating(self, ratingValue):
        IAnnotations(self.context)[self.KEY]=ratingValue

    rating = property(getRating, setRating)

This class sits in a separate package called "rating". The interfaces for this package:

from zope.interface import Interface
from zope.schema import Int

class IRating(Interface):
    """Rating for an item"""
    rating = Int(title=u"Rating")

    def getRating():
        "Returns a rating"

    def setRating(value):
        "Sets a rating"

class IRatable(Interface):
    """Marker interface for rating"""
    pass

The adapter that does the adaption from IRatable to IRating is registered with

<adapter
        for=".interfaces.IRatable"
        provides=".interfaces.IRating"
        factory=".ratingadapter.RatingAdapter"
        trusted="True"
        />

The adapter is set to trusted because it needs access to __annotations__, to be able to store the rating in the annotation. Now all it should needed to do to have ratings on objects is to declare it to implement IRatable and integrate its views with the rating setting methods.

Here comes the problem

I have a content item, let's say IBottle, with an edit form declared like this:

class BottleEditForm (EditForm):
    form_fields = Fields (IBottle, IRating)

The form generation will fail complaining about a forbidden attribute, "rating". Apparently, the adapter class needs to have security declarations as well, with something like this (declared in the rating package):

<class class=".ratingadapter.RatingAdapter">
        <require
            permission="zope.ManageContent"
            set_schema=".interfaces.IRating"
            interface=".interfaces.IRating"
            />
    </class>

I found traces of this problem mentioned around the web, in these two locations:


Comments