2

我在 Plone 4.2.4 中有一个灵巧的内容类型,它使用 contenttree 小部件来管理引用的对象,但仅在 editForm 中。

我意识到,引用的项目必须external_visible由小部件显示,这意味着匿名用户可以ViewAccessContentsInformation. 那不是我想要的。所以我挖掘了 contenttree 小部件源并将以下内容添加到我的产品中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" />

和一个适配器

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)    

[...]

但这似乎还不够。如果权限设置为拒绝ViewAccessContentsInformation匿名用户,则基础目录搜索不返回任何结果。所以我想,我必须使用查看权限来构造某种代理用户。

可以在新创建的视图中使用 aSecurityManager以其他用户的身份获取结果吗?还是我只是错过了什么?

4

1 回答 1

1

好的,这就是我解开谜团的方法。

经过一段时间的挖掘,我意识到,我之前的想法忽略了这一点,即覆盖@@contenttree-fetch视图。我想出的解决方案非常简单,对我来说似乎很优雅(足够)。我现在做一个 sudo 风格的回避,以收集所需的项目。

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)
于 2013-05-07T16:02:53.493 回答