如何在python的金字塔框架中设置request.authenticated_userid的值

如何在python的金字塔框架中设置request.authenticated_userid的值,python,pyramid,Python,Pyramid,当我试图将authenticated_userid的属性设置为请求参数时,出现了一个错误。这实际上是我用来模拟请求并查看响应的鼻子测试 Traceback (most recent call last): File "/web/core/pulse/wapi/tests/testWapiUtilities_integration.py", line 652, in setUp setattr(self.request, 'authenticated_userid', self.dat

当我试图将authenticated_userid的属性设置为请求参数时,出现了一个错误。这实际上是我用来模拟请求并查看响应的鼻子测试

Traceback (most recent call last):
  File "/web/core/pulse/wapi/tests/testWapiUtilities_integration.py", line 652, in setUp
    setattr(self.request, 'authenticated_userid', self.data['user'].id)
AttributeError: can't set attribute
代码如下

@attr(can_split=False)
class logSuspiciousRequestAndRaiseHTTPError(IntegrationTestCase):
    def setUp(self):
        super(logSuspiciousRequestAndRaiseHTTPError, self).setUp()
        from pyramid.request import Request
        from pyramid.threadlocal import get_current_registry
        request = Request({
            'SERVER_PROTOCOL': 'testprotocol',
            'SERVER_NAME': 'test server name',
            'SERVER_PORT': '80',
        })
        request.context = TestContext()
        request.root = request.context
        request.subpath = ['path']
        request.traversed = ['traversed']
        request.view_name = 'test view name'
        request.path_info = 'test info'
        request.scheme = 'https'
        request.host = 'test.com'
        request.registry = get_current_registry()
        self.request = request
        self.data = {}
        self.createDefaultData()
        self.request.userAccount = self.data['user'].userAccount

    # @unittest.skip('Pre-Demo skip. Need to mock userAccountModel')
    @mock.patch('pulse.wapi.wapiUtilities.pyramid.threadlocal.get_current_request')
    @mock.patch('pulse.wapi.wapiUtilities.securityLog')
    def testHasRequest_raises400AndLogsError(
            self, securityLog, get_current_request):
        # Arrange
        get_current_request.return_value = self.request

        with self.assertRaises(exception.HTTPBadRequest):
            from pulse.wapi.wapiUtilities import logSuspiciousRequestAndRaiseHTTPError
            logSuspiciousRequestAndRaiseHTTPError()
            self.assertTrue(securityLog.called)
            self.assertTrue(securityLog.return_value.info.called)
我正在创建一个虚拟请求,并向请求添加属性

当调用此方法
log猜疑请求和RaiseHttPeror()
时,该方法将解析请求以获取用户帐户

userAccountID=authenticated_userid(self.request)
这将返回
None
,因为请求没有属性
self.request.authenticated\u userid


如果您需要任何其他信息,请告诉我。

authenticated\u userid
是身份验证框架设置的具体化属性


请提供更多代码,说明您是如何设置请求的,因为在当前形式下,问题没有给出准确答案的详细信息。

最终我得到了解决方案

我添加了
self.config=testing.setUp()

添加userAccountId作为测试安全策略的模拟值

@attr(can_split=False)
class logSuspiciousRequestAndRaiseHTTPError(IntegrationTestCase):
    def setUp(self):
        super(logSuspiciousRequestAndRaiseHTTPError, self).setUp()
        from pyramid.request import Request
        from pyramid.threadlocal import get_current_registry
        self.config = testing.setUp()
        request = Request({
            'SERVER_PROTOCOL': 'testprotocol',
            'SERVER_NAME': 'test server name',
            'SERVER_PORT': '80',
        })
        request.context = TestContext()
        request.root = request.context
        request.subpath = ['path']
        request.traversed = ['traversed']
        request.view_name = 'test view name'
        request.path_info = 'test info'
        request.scheme = 'https'
        request.host = 'test.com'
        request.registry = get_current_registry()
        self.request = request
        self.data = {}
        self.createDefaultData()
        self.request.userAccount = self.data['user'].userAccount

    @mock.patch('pulse.wapi.wapiUtilities.pyramid.threadlocal.get_current_request')
    @mock.patch('pulse.wapi.wapiUtilities.securityLog')
    def testHasRequest_raises400AndLogsError(
            self, securityLog, get_current_request):
        # Arrange
        get_current_request.return_value = self.request
        self.loggedInUser = self.data['user']
        self.config.testing_securitypolicy(
            userid=self.data['user'].userAccount.id, permissive=True
        )

        with self.assertRaises(exception.HTTPBadRequest):
            from pulse.wapi.wapiUtilities import logSuspiciousRequestAndRaiseHTTPError
            logSuspiciousRequestAndRaiseHTTPError()
            self.assertTrue(securityLog.called)
            self.assertTrue(securityLog.return_value.info.called)

由于
authenticated\u userid
是来自底层身份验证策略的具体化属性,因此在执行测试时不能在
DummyRequest
中直接设置它。这意味着以下两个都不起作用

# Will NOT work
dummy_request = DummyRequest(authenticated_userid='mock_user')
# Also will NOT work
dummy_request = DummyRequest()
dummy_request.authenticated_userid = 'mock_user'
相反,如果我们希望能够控制测试的
authenticated\u userid
(或者验证策略的其他方面),我们需要更改正在运行的测试的底层金字塔配置。为此,您需要了解一下
pyramid.testing.setUp
()。这将返回一个config对象,它可以做很多事情,但对我们来说重要的是
testing\u securitypolicy
方法()

testing\u securitypolicy
允许我们从auth的角度对请求进行精确的控制。查看其文档了解详细信息,但通过它,我们可以为请求设置
已验证的\u userid
,使其忽略权限要求,等等

下面是一个在测试中使用的示例:

from pyramid.testing import (setUp, tearDown, DummyRequest)

def test_some_view():
    config = setUp()
    config.testing_securitypolicy(userid='mock_user')  # Sets authenticated_userid

    dummy_request = DummyRequest()
    print(dummy_request.authenticated_userid)  # Prints 'mock_user'

    # Now ready to test something that uses request.authenticated_userid
    from mypyramidapp.views.secure import some_auth_view
    result = some_auth_view(dummy_request)
    expected = 'Hello mock_user!'
    assert result == expected

    # Finally, to avoid security changes leaking to other tests, use tearDown
    tearDown()  # Undo the effects of pyramid.testing.setUp()

from pyramid.testing import (setUp, tearDown, DummyRequest)

def test_some_view():
    config = setUp()
    config.testing_securitypolicy(userid='mock_user')  # Sets authenticated_userid

    dummy_request = DummyRequest()
    print(dummy_request.authenticated_userid)  # Prints 'mock_user'

    # Now ready to test something that uses request.authenticated_userid
    from mypyramidapp.views.secure import some_auth_view
    result = some_auth_view(dummy_request)
    expected = 'Hello mock_user!'
    assert result == expected

    # Finally, to avoid security changes leaking to other tests, use tearDown
    tearDown()  # Undo the effects of pyramid.testing.setUp()