我在Plone 4.2.4中有一个dexterity内容类型,它使用contenttree小部件来管理引用的对象,但仅限于editForm。
我意识到,小部件必须显示引用的项目external_visible
,这意味着匿名用户可以View
和AccessContentsInformation
。那不是我想要的。因此,我在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)
[...]
但这似乎还不够。基础目录搜索不返回任何结果,如果权限设置为拒绝View
和AccessContentsInformation
匿名用户。所以我想,我必须使用视图权限来构建某种代理用户。
是否可以在新创建的视图中使用SecurityManager
以不同的用户身份获取结果?或者我错过了什么?
答案 0 :(得分: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)