The container has no security assertions
[Using Zope 2.6 final on Red Hat 7.3 with Python 2.1.3] I have a CMF portal type that's implemented as a Zope Product. I need to make a fairly complicated report for published content of this type. My basic approach is to take the portal_catalog.searchResults and stuff them into a Python class that provides access to the results in a way that facilitates the report. Where I'm stuck is that I just don't know how to get at that Python class from the Page Template where I do the report. I'm happy to provide as many details as possible, but I'm hoping at first to sketch the broad outlines of what I've tried, since I think what I'm missing is some basic understanding of the security model--that seems to be the particular wall I'm running into... I have a Python class that does not need to persist. I call it a DisplayBag. It sits in a module in the same folder as the portal type: PressRelease/ __init__.py DisplayBag.py PressRelease.py --> the portal_type DisplayBag.py looks like this: from AccessControl import ClassSecurityInfo from Acquisition import Implicit import Globals class DisplayBag(Implicit) security = ClassSecurityInfo() security.declareObjectPublic() def __init__(self, ...): # nothing really special security.declarePublic('years') def years(self): # nothing really special # other methods, similar to years, nothing really special Globals.InitializeClass(DisplayBag) The current hack I use to "get at" DisplayBag is with a method tacked onto the PressRelease class. (I've tried getting at the DisplayBag from an external method. I've had the same basic problem--the error indicated below.) class PressRelease(Document.Document): meta_type = 'Press Release' security = ClassSecurityInfo() def __init__(self, ...): # nothing really special # other methods--nothing really special security.declarePublic('make_bag') def make_bag(self, search_results): d = PressReleaseDisplayBag(search_results) # I've also tried __of__, which makes no difference (i.e., same error). # return d.__of__(self) return d InitializeClass(PressRelease) Then, in a skins folder, I have a PageTemplate called press_releases.pt. What this does is gets the published Press Releases and then, hackishly, takes the first one (so I have a PressRelease on which to call make_bag), do getObject() on it since searchResults doesn't give me the object, and call make_bag. I get the DisplayBag just fine--I've used tal:content="results" ('results' is the bag) to display it. But then when I call the years() method of the bag: <div tal:define="raw python:here.portal_catalog(portal_type='Press Release', review_state='published'); first_pr python:raw[0].getObject(); results python:first_pr.make_bag(raw)" tal:repeat="pr_year results/years"> I get this in the error_log (I have VerboseSecurity 0.4 installed): [snip lots of detail, this is at the tail end of the traceback...] Module Products.PageTemplates.Expressions, line 206, in __call__ Module Products.PageTemplates.Expressions, line 194, in _eval Module Products.PageTemplates.Expressions, line 150, in _eval __traceback_info__: results Module Products.PageTemplates.Expressions, line 346, in restrictedTraverse __traceback_info__: {'path': ['years'], 'TraversalRequestNameStack': []} Module Products.VerboseSecurity.VerboseSecurityPolicy, line 157, in validate Unauthorized: The container has no security assertions. Access to 'years' of (PressReleaseDisplayBag instance at 86746f8) denied. In the short-term, I wonder what magic incantation I need to use to workaround that error. Long-term, I wonder, Is there a better way for me to use Python in Zope that isn't just so plain hard and contorted? The reason I felt I needed to make the DisplayBag class and not just do all the stuff it's doing either in Python Scripts or TAL is that--well--it seems like it will be easier to test and maintain. I could have a profusion of scripts in the skins folder that effectively do the same thing. And I'd probably already be done, but I'd really like to figure this out. I have this itching suspicion that I haven't provided enough detail--or that I haven't summarized well enough. Thanks for any insights or suggestions you can offer. // mark -
A friend helped me answer this: I had an instance member variable named "years"--so even though I granted public access to the method named "years()", Zope was refusing access to the member variable. This became somewhat obvious when I did: security.setDefaultAccess('allow') Then it was just a matter of using _years to store the computed value so as not to overlap with the method name. Cheers, // mark
participants (2)
-
Mark McEahern -
Mark McEahern