Commit 7b65910f authored by 's avatar

fixed regression in Unauthorized handling:

In previous Zope versions string exceptions were used and all exceptions
re-raised. This doesn't work with each kind of exception, but we can still do
it with Unauthorized exceptions. This way the special handling for Unauthorized
exceptions works again, HTTPResponse._unauthorized is called again. This is now
done after rendering to make sure we don't break logging and custom views.
parent 0727afe1
...@@ -121,7 +121,8 @@ Handle zExceptions.Redirect. ...@@ -121,7 +121,8 @@ Handle zExceptions.Redirect.
Redirect: LOCATION Redirect: LOCATION
>>> browser.contents >>> browser.contents
Handle zExceptions.Unauthorized. Handle zExceptions.Unauthorized. We take the 'WWW-Authenticate' header as a
sign that HTTPResponse._unauthorized was called.
>>> from zExceptions import Unauthorized >>> from zExceptions import Unauthorized
>>> app.test_folder_1_.foo.exception = Unauthorized('ERROR VALUE') >>> app.test_folder_1_.foo.exception = Unauthorized('ERROR VALUE')
...@@ -135,6 +136,8 @@ Handle zExceptions.Unauthorized. ...@@ -135,6 +136,8 @@ Handle zExceptions.Unauthorized.
True True
>>> 'Error Value: ERROR VALUE' in browser.contents >>> 'Error Value: ERROR VALUE' in browser.contents
True True
>>> browser.headers['WWW-Authenticate']
'basic realm="Zope2"'
>>> browser.handleErrors = False >>> browser.handleErrors = False
>>> browser.open('http://localhost/test_folder_1_/foo') >>> browser.open('http://localhost/test_folder_1_/foo')
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE # FOR A PARTICULAR PURPOSE.
# #
############################################################################## ##############################################################################
"""Initialize the Zope2 Package and provide a published module """Initialize the Zope2 Package and provide a published module
...@@ -29,10 +29,10 @@ from App.config import getConfiguration ...@@ -29,10 +29,10 @@ from App.config import getConfiguration
from time import asctime from time import asctime
from zExceptions import upgradeException from zExceptions import upgradeException
from zExceptions import Redirect from zExceptions import Redirect
from zExceptions import Unauthorized
from ZODB.POSException import ConflictError from ZODB.POSException import ConflictError
import transaction import transaction
import AccessControl.User import AccessControl.User
import App.FindHomes
import ExtensionClass import ExtensionClass
import imp import imp
import logging import logging
...@@ -224,6 +224,12 @@ class ZPublisherExceptionHook: ...@@ -224,6 +224,12 @@ class ZPublisherExceptionHook:
else: else:
view.__parent__ = published view.__parent__ = published
v = view() v = view()
if issubclass(t, Unauthorized):
# Re-raise Unauthorized to make sure it is handled
# correctly. We can't do that with all exceptions
# because some don't work with the rendered v as
# argument.
raise t, v, traceback
response = REQUEST.RESPONSE response = REQUEST.RESPONSE
response.setStatus(t) response.setStatus(t)
response.setBody(v) response.setBody(v)
...@@ -264,12 +270,18 @@ class ZPublisherExceptionHook: ...@@ -264,12 +270,18 @@ class ZPublisherExceptionHook:
error_log_url=error_log_url) error_log_url=error_log_url)
if result is not None: if result is not None:
t, v, traceback = result t, v, traceback = result
if issubclass(t, Unauthorized):
# Re-raise Unauthorized to make sure it is handled
# correctly. We can't do that with all exceptions
# because some don't work with the rendered v as
# argument.
raise t, v, traceback
response = REQUEST.RESPONSE response = REQUEST.RESPONSE
response.setStatus(t) response.setStatus(t)
response.setBody(v) response.setBody(v)
return response return response
except TypeError: except TypeError:
# Pre 2.6 call signature # BBB: Pre Zope 2.6 call signature
f(client, REQUEST, t, v, traceback) f(client, REQUEST, t, v, traceback)
finally: finally:
......
...@@ -347,7 +347,6 @@ def registerExceptionView(for_): ...@@ -347,7 +347,6 @@ def registerExceptionView(for_):
class ExceptionViewsTest(PlacelessSetup, ExceptionHookTestCase): class ExceptionViewsTest(PlacelessSetup, ExceptionHookTestCase):
def testCustomExceptionViewUnauthorized(self): def testCustomExceptionViewUnauthorized(self):
from ZPublisher.HTTPResponse import HTTPResponse
from AccessControl import Unauthorized from AccessControl import Unauthorized
registerExceptionView(IUnauthorized) registerExceptionView(IUnauthorized)
def f(): def f():
...@@ -355,8 +354,7 @@ class ExceptionViewsTest(PlacelessSetup, ExceptionHookTestCase): ...@@ -355,8 +354,7 @@ class ExceptionViewsTest(PlacelessSetup, ExceptionHookTestCase):
request = self._makeRequest() request = self._makeRequest()
client = StandardClient() client = StandardClient()
v = self.call_exc_value(client, request, f) v = self.call_exc_value(client, request, f)
self.failUnless(isinstance(v, HTTPResponse), v) self.failUnless(isinstance(v, Unauthorized), v)
self.failUnless(v.status == 401, (v.status, 401))
self.failUnless("Exception View: Unauthorized" in str(v)) self.failUnless("Exception View: Unauthorized" in str(v))
self.failUnless("Context: StandardClient" in str(v)) self.failUnless("Context: StandardClient" in str(v))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment