1

我有一个问题,我需要能够让匿名用户通过 portal_catalog 搜索和检索自定义内容,但他们无法查看。

我使用了自定义内容类型和自定义工作流程,我得到的很可能是权限问题。我通过 ZMI -> portal_workflow 定义了一个自定义工作流,然后将其作为 XML 定义导出到源代码中。我将匿名用户的权限设置为“访问内容信息”而不是“查看”。请注意,代码片段中的“活动”是启用了该权限的工作流状态——sales_workflow

大脑查找适用于“经理”角色,但当角色切换为“匿名”时,目录返回一个空列表。

import unittest2 as unittest


from . import INTEGRATION_TESTING
from AccessControl import getSecurityManager

from plone.app.testing import setRoles, logout
from plone.app.testing import TEST_USER_ID

from Products.CMFCore.utils import getToolByName

def drop_to_anonymous(self):
    """
    Drop site roles to anonymous user only.
    Note this is a class method and not a function
    assign this method as a class member and then call it
    """
    logout()
    setRoles(self.portal, TEST_USER_ID, ['Anonymous'])
    user = getSecurityManager().getUser()
    roles =  user.getRolesInContext(self.portal)
    self.assertListEqual(['Anonymous'], roles)

class TestSalesRepWorkflow(unittest.TestCase):
    layer = INTEGRATION_TESTING
    drop_to_anonymous = drop_to_anonymous
    def setUp(self):
        self.portal = self.layer['portal']
        self.wftool = getToolByName(self.portal, 'portal_workflow')
        self.catalog = getToolByName(self.portal, 'portal_catalog')
    def test_workflow_lookup_anon(self):
        setRoles(self.portal, TEST_USER_ID, ['Manager'])
        self.portal.invokeFactory(
                                'CustomProduct',
                                'prod1',
                                title="Product 1"
                                )
        prod1 = self.portal['prod1']
        self.wftool.doActionFor(prod1, action='activate')
        review_state = self.wftool.getInfoFor(prod1, 'review_state')
        prod1.reindexObject()
        self.assertEqual('active', review_state)
        lookup = self.catalog(portal_type='CustomProduct', Title='Product 1',
                            review_state='active')
        #This test passes with managerial permissions
        self.assertEqual(len(lookup), 1)
        #Repeat the same test in 'Anonymous' role
        self.drop_to_anonymous()
        lookup1 = self.catalog(portal_type='CustomProduct', Title='Product 1',
                            review_state='active')
        #When dropped to anonymous role, the test fails, 
        #lookup returns an empty list
        self.assertEqual(len(lookup1), 1)

有没有办法在不彻底修改权限的情况下解决这个问题?

使用 unrestrictedSearchResults 似乎可以修复搜索,但是每当我尝试在大脑上运行“getObject”时,都会引发以下错误:

Unauthorized: You are not allowed to access 'XXX' in this context
4

1 回答 1

1

您的active州需要将查看权限授予匿名。目前它仅限于以下角色:

<state state_id="active" title="">
 <!-- other information elided here --> 
 <permission-map name="View" acquired="False">
   <permission-role>Manager</permission-role>
   <permission-role>Owner</permission-role>
   <permission-role>Reviewer</permission-role>
   <permission-role>SalesRep</permission-role>
   <permission-role>Site Administrator</permission-role>
  </permission-map>

如果没有查看权限,即使指定active状态,匿名也无法查看您的对象,该用户也无法在目录中找到它们。

您可以使用目录的方法覆盖目录的这种行为.unrestrictedSearchResults()

lookup1 = self.catalog.unrestrictedSearchResults(
    portal_type='SalesProduct', Title='Product 1', review_state='active')

此方法不能从受限代码中使用。

返回的大脑对象完全可以被匿名用户访问,但你不能getObject()在它们上使用该方法,因为这将使用当前用户的权限来遍历它。如果您需要从大脑中获取实际对象,还有一种特殊的私有方法可以不受这些限制地获取实际对象,称为._unrestrictedGetObject()

obj = brain._unrestrictedGetObject()

再一次,此方法仅适用于不受限制的代码。

于 2013-01-22T22:27:07.717 回答