Reputation: 1022
I am getting an error when I try to set the attribute for authenticated_userid as a request parameter. Its actually a nosetest I am using to mock up the request and see the response.
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
Code is as below
@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)
I am creating a dummy request and I am adding attributes to request.
When this method logSuspiciousRequestAndRaiseHTTPError()
is called the request is parsed by the method to get user account.
userAccountID=authenticated_userid(self.request)
This returns None
since the request doesn't have an attribute self.request.authenticated_userid
Please let me know if you need any additional information.
Upvotes: 4
Views: 1547
Reputation: 908
Because authenticated_userid
is a reified attribute coming from the underlying authentication policy, it can not be directly set in the DummyRequest
when doing a test. This means both of the below will not work:
# Will NOT work
dummy_request = DummyRequest(authenticated_userid='mock_user')
# Also will NOT work
dummy_request = DummyRequest()
dummy_request.authenticated_userid = 'mock_user'
Instead, if we want to be able to control the authenticated_userid
for a test (or other aspects of the auth policies as well), we need to change the underlying Pyramid config for the test we're running. For this, you'll want to take a look at pyramid.testing.setUp
(docs here). This returns a config object that can do a whole bunch of things, but the important one for our interests is the testing_securitypolicy
method (docs here).
testing_securitypolicy
allows us to have pretty granular control over how requests will be seen from an auth point of view. Look at its docs for specifics, but with it we can set what the authenticated_userid
will be for a request, make it so that permission requirements are ignored, and more.
Here's an example of usage in a test:
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()
Upvotes: 1
Reputation: 1022
Finally I got the solution.
I added self.config = testing.setUp()
self.config.testing_securitypolicy(
userid=self.data['user'].userAccount.id, permissive=True
)
Added the userAccountId as mock up value for testing security policy.
@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)
Upvotes: 3
Reputation: 83368
authenticated_userid
is reified attribute set by authentication framework.
See Logins with authentication for basic information.
Please include more code how you set up your request, as in its current form the question does not have details to give accurate answer.
Upvotes: 1