[ZPT] Authorization problem with public PT using restricted resources

Clemens Robbenhaar rzpt@zope.org
Mon, 14 Oct 2002 15:20:48 +0200


Dear ZPTistas,

 I got a little problem with authorization and ZPT's in Zope2.5.1.
Maybe this has been already resolved in later version; call me a troll
if it is, but I cannot find it out from the "cvs diff" ...

 The problem is some kind of heisenbug I encounter if a page template
itself is public available, but uses some resource which is
protected. Even when I am logged in with Manager role, Zope sometimes
fails to get the authorization information and rejects access. It does
not so by letting the browser pop up the login form, but fails directly
(error message follows below.)


 In the current example, this is some page template
"manage_assocationsForm" for managing instances of a product, where the
template does not define access restrictions by itself, but contains the
line:

<h1 tal:replace="structure here/manage_page_header">Header</h1>

The "manager_page_header" wants a "Manager" role for access.


Normally this works well, but sometimes I get the exception:


Error Type: Undefined
Error Value: You are not allowed to access manage_page_header in this context not found in 'here/manage_page_header', at line 6, column 1
Zope reported an error for:


Traceback (innermost last):
  File /opt/zope_cvs/Zope/lib/python/ZPublisher/Publish.py, line 150, in publish_module
  File /opt/zope_cvs/Zope/lib/python/ZPublisher/Publish.py, line 114, in publish
  File /opt/zope_cvs/Zope/lib/python/Zope/__init__.py, line 159, in zpublisher_exception_hook
    (Object: service_view_registry)
  File /opt/zope_cvs/Zope/lib/python/ZPublisher/Publish.py, line 98, in publish
  File /opt/zope_cvs/Zope/lib/python/ZPublisher/mapply.py, line 88, in mapply
    (Object: manage_assocationsForm)
  File /opt/zope_cvs/Zope/lib/python/ZPublisher/Publish.py, line 39, in call_object
    (Object: manage_assocationsForm)
  File /opt/zope_cvs/Zope/lib/python/Shared/DC/Scripts/Bindings.py, line 252, in __call__
    (Object: manage_assocationsForm)
  File /opt/zope_cvs/Zope/lib/python/Shared/DC/Scripts/Bindings.py, line 283, in _bindAndExec
    (Object: manage_assocationsForm)
  File /opt/zope_cvs/Zope/lib/python/Products/PageTemplates/PageTemplateFile.py, line 95, in _exec
    (Object: manage_assocationsForm)
  File /opt/zope_cvs/Zope/lib/python/Products/PageTemplates/PageTemplate.py, line 86, in pt_render
    (Object: manage_assocationsForm)
    (Info: {'container': <ViewRegistry instance at 8578560>,
 'here': <ViewRegistry instance at 8578560>,
 'modules': <Products.PageTemplates.ZRPythonExpr._SecureModuleImporter instance at 0x8648834>,
 'nothing': None,
 'options': {'args': ()},
 'request': [[snipped a lot, but:]]  'user': Anonymous User})
  File /opt/zope_cvs/Zope/lib/python/TAL/TALInterpreter.py, line 158, in __call__
  File /opt/zope_cvs/Zope/lib/python/TAL/TALInterpreter.py, line 191, in interpret
  File /opt/zope_cvs/Zope/lib/python/TAL/TALInterpreter.py, line 432, in do_insertStructure_tal
  File /opt/zope_cvs/Zope/lib/python/Products/PageTemplates/TALES.py, line 247, in evaluate
  File /opt/zope_cvs/Zope/lib/python/Products/PageTemplates/Expressions.py, line 198, in __call__
  File /opt/zope_cvs/Zope/lib/python/Products/PageTemplates/Expressions.py, line 188, in _eval
Undefined: (see above)


It seems Zope evaluates the authorization information lazy; first it
checks no authorization is needed, thus the request passes through with
the anonymous user. Then it evaluates the "here/manage_page_header"
which leads to an "Unauthorized" exception. Now Zope should look up the
authorization information (there should be one, as I am logged in as
Manager, and other pages in the ZMI are fine), but for some reason it
fails.

 Very strangely this happens only accidentally, but if it does it
remains relatively permanent. Restart of Zope does not help, but logging
out from the ZMI and log in again helps.


 One fix is to put some "Manager" access restrictions on the original
page template; but I feel this is an ad hoc fix. Another hotfix which
solves the problem is to mess in the ZPublishers exception hook, as in:

Index: Zope/__init__.py
===================================================================
RCS file: /cvs-repository/Zope/lib/python/Zope/__init__.py,v
retrieving revision 1.26.14.1
diff -w -u -r1.26.14.1 __init__.py
--- Zope/__init__.py    29 Jan 2002 17:44:37 -0000      1.26.14.1
+++ Zope/__init__.py    14 Oct 2002 13:03:49 -0000
@@ -103,10 +103,17 @@
     ListType=type([]),
     ):
     try:
+        from Products.PageTemplates.TALES import TALESError
+        if t is TALESError and v.type is not None:
+            t, v = v.type, v.value
+        
         if isinstance(t, StringType):
-            if t.lower() in ('unauthorized', 'redirect'):
+            if t.lower() in ('unauthorized',):
+                raise t
+            if t.lower() in ('redirect', ):
                 raise
         else:
+
             if t is SystemExit:
                 raise
             if issubclass(t, ConflictError):

(I hope You read "diff").

 Of course I do not propose this patch (beside it is pretty messy code,
it would introduce unnecessary dependencies). I only want to show this
ugly thing fixed the problem.


 The cause of the problem seems to be Page Templates wrap all exceptions
into TALESError. I heard rumours that this is changed in newer versions,
but I am not long enough on the list to figure out if and what happened.

 Maybe the problem is somewhere else at the point where Zope failes to
the the authentification data, or its a browser issue (Mozilla0.9.9 in
this case) ... then I am on the wrong list with this issue.


 Anyway, could this be solved by upgrading? Am I boring You by bringing
up an already known/fixed bug? Or has nobody else encountered such a
problem? Any feedback would be highly appreciated.


Cheers,
Clemens.


P.S. btw, the problem appears with Zope 2.5.1 (build from cvs source),
python 2.1.3 on a debian/linux box with a 2.4.9 kernel, if that
information is relevant.