user657127
user657127

Reputation:

Plone 4.2 formwidget contenttree permissions

I have a dexterity content type in Plone 4.2.4, that uses the contenttree widget to manage referenced objects, but only in the editForm.

I realized, that the referenced items had to be external_visible to get displayed by the widget, which means that anonymous users could View and AccessContentsInformation. Thats not what I wanted. So I dug in the contenttree widget source and added the following to my products browser/configure.zcml

<include package="Products.CMFCore" file="permissions.zcml"
         zcml:condition="installed plone.app.upgrade" />

<browser:page
    for="*"
    name="contenttree-fetch"
    class="my.product.content.bikemetamodel.EditForm"
    permission="cmf.ModifyPortalContent"
    />
<adapter factory="my.product.browser.widgets.MetamodellContenttreeAdapter" />

and an adapter

class MetamodellContenttreeAdapter(object):
    implements(IBikeMetaModel)
    adapts(Interface)

def __init__(self, context):
    self.context = context

def _get_allowed_modeltypes(self):
    return None

def _set_allowed_modeltypes(self, value):
    print "setting", value

allowed_modeltypes = property(_get_allowed_modeltypes, _set_allowed_modeltypes)    

[...]

But this seems to be not enough. The underlying catalog search returns no result, If the permissions are set to deny View and AccessContentsInformation to anonymous users. So I guess, I must use the view permission to construct some kind of proxy user.

Would it be ok, to use a SecurityManager in the newly created view to fetch the results as a different user? Or am I just missing something?

Upvotes: 2

Views: 59

Answers (1)

user657127
user657127

Reputation:

Ok, here is how I solved the mystery.

After digging around a while, I realized, that I missed the point with my previous idea to override the @@contenttree-fetch view. The solution I came up with is quite simple and seems elegant (enough) for me. I do a sudo style sidestep now, to gather the required items.

Class EditForm(dexterity.EditForm):
    grok.context(IBikeMetaModel)
    # If it would be another than the edit view, we could manage
    # permisssions here. Not neccessary in edit view, because the 
    # edit permission defined in this content types *.xml counts
    # grok.require("cmf.ModifyPortalContent")


    @property
    def acl_users(self):
        return getToolByName(getSite(), 'acl_users')

    def updateWidgets(self):
        # This is the magic. A sudo style sidestep to a user
        # with the id "system" that has permission to gather 
        # the required lists in the updateWidgets function of 
        # the base class
        proxy_user = self.acl_users.getUserById("system")
        oUser = getSecurityManager()
        newSecurityManager(self.request, proxy_user)
        super(EditForm, self).updateWidgets()

        # custom widget updates
        self.widgets['title'].mode = DISPLAY_MODE
        self.widgets['year'].mode = HIDDEN_MODE
        self.widgets['brand'].mode = HIDDEN_MODE
        self.widgets['model'].mode = HIDDEN_MODE

        # Very Important! Switch back to the original user.
        setSecurityManager(oUser)

Upvotes: 1

Related Questions