Commit 9db00ea6 authored by Tristan Cavelier's avatar Tristan Cavelier

erp5_xhtml_style: redirect to portal if unauthorized to show an error

After going to a resource that you are unauthorized to view, then the error is shown incorrectly because the default UI tries to use properties of the same resource, reraising unauthorized error.

With this commit, if unauthorized is reraised, it tries to show the error from the portal object. If the user is still unauthorized to see the error output, then the error is shown directly without the classic UI.

/reviewed-on nexedi/erp5!192
parent 80523287
"""
Tries to render the error with classic UI including all toolbars.
If the user is unauthorized to show it from this context, then
it tries to render the error from the web site root. If no web site
root is defined then it renders the error from portal.
"""
from zExceptions import Unauthorized
try:
return context.standard_error_message_template(*args, **kw)
except Unauthorized:
pass
try:
# Note: - user can be unauthorized to getWebSiteValue() from this context
# - "web_site_value" comes from erp5.Document.WebSite.WEBSITE_KEY (unauthorized to import)
web_site_split_path = context.REQUEST.get("web_site_value")
if web_site_split_path:
web_site_value = context.getPortalObject().restrictedTraverse(web_site_split_path, None)
if web_site_value is not None:
return web_site_value.standard_error_message_template(*args, **kw)
except Unauthorized:
pass
return context.getPortalObject().standard_error_message_template(*args, **kw)
......@@ -2,10 +2,14 @@
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
......@@ -20,6 +24,18 @@
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
......@@ -33,25 +49,13 @@
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
<key> <string>_params</string> </key>
<value> <string>*args, **kw</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>standard_error_message</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>standard_error_message_render</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -2,9 +2,8 @@
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
metal:use-macro="context/main_template/macros/master"
metal:define-macro="standard_error_message_render"
>
<metal:slot metal:fill-slot="main" i18n:domain="erp5_ui">
<div tal:condition="options/error_message" tal:content="structure options/error_message" />
<div tal:condition="not: options/error_message">
<h2 i18n:translate="">Site Error</h2>
......@@ -28,5 +27,4 @@
<hr noshade="noshade" />
<a href="error_log_url" tal:attributes="href options/error_log_url" i18n:translate="">Show Error Log Entry</a>
</div>
</metal:slot>
</tal:block>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>standard_error_message_template</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<tal:block
xmlns:tal="http://xml.zope.org/namespaces/tal"
xmlns:metal="http://xml.zope.org/namespaces/metal"
xmlns:i18n="http://xml.zope.org/namespaces/i18n"
metal:use-macro="context/main_template/macros/master"
>
<metal:slot metal:fill-slot="main" i18n:domain="erp5_ui">
<tal:block metal:use-macro="context/standard_error_message_render/macros/standard_error_message_render"></tal:block>
</metal:slot>
</tal:block>
\ No newline at end of file
......@@ -40,6 +40,8 @@ from Testing import ZopeTestCase
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from Products.ERP5Type.tests.utils import DummyTranslationService
from zExceptions import Unauthorized
if 1: # BBB
# Zope 2.12, simulate setting the globalTranslationService with
# zope.i18n utilities
......@@ -622,6 +624,32 @@ class TestERP5Core(ERP5TypeTestCase, ZopeTestCase.Functional):
self.assertEqual(response.status, 401)
self.assertEqual(response.getheader('WWW-Authenticate'), None)
def test_standardErrorMessageShouldNotRaiseUnauthorizeOnUnauthorizeDocument(self):
"""
When trying to show the `standard_error_message` on a document that user
doesn't have permission to access, the Unauthorized error should be handled
to allow the user to see the actual error.
"""
module = self.portal.newContent(portal_type='Folder', id='test_error_message')
document_1 = module.newContent(portal_type='Folder', id='1')
# Sanity check : can View document
document_1.view()
# Must not raise
document_1.standard_error_message(error_type="MyErrorType", error_message="my error message.")
document_1.manage_permission('View', [], acquire=0)
document_1.manage_permission('Access contents information', [], acquire=0)
# Sanity check : cannot View document anymore
self.assertRaises(Unauthorized, document_1.view)
# Must not raise even if Unauthorized to view
document_1.standard_error_message(error_type="MyErrorType", error_message="my error message.")
response = self.publish(document_1.getPath(), self.auth)
self.assertEqual(response.getStatus(), 401)
self.assertNotIn("Also, the following error occurred", str(response))
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestERP5Core))
......
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