using getProperty and catching Unauthorized
Using Zope 2.6.0, I have a script that returns a list of items to be shown in a navigation menu. I want to show only items where both a menu_order property exists and the user has permission to view the object (which will not always be controlled by 'View'). I can't use foo.getProperty('menu_order', None) because it will raise Unauthorized for objects the user has no permissions on. I can't use getattr(foo, 'menu_order', None) because foo will acquire menu_order, and I can't pass foo.aq_base or Acquisition.aq_base(foo) to getattr because aq_base will raise Unauthorized. If I could catch Unauthorized without also catching more serious errors, I could use getProperty, but I don't know how to do that.
I think the following should do what you want: for foo in bar.objectvalues() try: mo = foo.getProperty('menu_order', None) except 'Unauthorized': continue ..do stuff.. hth, -Casey On Thu, 24 Oct 2002 21:09:07 -0500 "John K. Hohm" <jhohm@acm.org> wrote:
Using Zope 2.6.0, I have a script that returns a list of items to be shown in a navigation menu. I want to show only items where both a menu_order property exists and the user has permission to view the object (which will not always be controlled by 'View'). I can't use foo.getProperty('menu_order', None) because it will raise Unauthorized for objects the user has no permissions on. I can't use getattr(foo, 'menu_order', None) because foo will acquire menu_order, and I can't pass foo.aq_base or Acquisition.aq_base(foo) to getattr because aq_base will raise Unauthorized. If I could catch Unauthorized without also catching more serious errors, I could use getProperty, but I don't know how to do that.
This kind of thing only works if the 'Unauthorized' string is always interned, which I'm not sure is guaranteed... I know I've had things like that *not* work in python scripts. Florent In article <20021025100215.65bc8b3e.casey@zope.com> you write:
I think the following should do what you want:
for foo in bar.objectvalues() try: mo = foo.getProperty('menu_order', None) except 'Unauthorized': continue ..do stuff..
So long as the string doesn't contain a space, then it is always interned by Python:
a = 'Not Found' b = 'Not Found' a is b 0 a = 'Unauthorized' b = 'Unauthorized' a is b 1
So it works if the string exception doesn't contain a space, otherwise you're hosed ;^) -Casey On Fri, 25 Oct 2002 20:46:32 +0200 Florent Guillaume <fg@nuxeo.com> wrote:
This kind of thing only works if the 'Unauthorized' string is always interned, which I'm not sure is guaranteed...
I know I've had things like that *not* work in python scripts.
Florent
In article <20021025100215.65bc8b3e.casey@zope.com> you write:
I think the following should do what you want:
for foo in bar.objectvalues() try: mo = foo.getProperty('menu_order', None) except 'Unauthorized': continue ..do stuff..
Aaaaaaaaah so that's why! Thanks for the explanation, I didn't know of this subtlety. Do you know if Guido will always keep it that way BTW? Florent On Fri, 2002-10-25 at 21:25, Casey Duncan wrote:
So long as the string doesn't contain a space, then it is always interned by Python:
a = 'Not Found' b = 'Not Found' a is b 0 a = 'Unauthorized' b = 'Unauthorized' a is b 1
So it works if the string exception doesn't contain a space, otherwise you're hosed ;^)
-Casey
On Fri, 25 Oct 2002 20:46:32 +0200 Florent Guillaume <fg@nuxeo.com> wrote:
This kind of thing only works if the 'Unauthorized' string is always interned, which I'm not sure is guaranteed...
I know I've had things like that *not* work in python scripts.
Florent
In article <20021025100215.65bc8b3e.casey@zope.com> you write:
I think the following should do what you want:
for foo in bar.objectvalues() try: mo = foo.getProperty('menu_order', None) except 'Unauthorized': continue ..do stuff..
-- Florent Guillaume, Nuxeo (Paris, France) +33 1 40 33 79 87 http://nuxeo.com mailto:fg@nuxeo.com
Florent> Aaaaaaaaah so that's why! Thanks for the explanation, I didn't Florent> know of this subtlety. Do you know if Guido will always keep it Florent> that way BTW? Most likely. The "no space" constraint means that identifiers in your programs get interned, but the interpreter doesn't waste resources interning long stuff like doc strings which wouldn't improve performance. In general you should only use "is" when you know you're dealing with a singleton like None. -- Skip Montanaro - skip@pobox.com http://www.mojam.com/ http://www.musi-cal.com/
Casey Duncan writes:
I think the following should do what you want:
for foo in bar.objectvalues() try: mo = foo.getProperty('menu_order', None) except 'Unauthorized': continue ..do stuff.. It may not work, because Python uses "is" to check against string exceptions and not "==".
Dieter
Yes, but as of right now, Python strings that do not contain spaces are interned as the same object. So as long as the name does not have a space in it, it should work. That said, string exceptions suck rocks. But string exceptions with spaces suck gravel ;^) -Casey On Fri, 25 Oct 2002 21:37:53 +0200 Dieter Maurer <dieter@handshake.de> wrote:
Casey Duncan writes:
I think the following should do what you want:
for foo in bar.objectvalues() try: mo = foo.getProperty('menu_order', None) except 'Unauthorized': continue ..do stuff.. It may not work, because Python uses "is" to check against string exceptions and not "==".
Dieter
Quoting Casey Duncan <casey@zope.com>:
Yes, but as of right now, Python strings that do not contain spaces are interned as the same object. So as long as the name does not have a space in it, it should work.
Thanks all, for the responses. Perhaps it should work, but it doesn't. I get the Unauthorized exception in my browser even though I'm doing this: try: menu_order = sibling.getProperty('menu_order', None) except 'Unauthorized': continue I somehow got the impression from reading the Python manual that raising an exception with a string that is the name of a class will raise the class instead, so I tried doing this: from AccessControl import Unauthorized #... try: menu_order = sibling.getProperty('menu_order', None) except Unauthorized: continue But then I get this incredibly ironic error in the browser: Error Type: ImportError Error Value: import of "Unauthorized" from "AccessControl" is unauthorized. You are not allowed to access Unauthorized in this context So apparently I'm allowed to call things that throw Unauthorized, but I'm not allowed to import Unauthorized in order to catch it? Harsh. Is there some other way of going about this? Perhaps some function that simulates the access control check that happens inside the acquisition wrapper, and returns a booleanish result?
That said, string exceptions suck rocks. But string exceptions with spaces suck gravel ;^)
-Casey
On Fri, 25 Oct 2002 21:37:53 +0200 Dieter Maurer <dieter@handshake.de> wrote:
Casey Duncan writes:
I think the following should do what you want:
for foo in bar.objectvalues() try: mo = foo.getProperty('menu_order', None) except 'Unauthorized': continue ..do stuff.. It may not work, because Python uses "is" to check against string exceptions and not "==".
Dieter
After a closer look, it would seem that nearly all of the 'Unauthorized' string exceptions have been replaced with a bonified exception object. So that is probably why it doesn't work. You could try importing this class in the python script using:: from zExeptions import Unauthorized and catch exceptions of this class. I have a feeling this import is not possible fom a python script however (though it probably should be). So that leaves you little choice but to either use a bare except, or write the code in an external method or other trusted code module. -Casey ----- Original Message ----- From: "John K. Hohm" <jhohm@acm.org> To: "Casey Duncan" <casey@zope.com> Cc: "Dieter Maurer" <dieter@handshake.de>; <zope@zope.org> Sent: Saturday, October 26, 2002 12:40 PM Subject: Re: [Zope] using getProperty and catching Unauthorized
Quoting Casey Duncan <casey@zope.com>:
Yes, but as of right now, Python strings that do not contain spaces are interned as the same object. So as long as the name does not have a space in it, it should work.
Thanks all, for the responses. Perhaps it should work, but it doesn't. I get the Unauthorized exception in my browser even though I'm doing this:
try: menu_order = sibling.getProperty('menu_order', None) except 'Unauthorized': continue
I somehow got the impression from reading the Python manual that raising an exception with a string that is the name of a class will raise the class instead, so I tried doing this:
from AccessControl import Unauthorized #... try: menu_order = sibling.getProperty('menu_order', None) except Unauthorized: continue
But then I get this incredibly ironic error in the browser: Error Type: ImportError Error Value: import of "Unauthorized" from "AccessControl" is unauthorized. You are not allowed to access Unauthorized in this context
So apparently I'm allowed to call things that throw Unauthorized, but I'm not allowed to import Unauthorized in order to catch it? Harsh. Is there some other way of going about this? Perhaps some function that simulates the access control check that happens inside the acquisition wrapper, and returns a booleanish result?
That said, string exceptions suck rocks. But string exceptions with spaces suck gravel ;^)
-Casey
On Fri, 25 Oct 2002 21:37:53 +0200 Dieter Maurer <dieter@handshake.de> wrote:
Casey Duncan writes:
I think the following should do what you want:
for foo in bar.objectvalues() try: mo = foo.getProperty('menu_order', None) except 'Unauthorized': continue ..do stuff.. It may not work, because Python uses "is" to check against string exceptions and not "==".
Dieter
Quoting Casey Duncan <casey@zope.com>:
After a closer look, it would seem that nearly all of the 'Unauthorized' string exceptions have been replaced with a bonified exception object. So that is probably why it doesn't work.
You could try importing this class in the python script using::
from zExeptions import Unauthorized
and catch exceptions of this class. I have a feeling this import is not possible fom a python script however (though it probably should be). So that leaves you little choice but to either use a bare except, or write the code in an external method or other trusted code module.
Thanks for the hint. I ended up with something pretty simple; I already had an AllowExports product, so I added this to the bottom of its __init__.py: # This is needed to circumvent stupidness and paranoia ModuleSecurityInfo('AccessControl').declarePublic('Unauthorized') In my menu item listing script, I now have this: from AccessControl import Unauthorized # ... try: menu_order = sibling.getProperty('menu_order', None) is_folderish = sibling.isPrincipiaFolderish except Unauthorized: continue
participants (5)
-
Casey Duncan -
Dieter Maurer -
Florent Guillaume -
John K. Hohm -
Skip Montanaro