changeset 2895:a0101a36a5a5

fix #218 Access Denied traceback when ACLs prevent user from viewing a transclusion
author RogerHaase <haaserd@gmail.com>
date Thu, 12 Feb 2015 10:38:36 -0700
parents 1a930b0f4ec5
children 76187487acb2
files MoinMoin/converter/_tests/test_include.py MoinMoin/converter/include.py
diffstat 2 files changed, 23 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/converter/_tests/test_include.py	Mon Feb 02 12:31:55 2015 -0700
+++ b/MoinMoin/converter/_tests/test_include.py	Thu Feb 12 10:38:36 2015 -0700
@@ -8,7 +8,7 @@
 
 from MoinMoin.converter.include import *
 from MoinMoin.items import Item
-from MoinMoin.constants.keys import CONTENTTYPE
+from MoinMoin.constants.keys import CONTENTTYPE, ACL
 from MoinMoin._tests import wikiconfig, update_item
 
 
@@ -73,6 +73,15 @@
         # an error message will follow strong tag
         assert '<strong class="moin-error">' in rendered
 
+    def test_Include_Read_Permission_Denied(self):
+        # attempt to include an item that user cannot read
+        update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8', ACL: u'All:write,create,admin,destroy'}, u'no one can read')
+        update_item(u'page2', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'some text{{page1}}more text')
+        page2 = Item.create(u'page2')
+        rendered = page2.content._render_data()
+        # an error message will follow p tag, similar to: Access Denied, transcluded content suppressed.
+        assert '<div class="warning"><p>' in rendered
+
     def test_ExternalInclude(self):
         # external include
         update_item(u'page1', {CONTENTTYPE: u'text/x.moin.wiki;charset=utf-8'}, u'{{http://moinmo.in}}')
--- a/MoinMoin/converter/include.py	Mon Feb 02 12:31:55 2015 -0700
+++ b/MoinMoin/converter/include.py	Thu Feb 12 10:38:36 2015 -0700
@@ -102,8 +102,8 @@
 from MoinMoin.util.mime import type_moin_document
 from MoinMoin.util.iri import Iri, IriPath
 from MoinMoin.util.tree import html, moin_page, xinclude, xlink
-
 from MoinMoin.converter.html_out import mark_item_as_transclusion, Attributes
+from MoinMoin.i18n import _, L_, N_
 
 from ._args import Arguments
 
@@ -293,8 +293,16 @@
 
                     link.path = path
 
-                    page = Item.create(unicode(path))
-                    pages = ((page, link), )
+                    if flaskg.user.may.read(unicode(path)):
+                        page = Item.create(unicode(path))
+                        pages = ((page, link), )
+                    else:
+                        # ACLs prevent user from viewing a transclusion - show message
+                        message = moin_page.p(children=(_('Access Denied, transcluded content suppressed.')))
+                        attrib = {html.class_: 'warning'}
+                        div = ET.Element(moin_page.div, attrib, children=(message, ))
+                        container = ET.Element(moin_page.body, children=(div, ))
+                        return [container, 0]  # replace transclusion with container's child
 
                 elif xp_include_pages:
                     # XXX we currently interpret xp_include_pages as wildcard, but it should be regex
@@ -370,7 +378,7 @@
 
                     if ret:
                         # Either child or a descendant of child is a transclusion.
-                        # See top of this script for notes on why these DOM adjustmenta are required.
+                        # See top of this script for notes on why these DOM adjustments are required.
                         if isinstance(ret, ET.Node) and elem.tag.name in NO_BLOCK_CHILDREN:
                             body = ret[0]
                             if len(body) == 0:
@@ -420,7 +428,7 @@
                                 elem[i] = ret
                         elif isinstance(ret, types.ListType):
                             # a container has been returned.
-                            # Note: there are two places where a container may be returned
+                            # Note: there are multiple places where a container may be constructed
                             ret_container, trans_ptr = ret
                             # trans_ptr points to the transclusion within ret_container.
                             # Here the transclusion will always contain a block level element