[Checkins] SVN: zmi.core/trunk/src/zmi/core/exception/ Copy browser code from zope.app.exception.

Yusei Tahara yusei at domen.cx
Sun Jun 7 11:26:18 EDT 2009


Log message for revision 100694:
  Copy browser code from zope.app.exception.
  

Changed:
  A   zmi.core/trunk/src/zmi/core/exception/__init__.py
  A   zmi.core/trunk/src/zmi/core/exception/configure.zcml
  A   zmi.core/trunk/src/zmi/core/exception/exception-ftesting.zcml
  A   zmi.core/trunk/src/zmi/core/exception/notfound.pt
  A   zmi.core/trunk/src/zmi/core/exception/notfound.py
  A   zmi.core/trunk/src/zmi/core/exception/systemerror.pt
  A   zmi.core/trunk/src/zmi/core/exception/systemerror.txt
  A   zmi.core/trunk/src/zmi/core/exception/tests/
  A   zmi.core/trunk/src/zmi/core/exception/tests/__init__.py
  A   zmi.core/trunk/src/zmi/core/exception/tests/test_error.py
  A   zmi.core/trunk/src/zmi/core/exception/tests/test_unauthorized.py
  A   zmi.core/trunk/src/zmi/core/exception/unauthorized.pt
  A   zmi.core/trunk/src/zmi/core/exception/unauthorized.py
  A   zmi.core/trunk/src/zmi/core/exception/user.pt
  A   zmi.core/trunk/src/zmi/core/exception/user.py

-=-
Added: zmi.core/trunk/src/zmi/core/exception/__init__.py
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/__init__.py	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/__init__.py	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1 @@
+# empty __init__.py file to make this directory into a package

Added: zmi.core/trunk/src/zmi/core/exception/configure.zcml
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/configure.zcml	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/configure.zcml	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,38 @@
+<zope:configure
+   xmlns:zope="http://namespaces.zope.org/zope"
+   xmlns="http://namespaces.zope.org/browser">
+
+  <page
+      for="zope.interface.common.interfaces.IException"
+      name="index.html"
+      template="systemerror.pt"
+      class="..systemerror.SystemErrorView"
+      permission="zope.Public"
+      />
+
+  <page
+      for="zope.security.interfaces.IUnauthorized"
+      name="index.html"
+      permission="zope.Public"
+      class=".unauthorized.Unauthorized"
+      />
+
+  <zope:adapter factory=".unauthorized.default_template" name="default" />
+
+  <page
+      for="zope.exceptions.interfaces.IUserError"
+      name="index.html"
+      permission="zope.Public"
+      template="user.pt"
+      class=".user.UserErrorView"
+      />
+
+  <page
+      for="zope.publisher.interfaces.INotFound"
+      name="index.html"
+      permission="zope.Public"
+      template="notfound.pt"
+      class=".notfound.NotFound"
+      />
+
+</zope:configure>

Added: zmi.core/trunk/src/zmi/core/exception/exception-ftesting.zcml
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/exception-ftesting.zcml	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/exception-ftesting.zcml	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,11 @@
+<configure
+   xmlns="http://namespaces.zope.org/browser">
+
+    <page
+      for="zope.app.folder.interfaces.IFolder"
+      name="componentlookuperror.html"
+      class="zmi.core.exception.tests.test_error.RaiseComponentLookupError"
+      permission="zope.Public"
+      />
+
+</configure>

Added: zmi.core/trunk/src/zmi/core/exception/notfound.pt
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/notfound.pt	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/notfound.pt	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,21 @@
+<html metal:use-macro="context/@@standard_macros/dialog"
+    i18n:domain="zope">
+<body>
+
+<div metal:fill-slot="body">
+
+<h3  i18n:translate="">
+  The page that you are trying to access is not available
+</h3>
+<br/> 
+<b  i18n:translate="">Please note the following:</b>
+<br/>
+<ol>
+   <li i18n:translate=""> You might have misspelled the url </li>
+   <li i18n:translate="">
+     You might be trying to access a non-existing page
+   </li>
+</ol>
+</div>
+</body>
+</html>

Added: zmi.core/trunk/src/zmi/core/exception/notfound.py
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/notfound.py	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/notfound.py	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,28 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""NotFound Error View class.
+
+$Id: notfound.py 70826 2006-10-20 03:41:16Z baijum $
+"""
+__docformat__ = 'restructuredtext'
+
+class NotFound(object):
+    """`NotFound` Error View
+
+    `NotFound` errors should return 404 instead of 200.
+    """
+
+    def __call__(self, *args, **kw):
+        self.request.response.setStatus(404)
+        return self.index(*args, **kw)

Added: zmi.core/trunk/src/zmi/core/exception/systemerror.pt
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/systemerror.pt	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/systemerror.pt	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,6 @@
+<html i18n:domain="zope"><title i18n:translate="">System Error</title>
+<body tal:define="ignored python:request.response.setStatus(500)"
+    i18n:translate="">
+  A system error occurred.
+</body>
+</html>

Added: zmi.core/trunk/src/zmi/core/exception/systemerror.txt
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/systemerror.txt	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/systemerror.txt	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,74 @@
+System Errors
+=============
+
+System Errors are errors representing a system failure.  At the
+application level, they are errors that are uncaught by the
+application and that a developer hasn't provided a custom error view
+for.
+
+Zope provides a default system error view that prints an obnoxius
+terse message and that sets the response status.
+
+To see an example of this, we'll create a ZPT page with an intentional
+error:
+
+  >>> print http(r"""
+  ... POST /+/zope.app.zptpage.ZPTPage%3D HTTP/1.1
+  ... Authorization: Basic mgr:mgrpw
+  ... Content-Length: 739
+  ... Content-Type: multipart/form-data; boundary=---------------------------125598457818223697821067764270
+  ... Referer: http://localhost:8081/+/zope.app.zptpage.ZPTPage=
+  ...
+  ... -----------------------------125598457818223697821067764270
+  ... Content-Disposition: form-data; name="field.source"
+  ...
+  ... <html><body tal:content="container/eek" /></html>
+  ... -----------------------------125598457818223697821067764270
+  ... Content-Disposition: form-data; name="field.expand.used"
+  ...
+  ...
+  ... -----------------------------125598457818223697821067764270
+  ... Content-Disposition: form-data; name="field.evaluateInlineCode.used"
+  ...
+  ...
+  ... -----------------------------125598457818223697821067764270
+  ... Content-Disposition: form-data; name="UPDATE_SUBMIT"
+  ...
+  ... Add
+  ... -----------------------------125598457818223697821067764270
+  ... Content-Disposition: form-data; name="add_input_name"
+  ...
+  ... test.html
+  ... -----------------------------125598457818223697821067764270--
+  ... """)
+  HTTP/1.1 303 See Other
+  ...
+  Location: http://localhost/@@contents.html
+  ...
+
+When we visit it, we get a terse error and a 500 status:
+
+We get a system error, because the problem is in the template, not in
+the URL:
+
+  >>> print http(r"""
+  ... GET /test.html HTTP/1.1
+  ... """)
+  HTTP/1.1 500 Internal Server Error
+  ...
+    A system error occurred.
+  ...
+
+Another way of getting a system error is the occurrence of a system
+error, such as ``ComponentLookupError``. I have registered a simple
+view in ``exception-ftesting.zcml`` that will raise a component lookup
+error. So if we call ``componentlookuperror.html``, we should get the
+error message:
+
+  >>> print http(r"""
+  ... GET /componentlookuperror.html HTTP/1.1
+  ... """)
+  HTTP/1.1 500 Internal Server Error
+  ...
+    A system error occurred.
+  ...


Property changes on: zmi.core/trunk/src/zmi/core/exception/systemerror.txt
___________________________________________________________________
Added: svn:eol-style
   + native

Added: zmi.core/trunk/src/zmi/core/exception/tests/__init__.py
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/tests/__init__.py	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/tests/__init__.py	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1 @@
+# empty __init__.py file to make this directory into a package

Added: zmi.core/trunk/src/zmi/core/exception/tests/test_error.py
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/tests/test_error.py	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/tests/test_error.py	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,50 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Functional tests for NotFoundError
+
+$Id: test_error.py 73711 2007-03-27 10:50:23Z dobe $
+"""
+import unittest
+from zope.app.testing import functional
+from zope.component.interfaces import ComponentLookupError
+from zope.app.exception.testing import AppExceptionLayer
+
+class RaiseComponentLookupError(object):
+
+    def __call__(self):
+        raise ComponentLookupError()
+
+
+class TestComponentLookupError(functional.BrowserTestCase):
+
+    def testComponentLookupError(self):
+        response = self.publish('/foobar', basic='mgr:mgrpw',
+                                handle_errors=True)
+        self.assertEqual(response.getStatus(), 404)
+        body = response.getBody()
+        self.assert_(
+            'The page that you are trying to access is not available' in body)
+
+
+def test_suite():
+    TestComponentLookupError.layer = AppExceptionLayer
+    systemerror = functional.FunctionalDocFileSuite('../systemerror.txt')
+    systemerror.layer = AppExceptionLayer
+    return unittest.TestSuite((
+        unittest.makeSuite(TestComponentLookupError),
+        systemerror,
+        ))
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')

Added: zmi.core/trunk/src/zmi/core/exception/tests/test_unauthorized.py
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/tests/test_unauthorized.py	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/tests/test_unauthorized.py	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,127 @@
+##############################################################################
+#
+# Copyright (c) 2001-2009 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Test Unauthorized Exception Views
+
+$Id: test_unauthorized.py 100113 2009-05-18 20:08:41Z icemac $
+"""
+from unittest import TestCase, main, makeSuite
+from zope import component, interface
+import zope.app.pagetemplate.namedtemplate
+from zope.publisher.browser import TestRequest
+from zope.authentication.interfaces import IAuthentication
+from zope.security.interfaces import IPrincipal
+from zope.app.testing import ztapi
+from zmi.core.exception.unauthorized import Unauthorized
+from zope.app.testing.placelesssetup import PlacelessSetup
+
+class DummyPrincipal(object):
+    interface.implements(IPrincipal)  # this is a lie
+
+    def __init__(self, id):
+        self.id = id
+
+    def getId(self):
+        return self.id
+
+class DummyAuthUtility(object):
+    interface.implements(IAuthentication)  # this is a lie
+
+    status = None
+
+    def unauthorized(self, principal_id, request):
+        self.principal_id = principal_id
+        self.request = request
+        if self.status is not None:
+            self.request.response.setStatus(self.status)
+
+class DummyTemplate(object):
+
+    def __init__(self, context):
+        self.context = context
+
+    component.adapts(Unauthorized)
+    interface.implements(zope.app.pagetemplate.namedtemplate.INamedTemplate)
+
+    def __call__(self):
+        return 'You are not authorized'
+
+class Test(PlacelessSetup, TestCase):
+
+    def setUp(self):
+        super(Test, self).setUp()
+        self.auth = DummyAuthUtility()
+        ztapi.provideUtility(IAuthentication, self.auth)
+
+    def tearDown(self):
+        super(Test, self).tearDown()
+
+    def testUnauthorized(self):
+        component.provideAdapter(DummyTemplate, name="default")
+        exception = Exception()
+        try:
+            raise exception
+        except:
+            pass
+        request = TestRequest()
+        request.setPrincipal(DummyPrincipal(23))
+        u = Unauthorized(exception, request)
+        res = u()
+
+        # Make sure that we rendered the expected template
+        self.assertEqual("You are not authorized", res)
+
+        # Make sure the response status was set
+        self.assertEqual(request.response.getStatus(), 403)
+
+        # check headers that work around squid "negative_ttl"
+        self.assertEqual(request.response.getHeader('Expires'),
+                         'Mon, 26 Jul 1997 05:00:00 GMT')
+        self.assertEqual(request.response.getHeader('Pragma'),
+                         'no-cache')
+        self.assertEqual(request.response.getHeader('Cache-Control'),
+                         'no-store, no-cache, must-revalidate')
+
+        # Make sure the auth utility was called
+        self.failUnless(self.auth.request is request)
+        self.assertEqual(self.auth.principal_id, 23)
+
+    def testRedirect(self):
+        exception= Exception()
+        try:
+            raise exception
+        except:
+            pass
+        request = TestRequest()
+        request.setPrincipal(DummyPrincipal(23))
+        u = Unauthorized(exception, request)
+
+        self.auth.status = 303
+
+        res = u()
+
+        # Make sure that the template was not rendered
+        self.assert_(res is None)
+
+        # Make sure the auth's redirect is honored
+        self.assertEqual(request.response.getStatus(), 303)
+
+        # Make sure the auth utility was called
+        self.failUnless(self.auth.request is request)
+        self.assertEqual(self.auth.principal_id, 23)
+
+def test_suite():
+    return makeSuite(Test)
+
+if __name__=='__main__':
+    main(defaultTest='test_suite')

Added: zmi.core/trunk/src/zmi/core/exception/unauthorized.pt
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/unauthorized.pt	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/unauthorized.pt	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,13 @@
+<html metal:use-macro="context/@@standard_macros/page"
+    i18n:domain="zope">
+<body i18n:domain="zope">
+
+<div metal:fill-slot="body">
+
+<h1 i18n:translate="">Unauthorized</h1>
+
+<p i18n:translate="">You are not authorized</p>
+
+</div>
+</body>
+</html>

Added: zmi.core/trunk/src/zmi/core/exception/unauthorized.py
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/unauthorized.py	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/unauthorized.py	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,47 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Unauthorized Exception View Class
+
+$Id: unauthorized.py 100113 2009-05-18 20:08:41Z icemac $
+"""
+__docformat__ = 'restructuredtext'
+
+from zope.authentication.interfaces import IAuthentication
+from zope.publisher.browser import BrowserPage
+from zope.app.pagetemplate import namedtemplate
+from zope.component import getUtility
+from zope.app.pagetemplate import ViewPageTemplateFile
+
+class Unauthorized(BrowserPage):
+
+    def __call__(self):
+        # Set the error status to 403 (Forbidden) in the case when we don't
+        # challenge the user
+        self.request.response.setStatus(403)
+
+        # make sure that squid does not keep the response in the cache
+        self.request.response.setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT')
+        self.request.response.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate')
+        self.request.response.setHeader('Pragma', 'no-cache')
+
+        principal = self.request.principal
+        auth = getUtility(IAuthentication)
+        auth.unauthorized(principal.id, self.request)
+        if self.request.response.getStatus() not in (302, 303):
+            return self.template()
+
+    template = namedtemplate.NamedTemplate('default')
+
+default_template = namedtemplate.NamedTemplateImplementation(
+    ViewPageTemplateFile('unauthorized.pt'), Unauthorized)

Added: zmi.core/trunk/src/zmi/core/exception/user.pt
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/user.pt	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/user.pt	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,13 @@
+<html metal:use-macro="context/@@standard_macros/page"
+    i18n:domain="zope">
+<body>
+<div metal:fill-slot="body">
+
+  <ul>
+    <li tal:repeat="part context" tal:content="part"
+        i18n:translate="">Error message</li>
+  </ul>
+
+</div>
+</body>
+</html>

Added: zmi.core/trunk/src/zmi/core/exception/user.py
===================================================================
--- zmi.core/trunk/src/zmi/core/exception/user.py	                        (rev 0)
+++ zmi.core/trunk/src/zmi/core/exception/user.py	2009-06-07 15:26:18 UTC (rev 100694)
@@ -0,0 +1,23 @@
+##############################################################################
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+##############################################################################
+"""Support for user views
+
+$Id: user.py 26738 2004-07-23 22:12:52Z pruggera $
+"""
+__docformat__ = 'restructuredtext'
+
+class UserErrorView(object):
+
+    def title(self):
+        return self.context.__class__.__name__
+
+    



More information about the Checkins mailing list