[Zope3-checkins] SVN: Zope3/trunk/ - Bugfix:

Roger Ineichen roger at projekt01.ch
Sat Jan 28 15:55:51 EST 2006


Log message for revision 41479:
  - Bugfix:
    Allow 'zmi_views' actions like: 'javascript:popup()', 
    '../parentview.html' or '++namespace++foobar' as first menu items.
  - Added tests for management view selector
  - Update CHANGES.txt

Changed:
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/src/zope/app/publisher/browser/managementviewselector.py
  U   Zope3/trunk/src/zope/app/publisher/browser/menu.txt

-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2006-01-28 19:58:32 UTC (rev 41478)
+++ Zope3/trunk/doc/CHANGES.txt	2006-01-28 20:55:50 UTC (rev 41479)
@@ -10,6 +10,9 @@
 
     New features
 
+      - Allow ``zmi_views`` actions like: ``javascript:popup()``, 
+        ``../parentview.html`` or ``++namespace++foobar`` as first menu items.
+
       - Added ``-x dirs`` option to i18nextract that allows to exclude
         particular directories from being searched.
 

Modified: Zope3/trunk/src/zope/app/publisher/browser/managementviewselector.py
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/managementviewselector.py	2006-01-28 19:58:32 UTC (rev 41478)
+++ Zope3/trunk/src/zope/app/publisher/browser/managementviewselector.py	2006-01-28 20:55:50 UTC (rev 41479)
@@ -23,7 +23,11 @@
 from zope.app.publisher.browser.menu import getFirstMenuItem
 
 class ManagementViewSelector(BrowserView):
-    """View that selects the first available management view."""
+    """View that selects the first available management view.
+
+    Support 'zmi_views' actions like: 'javascript:alert("hello")', 
+    '../view_on_parent.html' or '++rollover++'.
+    """
     implements(IBrowserPublisher)
 
     def browserDefault(self, request):
@@ -33,8 +37,12 @@
         item = getFirstMenuItem('zmi_views', self.context, self.request)
 
         if item:
-            self.request.response.redirect(item['action'])
-            return u''
+            redirect_url = item['action']
+            if not (redirect_url.startswith('../') or \
+                    redirect_url.lower().startswith('javascript:') or \
+                    redirect_url.lower().startswith('++')):
+                self.request.response.redirect(redirect_url)
+                return u''
 
         self.request.response.redirect('.') # Redirect to content/
         return u''

Modified: Zope3/trunk/src/zope/app/publisher/browser/menu.txt
===================================================================
--- Zope3/trunk/src/zope/app/publisher/browser/menu.txt	2006-01-28 19:58:32 UTC (rev 41478)
+++ Zope3/trunk/src/zope/app/publisher/browser/menu.txt	2006-01-28 20:55:50 UTC (rev 41479)
@@ -571,3 +571,65 @@
      <InterfaceClass zope.publisher.interfaces.browser.IDefaultBrowserLayer>),
     <InterfaceClass __builtin__.TestMenuItemType>,
     'View')]
+
+
+``ManagementViewSelector``
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Test the action (redirect url) of the first menu item and ensure that we don't
+redirect to the parent before we reach the item if we use actions like: '../'
+'javascript:popup()' or '++namespace++'.
+
+First setup the 'zmi_views' menu.
+
+  >>> class ZMIViews(zope.interface.Interface):
+  ...     """This is the zmi_views menu."""
+  >>> zope.interface.directlyProvides(ZMIViews, IMenuItemType)
+  >>> ztapi.provideUtility(IMenuItemType, ZMIViews, 'zmi_views')
+  >>> from zope.app.publisher.interfaces.browser import IBrowserMenu
+  >>> ztapi.provideUtility(
+  ...     IBrowserMenu, menu.BrowserMenu('zmi_views', u'ZMIViews', 
+  ...     u'ZMI Views'), 'zmi_views')
+
+Register some 'zmi_views' menu items.
+
+  >>> first = menumeta.MenuItemFactory(menu.BrowserMenuItem, title="First", 
+  ...     action="../")
+  >>> ztapi.provideAdapter((IContent, IBrowserRequest), ZMIViews, first, 
+  ...    'first')
+
+  >>> second = menumeta.MenuItemFactory(menu.BrowserMenuItem, title="Second", 
+  ...     action="second.html")
+  >>> ztapi.provideAdapter((IContent, IBrowserRequest), ZMIViews, second, 
+  ...    'second')
+
+Now create a new content object.
+
+  >>> content = Content()
+  >>> request = TestRequest(SERVER_URL='http://127.0.0.1/',
+  ...     PATH_INFO='/')
+
+Test the actions. Remember that this action get redirected before we traverse 
+to the content. This means actions like ``../`` will make it impossible to 
+access the view because the ``../`` will redirect us before we traverse.
+
+  >>> menus = menu.getMenu('zmi_views', content, request)
+  >>> [menu['action'] for menu in menus]
+  ['../', 'second.html']
+
+Now call the ManagementViewSelector view and we get a empty string as result.
+
+  >>> from zope.app.publisher.browser.managementviewselector import \
+  ...     ManagementViewSelector
+  >>> view = ManagementViewSelector(content, request)
+  >>> view()
+  u''
+
+Now check the more interesting redirect in the request. The redirect location
+is not like excpected '../'. We get '.' as the redirect location. This is 
+important otherwise we get redirected to the parent if we call the
+first menu item with actions like '../parentview.html' instead of traverse
+to the item.
+
+  >>> request.response.getHeader('Location')
+  '.'



More information about the Zope3-Checkins mailing list