| | |
| | | |
| | | from pyramid import testing |
| | | from pyramid.exceptions import ConfigurationError |
| | | from pyramid.interfaces import ( |
| | | IResponse, |
| | | IRequest, |
| | | ) |
| | | from pyramid.interfaces import IResponse, IRequest |
| | | |
| | | |
| | | class TestDeriveView(unittest.TestCase): |
| | | |
| | | def setUp(self): |
| | | self.config = testing.setUp() |
| | | self.config.set_default_csrf_options(require_csrf=False) |
| | |
| | | |
| | | def _registerLogger(self): |
| | | from pyramid.interfaces import IDebugLogger |
| | | |
| | | logger = DummyLogger() |
| | | self.config.registry.registerUtility(logger, IDebugLogger) |
| | | return logger |
| | |
| | | def _registerSecurityPolicy(self, permissive): |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | |
| | | policy = DummySecurityPolicy(permissive) |
| | | self.config.registry.registerUtility(policy, IAuthenticationPolicy) |
| | | self.config.registry.registerUtility(policy, IAuthorizationPolicy) |
| | |
| | | def test_function_returns_non_adaptable(self): |
| | | def view(request): |
| | | return None |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | try: |
| | |
| | | 'Could not convert return value of the view callable function ' |
| | | 'tests.test_viewderivers.view into a response ' |
| | | 'object. The value returned was None. You may have forgotten ' |
| | | 'to return a value from the view callable.' |
| | | ) |
| | | else: # pragma: no cover |
| | | 'to return a value from the view callable.', |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_function_returns_non_adaptable_dict(self): |
| | | def view(request): |
| | | return {'a':1} |
| | | return {'a': 1} |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | try: |
| | |
| | | "Could not convert return value of the view callable function " |
| | | "tests.test_viewderivers.view into a response " |
| | | "object. The value returned was {'a': 1}. You may have " |
| | | "forgotten to define a renderer in the view configuration." |
| | | ) |
| | | else: # pragma: no cover |
| | | "forgotten to define a renderer in the view configuration.", |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_instance_returns_non_adaptable(self): |
| | | class AView(object): |
| | | def __call__(self, request): |
| | | return None |
| | | |
| | | view = AView() |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | |
| | | result(None, None) |
| | | except ValueError as e: |
| | | msg = e.args[0] |
| | | self.assertTrue(msg.startswith( |
| | | 'Could not convert return value of the view callable object ' |
| | | '<tests.test_viewderivers.')) |
| | | self.assertTrue(msg.endswith( |
| | | '> into a response object. The value returned was None. You ' |
| | | 'may have forgotten to return a value from the view callable.')) |
| | | else: # pragma: no cover |
| | | self.assertTrue( |
| | | msg.startswith( |
| | | 'Could not convert return value of the view callable ' |
| | | 'object <tests.test_viewderivers.' |
| | | ) |
| | | ) |
| | | self.assertTrue( |
| | | msg.endswith( |
| | | '> into a response object. The value returned was None. ' |
| | | 'You may have forgotten to return a value from the view ' |
| | | 'callable.' |
| | | ) |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_function_returns_true_Response_no_renderer(self): |
| | | from pyramid.response import Response |
| | | |
| | | r = Response('Hello') |
| | | |
| | | def view(request): |
| | | return r |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | response = result(None, None) |
| | |
| | | |
| | | def test_function_returns_true_Response_with_renderer(self): |
| | | from pyramid.response import Response |
| | | |
| | | r = Response('Hello') |
| | | |
| | | def view(request): |
| | | return r |
| | | renderer = object() |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | response = result(None, None) |
| | |
| | | |
| | | def test_requestonly_default_method_returns_non_adaptable(self): |
| | | request = DummyRequest() |
| | | |
| | | class AView(object): |
| | | def __init__(self, request): |
| | | pass |
| | | |
| | | def __call__(self): |
| | | return None |
| | | |
| | | result = self.config.derive_view(AView) |
| | | self.assertFalse(result is AView) |
| | | try: |
| | |
| | | 'method __call__ of ' |
| | | 'class tests.test_viewderivers.AView into a ' |
| | | 'response object. The value returned was None. You may have ' |
| | | 'forgotten to return a value from the view callable.' |
| | | ) |
| | | else: # pragma: no cover |
| | | 'forgotten to return a value from the view callable.', |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_requestonly_nondefault_method_returns_non_adaptable(self): |
| | | request = DummyRequest() |
| | | |
| | | class AView(object): |
| | | def __init__(self, request): |
| | | pass |
| | | |
| | | def theviewmethod(self): |
| | | return None |
| | | |
| | | result = self.config.derive_view(AView, attr='theviewmethod') |
| | | self.assertFalse(result is AView) |
| | | try: |
| | |
| | | 'method theviewmethod of ' |
| | | 'class tests.test_viewderivers.AView into a ' |
| | | 'response object. The value returned was None. You may have ' |
| | | 'forgotten to return a value from the view callable.' |
| | | ) |
| | | else: # pragma: no cover |
| | | 'forgotten to return a value from the view callable.', |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_requestonly_function(self): |
| | | response = DummyResponse() |
| | | |
| | | def view(request): |
| | | return response |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | self.assertEqual(result(None, None), response) |
| | | |
| | | def test_requestonly_function_with_renderer(self): |
| | | response = DummyResponse() |
| | | |
| | | class moo(object): |
| | | def render_view(inself, req, resp, view_inst, ctx): |
| | | self.assertEqual(req, request) |
| | |
| | | self.assertEqual(view_inst, view) |
| | | self.assertEqual(ctx, context) |
| | | return response |
| | | |
| | | def clone(self): |
| | | return self |
| | | |
| | | def view(request): |
| | | return 'OK' |
| | | |
| | | result = self.config.derive_view(view, renderer=moo()) |
| | | self.assertFalse(result.__wraps__ is view) |
| | | request = self._makeRequest() |
| | |
| | | self.assertEqual(system['request'], request) |
| | | self.assertEqual(system['context'], context) |
| | | return b'moo' |
| | | |
| | | return inner |
| | | |
| | | def view(request): |
| | | return 'OK' |
| | | |
| | | self.config.add_renderer('moo', moo) |
| | | result = self.config.derive_view(view, renderer='string') |
| | | self.assertFalse(result is view) |
| | |
| | | |
| | | def test_requestonly_function_with_renderer_request_has_view(self): |
| | | response = DummyResponse() |
| | | |
| | | class moo(object): |
| | | def render_view(inself, req, resp, view_inst, ctx): |
| | | self.assertEqual(req, request) |
| | |
| | | self.assertEqual(view_inst, 'view') |
| | | self.assertEqual(ctx, context) |
| | | return response |
| | | |
| | | def clone(self): |
| | | return self |
| | | |
| | | def view(request): |
| | | return 'OK' |
| | | |
| | | result = self.config.derive_view(view, renderer=moo()) |
| | | self.assertFalse(result.__wraps__ is view) |
| | | request = self._makeRequest() |
| | |
| | | |
| | | def test_class_without_attr(self): |
| | | response = DummyResponse() |
| | | |
| | | class View(object): |
| | | def __init__(self, request): |
| | | pass |
| | | |
| | | def __call__(self): |
| | | return response |
| | | |
| | | result = self.config.derive_view(View) |
| | | request = self._makeRequest() |
| | | self.assertEqual(result(None, request), response) |
| | |
| | | |
| | | def test_class_with_attr(self): |
| | | response = DummyResponse() |
| | | |
| | | class View(object): |
| | | def __init__(self, request): |
| | | pass |
| | | |
| | | def another(self): |
| | | return response |
| | | |
| | | result = self.config.derive_view(View, attr='another') |
| | | request = self._makeRequest() |
| | | self.assertEqual(result(None, request), response) |
| | |
| | | def test_as_function_context_and_request(self): |
| | | def view(context, request): |
| | | return 'OK' |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertTrue(result.__wraps__ is view) |
| | | self.assertFalse(hasattr(result, '__call_permissive__')) |
| | |
| | | |
| | | def test_as_function_requestonly(self): |
| | | response = DummyResponse() |
| | | |
| | | def view(request): |
| | | return response |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | self.assertEqual(view.__module__, result.__module__) |
| | |
| | | |
| | | def test_as_newstyle_class_context_and_request(self): |
| | | response = DummyResponse() |
| | | |
| | | class view(object): |
| | | def __init__(self, context, request): |
| | | pass |
| | | |
| | | def __call__(self): |
| | | return response |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | self.assertEqual(view.__module__, result.__module__) |
| | |
| | | |
| | | def test_as_newstyle_class_requestonly(self): |
| | | response = DummyResponse() |
| | | |
| | | class view(object): |
| | | def __init__(self, context, request): |
| | | pass |
| | | |
| | | def __call__(self): |
| | | return response |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | self.assertEqual(view.__module__, result.__module__) |
| | |
| | | |
| | | def test_as_oldstyle_class_context_and_request(self): |
| | | response = DummyResponse() |
| | | |
| | | class view: |
| | | def __init__(self, context, request): |
| | | pass |
| | | |
| | | def __call__(self): |
| | | return response |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | self.assertEqual(view.__module__, result.__module__) |
| | |
| | | |
| | | def test_as_oldstyle_class_requestonly(self): |
| | | response = DummyResponse() |
| | | |
| | | class view: |
| | | def __init__(self, context, request): |
| | | pass |
| | | |
| | | def __call__(self): |
| | | return response |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | | self.assertEqual(view.__module__, result.__module__) |
| | |
| | | |
| | | def test_as_instance_context_and_request(self): |
| | | response = DummyResponse() |
| | | |
| | | class View: |
| | | def __call__(self, context, request): |
| | | return response |
| | | |
| | | view = View() |
| | | result = self.config.derive_view(view) |
| | | self.assertTrue(result.__wraps__ is view) |
| | |
| | | |
| | | def test_as_instance_requestonly(self): |
| | | response = DummyResponse() |
| | | |
| | | class View: |
| | | def __call__(self, request): |
| | | return response |
| | | |
| | | view = View() |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result is view) |
| | |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = dict( |
| | | debug_authorization=True, reload_templates=True) |
| | | debug_authorization=True, reload_templates=True |
| | | ) |
| | | logger = self._registerLogger() |
| | | result = self.config._derive_view(view, permission='view') |
| | | self.assertEqual(view.__module__, result.__module__) |
| | |
| | | request.url = 'url' |
| | | self.assertEqual(result(None, request), response) |
| | | self.assertEqual(len(logger.messages), 1) |
| | | self.assertEqual(logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): Allowed " |
| | | "(no authorization policy in use)") |
| | | self.assertEqual( |
| | | logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): Allowed " |
| | | "(no authorization policy in use)", |
| | | ) |
| | | |
| | | def test_with_debug_authorization_authn_policy_no_authz_policy(self): |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = dict(debug_authorization=True) |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | |
| | | policy = DummySecurityPolicy(False) |
| | | self.config.registry.registerUtility(policy, IAuthenticationPolicy) |
| | | logger = self._registerLogger() |
| | |
| | | request.url = 'url' |
| | | self.assertEqual(result(None, request), response) |
| | | self.assertEqual(len(logger.messages), 1) |
| | | self.assertEqual(logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): Allowed " |
| | | "(no authorization policy in use)") |
| | | self.assertEqual( |
| | | logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): Allowed " |
| | | "(no authorization policy in use)", |
| | | ) |
| | | |
| | | def test_with_debug_authorization_authz_policy_no_authn_policy(self): |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = dict(debug_authorization=True) |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | |
| | | policy = DummySecurityPolicy(False) |
| | | self.config.registry.registerUtility(policy, IAuthorizationPolicy) |
| | | logger = self._registerLogger() |
| | |
| | | request.url = 'url' |
| | | self.assertEqual(result(None, request), response) |
| | | self.assertEqual(len(logger.messages), 1) |
| | | self.assertEqual(logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): Allowed " |
| | | "(no authorization policy in use)") |
| | | self.assertEqual( |
| | | logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): Allowed " |
| | | "(no authorization policy in use)", |
| | | ) |
| | | |
| | | def test_with_debug_authorization_no_permission(self): |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = dict( |
| | | debug_authorization=True, reload_templates=True) |
| | | debug_authorization=True, reload_templates=True |
| | | ) |
| | | self._registerSecurityPolicy(True) |
| | | logger = self._registerLogger() |
| | | result = self.config._derive_view(view) |
| | |
| | | request.url = 'url' |
| | | self.assertEqual(result(None, request), response) |
| | | self.assertEqual(len(logger.messages), 1) |
| | | self.assertEqual(logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): Allowed (" |
| | | "no permission registered)") |
| | | self.assertEqual( |
| | | logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): Allowed (" |
| | | "no permission registered)", |
| | | ) |
| | | |
| | | def test_debug_auth_permission_authpol_permitted(self): |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = dict( |
| | | debug_authorization=True, reload_templates=True) |
| | | debug_authorization=True, reload_templates=True |
| | | ) |
| | | logger = self._registerLogger() |
| | | self._registerSecurityPolicy(True) |
| | | result = self.config._derive_view(view, permission='view') |
| | |
| | | request.url = 'url' |
| | | self.assertEqual(result(None, request), response) |
| | | self.assertEqual(len(logger.messages), 1) |
| | | self.assertEqual(logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): True") |
| | | self.assertEqual( |
| | | logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): True", |
| | | ) |
| | | |
| | | def test_debug_auth_permission_authpol_permitted_no_request(self): |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = dict( |
| | | debug_authorization=True, reload_templates=True) |
| | | debug_authorization=True, reload_templates=True |
| | | ) |
| | | logger = self._registerLogger() |
| | | self._registerSecurityPolicy(True) |
| | | result = self.config._derive_view(view, permission='view') |
| | |
| | | self.assertEqual(result.__call_permissive__.__wraps__, view) |
| | | self.assertEqual(result(None, None), response) |
| | | self.assertEqual(len(logger.messages), 1) |
| | | self.assertEqual(logger.messages[0], |
| | | "debug_authorization of url None (view name " |
| | | "None against context None): True") |
| | | self.assertEqual( |
| | | logger.messages[0], |
| | | "debug_authorization of url None (view name " |
| | | "None against context None): True", |
| | | ) |
| | | |
| | | def test_debug_auth_permission_authpol_denied(self): |
| | | from pyramid.httpexceptions import HTTPForbidden |
| | | |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = dict( |
| | | debug_authorization=True, reload_templates=True) |
| | | debug_authorization=True, reload_templates=True |
| | | ) |
| | | logger = self._registerLogger() |
| | | self._registerSecurityPolicy(False) |
| | | result = self.config._derive_view(view, permission='view') |
| | |
| | | request.url = 'url' |
| | | self.assertRaises(HTTPForbidden, result, None, request) |
| | | self.assertEqual(len(logger.messages), 1) |
| | | self.assertEqual(logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): False") |
| | | self.assertEqual( |
| | | logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): False", |
| | | ) |
| | | |
| | | def test_debug_auth_permission_authpol_denied2(self): |
| | | view = lambda *arg: 'OK' |
| | | self.config.registry.settings = dict( |
| | | debug_authorization=True, reload_templates=True) |
| | | debug_authorization=True, reload_templates=True |
| | | ) |
| | | self._registerLogger() |
| | | self._registerSecurityPolicy(False) |
| | | result = self.config._derive_view(view, permission='view') |
| | |
| | | |
| | | def test_debug_auth_permission_authpol_overridden(self): |
| | | from pyramid.security import NO_PERMISSION_REQUIRED |
| | | |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = dict( |
| | | debug_authorization=True, reload_templates=True) |
| | | debug_authorization=True, reload_templates=True |
| | | ) |
| | | logger = self._registerLogger() |
| | | self._registerSecurityPolicy(False) |
| | | result = self.config._derive_view(view, permission=NO_PERMISSION_REQUIRED) |
| | | result = self.config._derive_view( |
| | | view, permission=NO_PERMISSION_REQUIRED |
| | | ) |
| | | self.assertEqual(view.__module__, result.__module__) |
| | | self.assertEqual(view.__doc__, result.__doc__) |
| | | self.assertEqual(view.__name__, result.__name__) |
| | |
| | | request.url = 'url' |
| | | self.assertEqual(result(None, request), response) |
| | | self.assertEqual(len(logger.messages), 1) |
| | | self.assertEqual(logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): " |
| | | "Allowed (NO_PERMISSION_REQUIRED)") |
| | | self.assertEqual( |
| | | logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context None): " |
| | | "Allowed (NO_PERMISSION_REQUIRED)", |
| | | ) |
| | | |
| | | def test_debug_auth_permission_authpol_permitted_excview(self): |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = dict( |
| | | debug_authorization=True, reload_templates=True) |
| | | debug_authorization=True, reload_templates=True |
| | | ) |
| | | logger = self._registerLogger() |
| | | self._registerSecurityPolicy(True) |
| | | result = self.config._derive_view( |
| | | view, context=Exception, permission='view') |
| | | view, context=Exception, permission='view' |
| | | ) |
| | | self.assertEqual(view.__module__, result.__module__) |
| | | self.assertEqual(view.__doc__, result.__doc__) |
| | | self.assertEqual(view.__name__, result.__name__) |
| | |
| | | request.url = 'url' |
| | | self.assertEqual(result(Exception(), request), response) |
| | | self.assertEqual(len(logger.messages), 1) |
| | | self.assertEqual(logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context Exception()): True") |
| | | self.assertEqual( |
| | | logger.messages[0], |
| | | "debug_authorization of url url (view name " |
| | | "'view_name' against context Exception()): True", |
| | | ) |
| | | |
| | | def test_secured_view_authn_policy_no_authz_policy(self): |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = {} |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | |
| | | policy = DummySecurityPolicy(False) |
| | | self.config.registry.registerUtility(policy, IAuthenticationPolicy) |
| | | result = self.config._derive_view(view, permission='view') |
| | |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = {} |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | |
| | | policy = DummySecurityPolicy(False) |
| | | self.config.registry.registerUtility(policy, IAuthorizationPolicy) |
| | | result = self.config._derive_view(view, permission='view') |
| | |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | from pyramid.httpexceptions import HTTPForbidden |
| | | |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | self.config.registry.settings = {} |
| | |
| | | try: |
| | | result(None, request) |
| | | except HTTPForbidden as e: |
| | | self.assertEqual(e.message, |
| | | 'Unauthorized: <lambda> failed permission check') |
| | | else: # pragma: no cover |
| | | self.assertEqual( |
| | | e.message, 'Unauthorized: <lambda> failed permission check' |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_secured_view_raises_forbidden_with_name(self): |
| | | from pyramid.interfaces import IAuthenticationPolicy |
| | | from pyramid.interfaces import IAuthorizationPolicy |
| | | from pyramid.httpexceptions import HTTPForbidden |
| | | def myview(request): pass |
| | | |
| | | def myview(request): # pragma: no cover |
| | | pass |
| | | |
| | | self.config.registry.settings = {} |
| | | policy = DummySecurityPolicy(False) |
| | | self.config.registry.registerUtility(policy, IAuthenticationPolicy) |
| | |
| | | try: |
| | | result(None, request) |
| | | except HTTPForbidden as e: |
| | | self.assertEqual(e.message, |
| | | 'Unauthorized: myview failed permission check') |
| | | else: # pragma: no cover |
| | | self.assertEqual( |
| | | e.message, 'Unauthorized: myview failed permission check' |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_secured_view_skipped_by_default_on_exception_view(self): |
| | | from pyramid.request import Request |
| | | from pyramid.security import NO_PERMISSION_REQUIRED |
| | | |
| | | def view(request): |
| | | raise ValueError |
| | | |
| | | def excview(request): |
| | | return 'hello' |
| | | |
| | | self._registerSecurityPolicy(False) |
| | | self.config.add_settings({'debug_authorization': True}) |
| | | self.config.set_default_permission('view') |
| | | self.config.add_view(view, name='foo', permission=NO_PERMISSION_REQUIRED) |
| | | self.config.add_view( |
| | | view, name='foo', permission=NO_PERMISSION_REQUIRED |
| | | ) |
| | | self.config.add_view(excview, context=ValueError, renderer='string') |
| | | app = self.config.make_wsgi_app() |
| | | request = Request.blank('/foo', base_url='http://example.com') |
| | |
| | | from pyramid.httpexceptions import HTTPForbidden |
| | | from pyramid.request import Request |
| | | from pyramid.security import NO_PERMISSION_REQUIRED |
| | | |
| | | def view(request): |
| | | raise ValueError |
| | | def excview(request): pass |
| | | |
| | | def excview(request): # pragma: no cover |
| | | pass |
| | | |
| | | self._registerSecurityPolicy(False) |
| | | self.config.add_view(view, name='foo', permission=NO_PERMISSION_REQUIRED) |
| | | self.config.add_view(excview, context=ValueError, renderer='string', |
| | | permission='view') |
| | | self.config.add_view( |
| | | view, name='foo', permission=NO_PERMISSION_REQUIRED |
| | | ) |
| | | self.config.add_view( |
| | | excview, context=ValueError, renderer='string', permission='view' |
| | | ) |
| | | app = self.config.make_wsgi_app() |
| | | request = Request.blank('/foo', base_url='http://example.com') |
| | | request.method = 'POST' |
| | |
| | | request.get_response(app) |
| | | except HTTPForbidden: |
| | | pass |
| | | else: # pragma: no cover |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_secured_view_passed_on_explicit_exception_view(self): |
| | | from pyramid.request import Request |
| | | from pyramid.security import NO_PERMISSION_REQUIRED |
| | | |
| | | def view(request): |
| | | raise ValueError |
| | | |
| | | def excview(request): |
| | | return 'hello' |
| | | |
| | | self._registerSecurityPolicy(True) |
| | | self.config.add_view(view, name='foo', permission=NO_PERMISSION_REQUIRED) |
| | | self.config.add_view(excview, context=ValueError, renderer='string', |
| | | permission='view') |
| | | self.config.add_view( |
| | | view, name='foo', permission=NO_PERMISSION_REQUIRED |
| | | ) |
| | | self.config.add_view( |
| | | excview, context=ValueError, renderer='string', permission='view' |
| | | ) |
| | | app = self.config.make_wsgi_app() |
| | | request = Request.blank('/foo', base_url='http://example.com') |
| | | request.method = 'POST' |
| | |
| | | |
| | | def test_predicate_mismatch_view_has_no_name(self): |
| | | from pyramid.exceptions import PredicateMismatch |
| | | |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | |
| | | def predicate1(context, request): |
| | | return False |
| | | |
| | | predicate1.text = lambda *arg: 'text' |
| | | result = self.config._derive_view(view, predicates=[predicate1]) |
| | | request = self._makeRequest() |
| | |
| | | try: |
| | | result(None, None) |
| | | except PredicateMismatch as e: |
| | | self.assertEqual(e.detail, |
| | | 'predicate mismatch for view <lambda> (text)') |
| | | else: # pragma: no cover |
| | | self.assertEqual( |
| | | e.detail, 'predicate mismatch for view <lambda> (text)' |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_predicate_mismatch_view_has_name(self): |
| | | from pyramid.exceptions import PredicateMismatch |
| | | def myview(request): pass |
| | | |
| | | def myview(request): # pragma: no cover |
| | | pass |
| | | |
| | | def predicate1(context, request): |
| | | return False |
| | | |
| | | predicate1.text = lambda *arg: 'text' |
| | | result = self.config._derive_view(myview, predicates=[predicate1]) |
| | | request = self._makeRequest() |
| | |
| | | try: |
| | | result(None, None) |
| | | except PredicateMismatch as e: |
| | | self.assertEqual(e.detail, |
| | | 'predicate mismatch for view myview (text)') |
| | | else: # pragma: no cover |
| | | self.assertEqual( |
| | | e.detail, 'predicate mismatch for view myview (text)' |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_predicate_mismatch_exception_has_text_in_detail(self): |
| | | from pyramid.exceptions import PredicateMismatch |
| | | def myview(request): pass |
| | | |
| | | def myview(request): # pragma: no cover |
| | | pass |
| | | |
| | | def predicate1(context, request): |
| | | return True |
| | | |
| | | predicate1.text = lambda *arg: 'pred1' |
| | | |
| | | def predicate2(context, request): |
| | | return False |
| | | |
| | | predicate2.text = lambda *arg: 'pred2' |
| | | result = self.config._derive_view(myview, |
| | | predicates=[predicate1, predicate2]) |
| | | result = self.config._derive_view( |
| | | myview, predicates=[predicate1, predicate2] |
| | | ) |
| | | request = self._makeRequest() |
| | | request.method = 'POST' |
| | | try: |
| | | result(None, None) |
| | | except PredicateMismatch as e: |
| | | self.assertEqual(e.detail, |
| | | 'predicate mismatch for view myview (pred2)') |
| | | else: # pragma: no cover |
| | | self.assertEqual( |
| | | e.detail, 'predicate mismatch for view myview (pred2)' |
| | | ) |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_with_predicates_all(self): |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | predicates = [] |
| | | |
| | | def predicate1(context, request): |
| | | predicates.append(True) |
| | | return True |
| | | |
| | | def predicate2(context, request): |
| | | predicates.append(True) |
| | | return True |
| | | result = self.config._derive_view(view, |
| | | predicates=[predicate1, predicate2]) |
| | | |
| | | result = self.config._derive_view( |
| | | view, predicates=[predicate1, predicate2] |
| | | ) |
| | | request = self._makeRequest() |
| | | request.method = 'POST' |
| | | next = result(None, None) |
| | |
| | | def test_with_predicates_checker(self): |
| | | view = lambda *arg: 'OK' |
| | | predicates = [] |
| | | |
| | | def predicate1(context, request): |
| | | predicates.append(True) |
| | | return True |
| | | |
| | | def predicate2(context, request): |
| | | predicates.append(True) |
| | | return True |
| | | result = self.config._derive_view(view, |
| | | predicates=[predicate1, predicate2]) |
| | | |
| | | result = self.config._derive_view( |
| | | view, predicates=[predicate1, predicate2] |
| | | ) |
| | | request = self._makeRequest() |
| | | request.method = 'POST' |
| | | next = result.__predicated__(None, None) |
| | |
| | | |
| | | def test_with_predicates_notall(self): |
| | | from pyramid.httpexceptions import HTTPNotFound |
| | | |
| | | view = lambda *arg: 'OK' |
| | | predicates = [] |
| | | |
| | | def predicate1(context, request): |
| | | predicates.append(True) |
| | | return True |
| | | |
| | | predicate1.text = lambda *arg: 'text' |
| | | |
| | | def predicate2(context, request): |
| | | predicates.append(True) |
| | | return False |
| | | |
| | | predicate2.text = lambda *arg: 'text' |
| | | result = self.config._derive_view(view, |
| | | predicates=[predicate1, predicate2]) |
| | | result = self.config._derive_view( |
| | | view, predicates=[predicate1, predicate2] |
| | | ) |
| | | request = self._makeRequest() |
| | | request.method = 'POST' |
| | | self.assertRaises(HTTPNotFound, result, None, None) |
| | |
| | | from pyramid.response import Response |
| | | from pyramid.interfaces import IView |
| | | from pyramid.interfaces import IViewClassifier |
| | | |
| | | inner_response = Response('OK') |
| | | |
| | | def inner_view(context, request): |
| | | return inner_response |
| | | |
| | | def outer_view(context, request): |
| | | self.assertEqual(request.wrapped_response, inner_response) |
| | | self.assertEqual(request.wrapped_body, inner_response.body) |
| | | self.assertEqual(request.wrapped_view.__original_view__, |
| | | inner_view) |
| | | self.assertEqual( |
| | | request.wrapped_view.__original_view__, inner_view |
| | | ) |
| | | return Response(b'outer ' + request.wrapped_body) |
| | | |
| | | self.config.registry.registerAdapter( |
| | | outer_view, (IViewClassifier, None, None), IView, 'owrap') |
| | | result = self.config._derive_view(inner_view, viewname='inner', |
| | | wrapper_viewname='owrap') |
| | | outer_view, (IViewClassifier, None, None), IView, 'owrap' |
| | | ) |
| | | result = self.config._derive_view( |
| | | inner_view, viewname='inner', wrapper_viewname='owrap' |
| | | ) |
| | | self.assertFalse(result is inner_view) |
| | | self.assertEqual(inner_view.__module__, result.__module__) |
| | | self.assertEqual(inner_view.__doc__, result.__doc__) |
| | |
| | | |
| | | def test_with_wrapper_viewname_notfound(self): |
| | | from pyramid.response import Response |
| | | |
| | | inner_response = Response('OK') |
| | | |
| | | def inner_view(context, request): |
| | | return inner_response |
| | | wrapped = self.config._derive_view(inner_view, viewname='inner', |
| | | wrapper_viewname='owrap') |
| | | |
| | | wrapped = self.config._derive_view( |
| | | inner_view, viewname='inner', wrapper_viewname='owrap' |
| | | ) |
| | | request = self._makeRequest() |
| | | self.assertRaises(ValueError, wrapped, None, request) |
| | | |
| | | def test_as_newstyle_class_context_and_request_attr_and_renderer(self): |
| | | response = DummyResponse() |
| | | |
| | | class renderer(object): |
| | | def render_view(inself, req, resp, view_inst, ctx): |
| | | self.assertEqual(req, request) |
| | | self.assertEqual(resp, {'a':'1'}) |
| | | self.assertEqual(resp, {'a': '1'}) |
| | | self.assertEqual(view_inst.__class__, View) |
| | | self.assertEqual(ctx, context) |
| | | return response |
| | | |
| | | def clone(self): |
| | | return self |
| | | |
| | | class View(object): |
| | | def __init__(self, context, request): |
| | | pass |
| | | |
| | | def index(self): |
| | | return {'a':'1'} |
| | | result = self.config._derive_view(View, |
| | | renderer=renderer(), attr='index') |
| | | return {'a': '1'} |
| | | |
| | | result = self.config._derive_view( |
| | | View, renderer=renderer(), attr='index' |
| | | ) |
| | | self.assertFalse(result is View) |
| | | self.assertEqual(result.__module__, View.__module__) |
| | | self.assertEqual(result.__doc__, View.__doc__) |
| | |
| | | |
| | | def test_as_newstyle_class_requestonly_attr_and_renderer(self): |
| | | response = DummyResponse() |
| | | |
| | | class renderer(object): |
| | | def render_view(inself, req, resp, view_inst, ctx): |
| | | self.assertEqual(req, request) |
| | | self.assertEqual(resp, {'a':'1'}) |
| | | self.assertEqual(resp, {'a': '1'}) |
| | | self.assertEqual(view_inst.__class__, View) |
| | | self.assertEqual(ctx, context) |
| | | return response |
| | | |
| | | def clone(self): |
| | | return self |
| | | |
| | | class View(object): |
| | | def __init__(self, request): |
| | | pass |
| | | |
| | | def index(self): |
| | | return {'a':'1'} |
| | | result = self.config.derive_view(View, |
| | | renderer=renderer(), attr='index') |
| | | return {'a': '1'} |
| | | |
| | | result = self.config.derive_view( |
| | | View, renderer=renderer(), attr='index' |
| | | ) |
| | | self.assertFalse(result is View) |
| | | self.assertEqual(result.__module__, View.__module__) |
| | | self.assertEqual(result.__doc__, View.__doc__) |
| | |
| | | |
| | | def test_as_oldstyle_cls_context_request_attr_and_renderer(self): |
| | | response = DummyResponse() |
| | | |
| | | class renderer(object): |
| | | def render_view(inself, req, resp, view_inst, ctx): |
| | | self.assertEqual(req, request) |
| | | self.assertEqual(resp, {'a':'1'}) |
| | | self.assertEqual(resp, {'a': '1'}) |
| | | self.assertEqual(view_inst.__class__, View) |
| | | self.assertEqual(ctx, context) |
| | | return response |
| | | |
| | | def clone(self): |
| | | return self |
| | | |
| | | class View: |
| | | def __init__(self, context, request): |
| | | pass |
| | | |
| | | def index(self): |
| | | return {'a':'1'} |
| | | result = self.config.derive_view(View, |
| | | renderer=renderer(), attr='index') |
| | | return {'a': '1'} |
| | | |
| | | result = self.config.derive_view( |
| | | View, renderer=renderer(), attr='index' |
| | | ) |
| | | self.assertFalse(result is View) |
| | | self.assertEqual(result.__module__, View.__module__) |
| | | self.assertEqual(result.__doc__, View.__doc__) |
| | |
| | | |
| | | def test_as_oldstyle_cls_requestonly_attr_and_renderer(self): |
| | | response = DummyResponse() |
| | | |
| | | class renderer(object): |
| | | def render_view(inself, req, resp, view_inst, ctx): |
| | | self.assertEqual(req, request) |
| | | self.assertEqual(resp, {'a':'1'}) |
| | | self.assertEqual(resp, {'a': '1'}) |
| | | self.assertEqual(view_inst.__class__, View) |
| | | self.assertEqual(ctx, context) |
| | | return response |
| | | |
| | | def clone(self): |
| | | return self |
| | | |
| | | class View: |
| | | def __init__(self, request): |
| | | pass |
| | | |
| | | def index(self): |
| | | return {'a':'1'} |
| | | result = self.config.derive_view(View, |
| | | renderer=renderer(), attr='index') |
| | | return {'a': '1'} |
| | | |
| | | result = self.config.derive_view( |
| | | View, renderer=renderer(), attr='index' |
| | | ) |
| | | self.assertFalse(result is View) |
| | | self.assertEqual(result.__module__, View.__module__) |
| | | self.assertEqual(result.__doc__, View.__doc__) |
| | |
| | | |
| | | def test_as_instance_context_and_request_attr_and_renderer(self): |
| | | response = DummyResponse() |
| | | |
| | | class renderer(object): |
| | | def render_view(inself, req, resp, view_inst, ctx): |
| | | self.assertEqual(req, request) |
| | | self.assertEqual(resp, {'a':'1'}) |
| | | self.assertEqual(resp, {'a': '1'}) |
| | | self.assertEqual(view_inst, view) |
| | | self.assertEqual(ctx, context) |
| | | return response |
| | | |
| | | def clone(self): |
| | | return self |
| | | |
| | | class View: |
| | | def index(self, context, request): |
| | | return {'a':'1'} |
| | | return {'a': '1'} |
| | | |
| | | view = View() |
| | | result = self.config.derive_view(view, |
| | | renderer=renderer(), attr='index') |
| | | result = self.config.derive_view( |
| | | view, renderer=renderer(), attr='index' |
| | | ) |
| | | self.assertFalse(result is view) |
| | | self.assertEqual(result.__module__, view.__module__) |
| | | self.assertEqual(result.__doc__, view.__doc__) |
| | |
| | | |
| | | def test_as_instance_requestonly_attr_and_renderer(self): |
| | | response = DummyResponse() |
| | | |
| | | class renderer(object): |
| | | def render_view(inself, req, resp, view_inst, ctx): |
| | | self.assertEqual(req, request) |
| | | self.assertEqual(resp, {'a':'1'}) |
| | | self.assertEqual(resp, {'a': '1'}) |
| | | self.assertEqual(view_inst, view) |
| | | self.assertEqual(ctx, context) |
| | | return response |
| | | |
| | | def clone(self): |
| | | return self |
| | | |
| | | class View: |
| | | def index(self, request): |
| | | return {'a':'1'} |
| | | return {'a': '1'} |
| | | |
| | | view = View() |
| | | result = self.config.derive_view(view, |
| | | renderer=renderer(), attr='index') |
| | | result = self.config.derive_view( |
| | | view, renderer=renderer(), attr='index' |
| | | ) |
| | | self.assertFalse(result is view) |
| | | self.assertEqual(result.__module__, view.__module__) |
| | | self.assertEqual(result.__doc__, view.__doc__) |
| | |
| | | |
| | | def test_with_view_mapper_config_specified(self): |
| | | response = DummyResponse() |
| | | |
| | | class mapper(object): |
| | | def __init__(self, **kw): |
| | | self.kw = kw |
| | | |
| | | def __call__(self, view): |
| | | def wrapped(context, request): |
| | | return response |
| | | |
| | | return wrapped |
| | | def view(context, request): return 'NOTOK' |
| | | |
| | | def view(context, request): # pragma: no cover |
| | | return 'NOTOK' |
| | | |
| | | result = self.config._derive_view(view, mapper=mapper) |
| | | self.assertFalse(result.__wraps__ is view) |
| | | self.assertEqual(result(None, None), response) |
| | | |
| | | def test_with_view_mapper_view_specified(self): |
| | | from pyramid.response import Response |
| | | |
| | | response = Response() |
| | | |
| | | def mapper(**kw): |
| | | def inner(view): |
| | | def superinner(context, request): |
| | | self.assertEqual(request, None) |
| | | return response |
| | | |
| | | return superinner |
| | | |
| | | return inner |
| | | def view(context, request): return 'NOTOK' |
| | | |
| | | def view(context, request): # pragma: no cover |
| | | return 'NOTOK' |
| | | |
| | | view.__view_mapper__ = mapper |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result.__wraps__ is view) |
| | |
| | | |
| | | def test_with_view_mapper_default_mapper_specified(self): |
| | | from pyramid.response import Response |
| | | |
| | | response = Response() |
| | | |
| | | def mapper(**kw): |
| | | def inner(view): |
| | | def superinner(context, request): |
| | | self.assertEqual(request, None) |
| | | return response |
| | | return response |
| | | |
| | | return superinner |
| | | |
| | | return inner |
| | | |
| | | self.config.set_view_mapper(mapper) |
| | | def view(context, request): return 'NOTOK' |
| | | |
| | | def view(context, request): # pragma: no cover |
| | | return 'NOTOK' |
| | | |
| | | result = self.config.derive_view(view) |
| | | self.assertFalse(result.__wraps__ is view) |
| | | self.assertEqual(result(None, None), response) |
| | | |
| | | def test_attr_wrapped_view_branching_default_phash(self): |
| | | from pyramid.config.util import DEFAULT_PHASH |
| | | def view(context, request): pass |
| | | from pyramid.config.predicates import DEFAULT_PHASH |
| | | |
| | | def view(context, request): # pragma: no cover |
| | | pass |
| | | |
| | | result = self.config._derive_view(view, phash=DEFAULT_PHASH) |
| | | self.assertEqual(result.__wraps__, view) |
| | | |
| | | def test_attr_wrapped_view_branching_nondefault_phash(self): |
| | | def view(context, request): pass |
| | | def view(context, request): # pragma: no cover |
| | | pass |
| | | |
| | | result = self.config._derive_view(view, phash='nondefault') |
| | | self.assertNotEqual(result, view) |
| | | |
| | | def test_http_cached_view_integer(self): |
| | | import datetime |
| | | from pyramid.response import Response |
| | | |
| | | response = Response('OK') |
| | | |
| | | def inner_view(context, request): |
| | | return response |
| | | |
| | | result = self.config._derive_view(inner_view, http_cache=3600) |
| | | self.assertFalse(result is inner_view) |
| | | self.assertEqual(inner_view.__module__, result.__module__) |
| | |
| | | def test_http_cached_view_timedelta(self): |
| | | import datetime |
| | | from pyramid.response import Response |
| | | |
| | | response = Response('OK') |
| | | |
| | | def inner_view(context, request): |
| | | return response |
| | | result = self.config._derive_view(inner_view, |
| | | http_cache=datetime.timedelta(hours=1)) |
| | | |
| | | result = self.config._derive_view( |
| | | inner_view, http_cache=datetime.timedelta(hours=1) |
| | | ) |
| | | self.assertFalse(result is inner_view) |
| | | self.assertEqual(inner_view.__module__, result.__module__) |
| | | self.assertEqual(inner_view.__doc__, result.__doc__) |
| | |
| | | def test_http_cached_view_tuple(self): |
| | | import datetime |
| | | from pyramid.response import Response |
| | | |
| | | response = Response('OK') |
| | | |
| | | def inner_view(context, request): |
| | | return response |
| | | result = self.config._derive_view(inner_view, |
| | | http_cache=(3600, {'public':True})) |
| | | |
| | | result = self.config._derive_view( |
| | | inner_view, http_cache=(3600, {'public': True}) |
| | | ) |
| | | self.assertFalse(result is inner_view) |
| | | self.assertEqual(inner_view.__module__, result.__module__) |
| | | self.assertEqual(inner_view.__doc__, result.__doc__) |
| | |
| | | |
| | | def test_http_cached_view_tuple_seconds_None(self): |
| | | from pyramid.response import Response |
| | | |
| | | response = Response('OK') |
| | | |
| | | def inner_view(context, request): |
| | | return response |
| | | result = self.config._derive_view(inner_view, |
| | | http_cache=(None, {'public':True})) |
| | | |
| | | result = self.config._derive_view( |
| | | inner_view, http_cache=(None, {'public': True}) |
| | | ) |
| | | self.assertFalse(result is inner_view) |
| | | self.assertEqual(inner_view.__module__, result.__module__) |
| | | self.assertEqual(inner_view.__doc__, result.__doc__) |
| | |
| | | |
| | | def test_http_cached_view_prevent_auto_set(self): |
| | | from pyramid.response import Response |
| | | |
| | | response = Response() |
| | | response.cache_control.prevent_auto = True |
| | | |
| | | def inner_view(context, request): |
| | | return response |
| | | |
| | | result = self.config._derive_view(inner_view, http_cache=3600) |
| | | request = self._makeRequest() |
| | | result = result(None, request) |
| | | self.assertEqual(result, response) # doesn't blow up |
| | | self.assertEqual(result, response) # doesn't blow up |
| | | headers = dict(result.headerlist) |
| | | self.assertFalse('Expires' in headers) |
| | | self.assertFalse('Cache-Control' in headers) |
| | |
| | | def test_http_cached_prevent_http_cache_in_settings(self): |
| | | self.config.registry.settings['prevent_http_cache'] = True |
| | | from pyramid.response import Response |
| | | |
| | | response = Response() |
| | | |
| | | def inner_view(context, request): |
| | | return response |
| | | |
| | | result = self.config._derive_view(inner_view, http_cache=3600) |
| | | request = self._makeRequest() |
| | | result = result(None, request) |
| | |
| | | self.assertFalse('Cache-Control' in headers) |
| | | |
| | | def test_http_cached_view_bad_tuple(self): |
| | | def view(request): pass |
| | | self.assertRaises(ConfigurationError, self.config._derive_view, |
| | | view, http_cache=(None,)) |
| | | def view(request): # pragma: no cover |
| | | pass |
| | | |
| | | self.assertRaises( |
| | | ConfigurationError, |
| | | self.config._derive_view, |
| | | view, |
| | | http_cache=(None,), |
| | | ) |
| | | |
| | | def test_csrf_view_ignores_GET(self): |
| | | response = DummyResponse() |
| | | |
| | | def inner_view(request): |
| | | return response |
| | | |
| | | request = self._makeRequest() |
| | | request.method = 'GET' |
| | | view = self.config._derive_view(inner_view, require_csrf=True) |
| | |
| | | |
| | | def test_csrf_view_fails_with_bad_POST_header(self): |
| | | from pyramid.exceptions import BadCSRFToken |
| | | def inner_view(request): pass |
| | | |
| | | def inner_view(request): # pragma: no cover |
| | | pass |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | |
| | | |
| | | def test_csrf_view_passes_with_good_POST_header(self): |
| | | response = DummyResponse() |
| | | |
| | | def inner_view(request): |
| | | return response |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | |
| | | |
| | | def test_csrf_view_fails_with_bad_POST_token(self): |
| | | from pyramid.exceptions import BadCSRFToken |
| | | def inner_view(request): pass |
| | | |
| | | def inner_view(request): # pragma: no cover |
| | | pass |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | |
| | | |
| | | def test_csrf_view_passes_with_good_POST_token(self): |
| | | response = DummyResponse() |
| | | |
| | | def inner_view(request): |
| | | return response |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | |
| | | |
| | | def test_csrf_view_https_domain(self): |
| | | response = DummyResponse() |
| | | |
| | | def inner_view(request): |
| | | return response |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "https" |
| | | request.domain = "example.com" |
| | |
| | | |
| | | def test_csrf_view_fails_on_bad_PUT_header(self): |
| | | from pyramid.exceptions import BadCSRFToken |
| | | def inner_view(request): pass |
| | | |
| | | def inner_view(request): # pragma: no cover |
| | | pass |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'PUT' |
| | |
| | | |
| | | def test_csrf_view_fails_on_bad_referrer(self): |
| | | from pyramid.exceptions import BadCSRFOrigin |
| | | def inner_view(request): pass |
| | | |
| | | def inner_view(request): # pragma: no cover |
| | | pass |
| | | |
| | | request = self._makeRequest() |
| | | request.method = "POST" |
| | | request.scheme = "https" |
| | |
| | | |
| | | def test_csrf_view_fails_on_bad_origin(self): |
| | | from pyramid.exceptions import BadCSRFOrigin |
| | | def inner_view(request): pass |
| | | |
| | | def inner_view(request): # pragma: no cover |
| | | pass |
| | | |
| | | request = self._makeRequest() |
| | | request.method = "POST" |
| | | request.scheme = "https" |
| | |
| | | |
| | | def test_csrf_view_enabled_by_default(self): |
| | | from pyramid.exceptions import BadCSRFToken |
| | | def inner_view(request): pass |
| | | |
| | | def inner_view(request): # pragma: no cover |
| | | pass |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | |
| | | def test_csrf_view_enabled_via_callback(self): |
| | | def callback(request): |
| | | return True |
| | | |
| | | from pyramid.exceptions import BadCSRFToken |
| | | def inner_view(request): pass |
| | | |
| | | def inner_view(request): # pragma: no cover |
| | | pass |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | | request.session = DummySession({'csrf_token': 'foo'}) |
| | | self.config.set_default_csrf_options(require_csrf=True, callback=callback) |
| | | self.config.set_default_csrf_options( |
| | | require_csrf=True, callback=callback |
| | | ) |
| | | view = self.config._derive_view(inner_view) |
| | | self.assertRaises(BadCSRFToken, lambda: view(None, request)) |
| | | |
| | | def test_csrf_view_disabled_via_callback(self): |
| | | def callback(request): |
| | | return False |
| | | |
| | | response = DummyResponse() |
| | | |
| | | def inner_view(request): |
| | | return response |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | | request.session = DummySession({'csrf_token': 'foo'}) |
| | | self.config.set_default_csrf_options(require_csrf=True, callback=callback) |
| | | self.config.set_default_csrf_options( |
| | | require_csrf=True, callback=callback |
| | | ) |
| | | view = self.config._derive_view(inner_view) |
| | | result = view(None, request) |
| | | self.assertTrue(result is response) |
| | | |
| | | def test_csrf_view_uses_custom_csrf_token(self): |
| | | response = DummyResponse() |
| | | |
| | | def inner_view(request): |
| | | return response |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | |
| | | |
| | | def test_csrf_view_uses_custom_csrf_header(self): |
| | | response = DummyResponse() |
| | | |
| | | def inner_view(request): |
| | | return response |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | |
| | | |
| | | def test_csrf_view_uses_custom_methods(self): |
| | | response = DummyResponse() |
| | | |
| | | def inner_view(request): |
| | | return response |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'PUT' |
| | | request.session = DummySession({'csrf_token': 'foo'}) |
| | | self.config.set_default_csrf_options( |
| | | require_csrf=True, safe_methods=['PUT']) |
| | | require_csrf=True, safe_methods=['PUT'] |
| | | ) |
| | | view = self.config._derive_view(inner_view) |
| | | result = view(None, request) |
| | | self.assertTrue(result is response) |
| | | |
| | | def test_csrf_view_uses_view_option_override(self): |
| | | response = DummyResponse() |
| | | |
| | | def inner_view(request): |
| | | return response |
| | | |
| | | request = self._makeRequest() |
| | | request.scheme = "http" |
| | | request.method = 'POST' |
| | |
| | | |
| | | def test_csrf_view_skipped_by_default_on_exception_view(self): |
| | | from pyramid.request import Request |
| | | |
| | | def view(request): |
| | | raise ValueError |
| | | |
| | | def excview(request): |
| | | return 'hello' |
| | | |
| | | self.config.set_default_csrf_options(require_csrf=True) |
| | | self.config.set_session_factory( |
| | | lambda request: DummySession({'csrf_token': 'foo'})) |
| | | lambda request: DummySession({'csrf_token': 'foo'}) |
| | | ) |
| | | self.config.add_view(view, name='foo', require_csrf=False) |
| | | self.config.add_view(excview, context=ValueError, renderer='string') |
| | | app = self.config.make_wsgi_app() |
| | |
| | | def test_csrf_view_failed_on_explicit_exception_view(self): |
| | | from pyramid.exceptions import BadCSRFToken |
| | | from pyramid.request import Request |
| | | |
| | | def view(request): |
| | | raise ValueError |
| | | def excview(request): pass |
| | | |
| | | def excview(request): # pragma: no cover |
| | | pass |
| | | |
| | | self.config.set_default_csrf_options(require_csrf=True) |
| | | self.config.set_session_factory( |
| | | lambda request: DummySession({'csrf_token': 'foo'})) |
| | | lambda request: DummySession({'csrf_token': 'foo'}) |
| | | ) |
| | | self.config.add_view(view, name='foo', require_csrf=False) |
| | | self.config.add_view(excview, context=ValueError, renderer='string', |
| | | require_csrf=True) |
| | | self.config.add_view( |
| | | excview, context=ValueError, renderer='string', require_csrf=True |
| | | ) |
| | | app = self.config.make_wsgi_app() |
| | | request = Request.blank('/foo', base_url='http://example.com') |
| | | request.method = 'POST' |
| | |
| | | request.get_response(app) |
| | | except BadCSRFToken: |
| | | pass |
| | | else: # pragma: no cover |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_csrf_view_passed_on_explicit_exception_view(self): |
| | | from pyramid.request import Request |
| | | |
| | | def view(request): |
| | | raise ValueError |
| | | |
| | | def excview(request): |
| | | return 'hello' |
| | | |
| | | self.config.set_default_csrf_options(require_csrf=True) |
| | | self.config.set_session_factory( |
| | | lambda request: DummySession({'csrf_token': 'foo'})) |
| | | lambda request: DummySession({'csrf_token': 'foo'}) |
| | | ) |
| | | self.config.add_view(view, name='foo', require_csrf=False) |
| | | self.config.add_view(excview, context=ValueError, renderer='string', |
| | | require_csrf=True) |
| | | self.config.add_view( |
| | | excview, context=ValueError, renderer='string', require_csrf=True |
| | | ) |
| | | app = self.config.make_wsgi_app() |
| | | request = Request.blank('/foo', base_url='http://example.com') |
| | | request.method = 'POST' |
| | |
| | | from pyramid.interfaces import IViewDerivers |
| | | |
| | | self.config.add_view_deriver(None, 'deriv1') |
| | | self.config.add_view_deriver(None, 'deriv2', 'decorated_view', 'deriv1') |
| | | self.config.add_view_deriver( |
| | | None, 'deriv2', 'decorated_view', 'deriv1' |
| | | ) |
| | | self.config.add_view_deriver(None, 'deriv3', 'deriv2', 'deriv1') |
| | | |
| | | derivers = self.config.registry.getUtility(IViewDerivers) |
| | | derivers_sorted = derivers.sorted() |
| | | dlist = [d for (d, _) in derivers_sorted] |
| | | self.assertEqual([ |
| | | 'secured_view', |
| | | 'csrf_view', |
| | | 'owrapped_view', |
| | | 'http_cached_view', |
| | | 'decorated_view', |
| | | 'deriv2', |
| | | 'deriv3', |
| | | 'deriv1', |
| | | 'rendered_view', |
| | | 'mapped_view', |
| | | ], dlist) |
| | | self.assertEqual( |
| | | [ |
| | | 'secured_view', |
| | | 'csrf_view', |
| | | 'owrapped_view', |
| | | 'http_cached_view', |
| | | 'decorated_view', |
| | | 'deriv2', |
| | | 'deriv3', |
| | | 'deriv1', |
| | | 'rendered_view', |
| | | 'mapped_view', |
| | | ], |
| | | dlist, |
| | | ) |
| | | |
| | | def test_right_order_implicit(self): |
| | | from pyramid.interfaces import IViewDerivers |
| | |
| | | derivers = self.config.registry.getUtility(IViewDerivers) |
| | | derivers_sorted = derivers.sorted() |
| | | dlist = [d for (d, _) in derivers_sorted] |
| | | self.assertEqual([ |
| | | 'secured_view', |
| | | 'csrf_view', |
| | | 'owrapped_view', |
| | | 'http_cached_view', |
| | | 'decorated_view', |
| | | 'deriv3', |
| | | 'deriv2', |
| | | 'deriv1', |
| | | 'rendered_view', |
| | | 'mapped_view', |
| | | ], dlist) |
| | | self.assertEqual( |
| | | [ |
| | | 'secured_view', |
| | | 'csrf_view', |
| | | 'owrapped_view', |
| | | 'http_cached_view', |
| | | 'decorated_view', |
| | | 'deriv3', |
| | | 'deriv2', |
| | | 'deriv1', |
| | | 'rendered_view', |
| | | 'mapped_view', |
| | | ], |
| | | dlist, |
| | | ) |
| | | |
| | | def test_right_order_under_rendered_view(self): |
| | | from pyramid.interfaces import IViewDerivers |
| | | |
| | | self.config.add_view_deriver(None, 'deriv1', 'rendered_view', 'mapped_view') |
| | | self.config.add_view_deriver( |
| | | None, 'deriv1', 'rendered_view', 'mapped_view' |
| | | ) |
| | | |
| | | derivers = self.config.registry.getUtility(IViewDerivers) |
| | | derivers_sorted = derivers.sorted() |
| | | dlist = [d for (d, _) in derivers_sorted] |
| | | self.assertEqual([ |
| | | 'secured_view', |
| | | 'csrf_view', |
| | | 'owrapped_view', |
| | | 'http_cached_view', |
| | | 'decorated_view', |
| | | 'rendered_view', |
| | | 'deriv1', |
| | | 'mapped_view', |
| | | ], dlist) |
| | | |
| | | self.assertEqual( |
| | | [ |
| | | 'secured_view', |
| | | 'csrf_view', |
| | | 'owrapped_view', |
| | | 'http_cached_view', |
| | | 'decorated_view', |
| | | 'rendered_view', |
| | | 'deriv1', |
| | | 'mapped_view', |
| | | ], |
| | | dlist, |
| | | ) |
| | | |
| | | def test_right_order_under_rendered_view_others(self): |
| | | from pyramid.interfaces import IViewDerivers |
| | | |
| | | self.config.add_view_deriver(None, 'deriv1', 'rendered_view', 'mapped_view') |
| | | self.config.add_view_deriver( |
| | | None, 'deriv1', 'rendered_view', 'mapped_view' |
| | | ) |
| | | self.config.add_view_deriver(None, 'deriv2') |
| | | self.config.add_view_deriver(None, 'deriv3') |
| | | |
| | | derivers = self.config.registry.getUtility(IViewDerivers) |
| | | derivers_sorted = derivers.sorted() |
| | | dlist = [d for (d, _) in derivers_sorted] |
| | | self.assertEqual([ |
| | | 'secured_view', |
| | | 'csrf_view', |
| | | 'owrapped_view', |
| | | 'http_cached_view', |
| | | 'decorated_view', |
| | | 'deriv3', |
| | | 'deriv2', |
| | | 'rendered_view', |
| | | 'deriv1', |
| | | 'mapped_view', |
| | | ], dlist) |
| | | self.assertEqual( |
| | | [ |
| | | 'secured_view', |
| | | 'csrf_view', |
| | | 'owrapped_view', |
| | | 'http_cached_view', |
| | | 'decorated_view', |
| | | 'deriv3', |
| | | 'deriv2', |
| | | 'rendered_view', |
| | | 'deriv1', |
| | | 'mapped_view', |
| | | ], |
| | | dlist, |
| | | ) |
| | | |
| | | |
| | | class TestAddDeriver(unittest.TestCase): |
| | | |
| | | def setUp(self): |
| | | self.config = testing.setUp() |
| | | |
| | |
| | | self.assertFalse(response.deriv) |
| | | self.config.add_view_deriver(deriv, 'test_deriv') |
| | | |
| | | result = self.config._derive_view(view) |
| | | result = self.config._derive_view(view) # noqa: F841 |
| | | self.assertTrue(response.deriv) |
| | | |
| | | def test_override_deriver(self): |
| | |
| | | flags.clear() |
| | | view2 = AView() |
| | | self.config.add_view_deriver(deriv2, 'test_deriv') |
| | | result = self.config._derive_view(view2) |
| | | result = self.config._derive_view(view2) # noqa: F841 |
| | | self.assertFalse(flags.get('deriv1')) |
| | | self.assertTrue(flags.get('deriv2')) |
| | | |
| | | def test_override_mapped_view(self): |
| | | from pyramid.viewderivers import VIEW |
| | | |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | flags = {} |
| | |
| | | |
| | | flags.clear() |
| | | self.config.add_view_deriver( |
| | | deriv1, name='mapped_view', under='rendered_view', over=VIEW) |
| | | result = self.config._derive_view(view) |
| | | deriv1, name='mapped_view', under='rendered_view', over=VIEW |
| | | ) |
| | | result = self.config._derive_view(view) # noqa: F841 |
| | | self.assertTrue(flags.get('deriv1')) |
| | | |
| | | def test_add_multi_derivers_ordered(self): |
| | | from pyramid.viewderivers import INGRESS |
| | | |
| | | response = DummyResponse() |
| | | view = lambda *arg: response |
| | | response.deriv = [] |
| | |
| | | self.config.add_view_deriver(deriv1, 'deriv1') |
| | | self.config.add_view_deriver(deriv2, 'deriv2', INGRESS, 'deriv1') |
| | | self.config.add_view_deriver(deriv3, 'deriv3', 'deriv2', 'deriv1') |
| | | result = self.config._derive_view(view) |
| | | result = self.config._derive_view(view) # noqa: F841 |
| | | self.assertEqual(response.deriv, ['deriv1', 'deriv3', 'deriv2']) |
| | | |
| | | def test_add_deriver_without_name(self): |
| | | from pyramid.interfaces import IViewDerivers |
| | | def deriv1(view, info): pass |
| | | |
| | | def deriv1(view, info): # pragma: no cover |
| | | pass |
| | | |
| | | self.config.add_view_deriver(deriv1) |
| | | derivers = self.config.registry.getUtility(IViewDerivers) |
| | | self.assertTrue('deriv1' in derivers.names) |
| | |
| | | def test_add_deriver_reserves_ingress(self): |
| | | from pyramid.exceptions import ConfigurationError |
| | | from pyramid.viewderivers import INGRESS |
| | | def deriv1(view, info): pass |
| | | |
| | | def deriv1(view, info): # pragma: no cover |
| | | pass |
| | | |
| | | self.assertRaises( |
| | | ConfigurationError, self.config.add_view_deriver, deriv1, INGRESS) |
| | | ConfigurationError, self.config.add_view_deriver, deriv1, INGRESS |
| | | ) |
| | | |
| | | def test_add_deriver_enforces_ingress_is_first(self): |
| | | from pyramid.exceptions import ConfigurationError |
| | | from pyramid.viewderivers import INGRESS |
| | | def deriv1(view, info): pass |
| | | |
| | | def deriv1(view, info): # pragma: no cover |
| | | pass |
| | | |
| | | try: |
| | | self.config.add_view_deriver(deriv1, over=INGRESS) |
| | | except ConfigurationError as ex: |
| | | self.assertTrue('cannot be over INGRESS' in ex.args[0]) |
| | | else: # pragma: no cover |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_add_deriver_enforces_view_is_last(self): |
| | | from pyramid.exceptions import ConfigurationError |
| | | from pyramid.viewderivers import VIEW |
| | | def deriv1(view, info): pass |
| | | |
| | | def deriv1(view, info): # pragma: no cover |
| | | pass |
| | | |
| | | try: |
| | | self.config.add_view_deriver(deriv1, under=VIEW) |
| | | except ConfigurationError as ex: |
| | | self.assertTrue('cannot be under VIEW' in ex.args[0]) |
| | | else: # pragma: no cover |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | def test_add_deriver_enforces_mapped_view_is_last(self): |
| | | from pyramid.exceptions import ConfigurationError |
| | | def deriv1(view, info): pass |
| | | |
| | | def deriv1(view, info): # pragma: no cover |
| | | pass |
| | | |
| | | try: |
| | | self.config.add_view_deriver(deriv1, 'deriv1', under='mapped_view') |
| | | except ConfigurationError as ex: |
| | | self.assertTrue('cannot be under "mapped_view"' in ex.args[0]) |
| | | else: # pragma: no cover |
| | | else: # pragma: no cover |
| | | raise AssertionError |
| | | |
| | | |
| | |
| | | self.config = None |
| | | testing.tearDown() |
| | | |
| | | def _getViewCallable(self, config, ctx_iface=None, request_iface=None, |
| | | name=''): |
| | | def _getViewCallable( |
| | | self, config, ctx_iface=None, request_iface=None, name='' |
| | | ): |
| | | from zope.interface import Interface |
| | | from pyramid.interfaces import IRequest |
| | | from pyramid.interfaces import IView |
| | | from pyramid.interfaces import IViewClassifier |
| | | |
| | | classifier = IViewClassifier |
| | | if ctx_iface is None: |
| | | ctx_iface = Interface |
| | | if request_iface is None: |
| | | request_iface = IRequest |
| | | return config.registry.adapters.lookup( |
| | | (classifier, request_iface, ctx_iface), IView, name=name, |
| | | default=None) |
| | | (classifier, request_iface, ctx_iface), |
| | | IView, |
| | | name=name, |
| | | default=None, |
| | | ) |
| | | |
| | | def _makeRequest(self, config): |
| | | request = DummyRequest() |
| | |
| | | def deriv1(view, info): |
| | | response.deriv.append(info.options['deriv1']) |
| | | return view |
| | | |
| | | deriv1.options = ('deriv1',) |
| | | |
| | | def deriv2(view, info): |
| | | response.deriv.append(info.options['deriv2']) |
| | | return view |
| | | |
| | | deriv2.options = ('deriv2',) |
| | | |
| | | self.config.add_view_deriver(deriv1, 'deriv1') |
| | |
| | | |
| | | def test_unexpected_view_options(self): |
| | | from pyramid.exceptions import ConfigurationError |
| | | def deriv1(view, info): pass |
| | | |
| | | def deriv1(view, info): # pragma: no cover |
| | | pass |
| | | |
| | | self.config.add_view_deriver(deriv1, 'deriv1') |
| | | self.assertRaises( |
| | | ConfigurationError, |
| | | lambda: self.config.add_view(lambda r: {}, deriv1='test1')) |
| | | lambda: self.config.add_view(lambda r: {}, deriv1='test1'), |
| | | ) |
| | | |
| | | |
| | | @implementer(IResponse) |
| | | class DummyResponse(object): |
| | |
| | | default_content_type = None |
| | | body = None |
| | | |
| | | |
| | | class DummyRequest: |
| | | subpath = () |
| | | matchdict = None |
| | | request_iface = IRequest |
| | | request_iface = IRequest |
| | | |
| | | def __init__(self, environ=None): |
| | | if environ is None: |
| | |
| | | self.headers = {} |
| | | self.response = DummyResponse() |
| | | |
| | | |
| | | class DummyLogger: |
| | | def __init__(self): |
| | | self.messages = [] |
| | | |
| | | def info(self, msg): |
| | | self.messages.append(msg) |
| | | |
| | | warn = info |
| | | debug = info |
| | | |
| | | |
| | | class DummySecurityPolicy: |
| | | def __init__(self, permitted=True): |
| | |
| | | def permits(self, context, principals, permission): |
| | | return self.permitted |
| | | |
| | | |
| | | class DummySession(dict): |
| | | def get_csrf_token(self): |
| | | return self['csrf_token'] |
| | | |
| | | |
| | | def parse_httpdate(s): |
| | | import datetime |
| | | |
| | | # cannot use %Z, must use literal GMT; Jython honors timezone |
| | | # but CPython does not |
| | | return datetime.datetime.strptime(s, "%a, %d %b %Y %H:%M:%S GMT") |
| | | |
| | | |
| | | def assert_similar_datetime(one, two): |
| | | for attr in ('year', 'month', 'day', 'hour', 'minute'): |
| | | one_attr = getattr(one, attr) |
| | | two_attr = getattr(two, attr) |
| | | if not one_attr == two_attr: # pragma: no cover |
| | | if not one_attr == two_attr: # pragma: no cover |
| | | raise AssertionError('%r != %r in %s' % (one_attr, two_attr, attr)) |