Zope guru help needed (or become guru if you help me)
Hi there, Yesterday I released ZFormulator 0.1. I've run into a problem with Zope security settings with it now. I would appreciate it a lot if anyone knowledgable and daring enough would take a look at the file Form.py in ZFormulator. The symptoms are as following: I've been developing ZFormulator logged in as the Zope superuser. Apparently this Zope superuser has powers above the manager role, as ZFormulator works for the superuser, but not for the manager. I don't know exactly why, but I do know I am doing a lot of hacking in Form.py that might be causing it. Here I'll describe some of the hackery. It is probably completely incomprehensible if you haven't at least tried to read Form.py in ZFormulator first (or are reading it while you read this post). Also check out __init__.py to see how Form.py is used from the other side. In order to be able to easily register new field classes with Zope, without having to do a lot of boring code duplication (which would mean also maintenance hassles), I've tried to shield the Python programmer as much as possible from Zope itself. Form.py contains, besides the code implementing ZFormulatorForm, also code to register fields with it. The normal way to register a product in Zope is to tell Zope about a manage_add method, and a manage_addForm. In ZFormulator I only have a single manage_add method (which receives from the manage_add Form which field to add), and I dynamically add manage_addForm methods for each registered field (in the form manage_add<field meta_type>Form). These Forms cannot be HTMLFile objects, because they should be rendered differently for each field that is added. Because I could not figure out a way to pass extra information to the HTMLFile object when it's called, I decided not to use them, and wrote a custom class instead to produce the right form. Unfortunately, a mechanism in OFS/CopySupport.py needed when doing a copy & paste or a rename of an object in the Zope management interface, didn't like my custom class. It was looking for some mysterious (to me) attribute __roles__, and didn't find it. So while I was doing hacks anyway, I manually added in a __roles__ attribute to the FormHack class. After that renaming and copy and pasting *appeared* to work, though I've had some odd results after a rename recently, so I'm not entirely sure. This is one possible cause of the bug. A less hackish solution to all this would be appreciated, in any case. There's another possibility, however. Because the manage_add<meta_type>Form methods are added dynamically to the Form class, I can't include these Forms in the __ac_permissions__ of that class. So, I reasoned perhaps the superuser isn't bothered by this lack of permission information, but normal managers are, and thus can't access the form because they have no permission to do so. It seems like this is not the case however; I added yet more hackery stuff to the registration code, this time modifying the __ac_permissions__ attribute. If my hack went right the Forms *should* be part of __ac_permissions__ now and the manager ought to have no problems. But the problem persisted, so I don't think this is the solution. In general, I'd like to know if there's some better way to accomplish what I want without resorting to such hacking. To make my framework work well currently I *do* need it; I don't want to have to write an identical add<meta_type>Form.dtml file for each field that I add, I don't want to have to edit the __ac_permission__ attribute of the Form class for each field I add, I don't want to have to add manage_addForm methods to the Form class manually. Right now the framework works pretty nicely, shielding you from all that. Unfortunately it doesn't work properly yet... So, Zope gurus, *please* *please* take a look at Form.py. Please save me from all these kludges! Regards, Martijn
Hi Martijn - A few non guruish comments. On Sat, 4 Dec 1999, Martijn Faassen wrote:
differently for each field that is added. Because I could not figure out a way to pass extra information to the HTMLFile object when it's called, I decided not to use them, and wrote a custom class instead to produce the right form.
You mean you could not pass extra info in terms of keword arguments or that was not an option?
__roles__, and didn't find it. So while I was doing hacks anyway, I manually added in a __roles__ attribute to the FormHack class. After that renaming and copy and pasting *appeared* to work, though I've had some odd results after a rename recently, so I'm not entirely sure. This is one possible cause of the bug. A less hackish solution to all this would be appreciated, in any case.
The __roles__ (or <method>___roles__) attribute is the fundamental attribute that holds the roles info for each method, class etc. (unless things changed radically in later versions. If you are not using ZPublisher directly you shouldn't need to mess with it. Then again you are trying to do pretty unusual stuff so you might need an unusual solution ;-) I haven't offered much help, but if I get some time tonight I will read Form.py. Good Luck - Pavlos
Pavlos Christoforou wrote:
A few non guruish comments.
Those are very welcome as well, of course. Maybe a few non-gurus can manage to figure it out as well. :)
On Sat, 4 Dec 1999, Martijn Faassen wrote:
differently for each field that is added. Because I could not figure out a way to pass extra information to the HTMLFile object when it's called, I decided not to use them, and wrote a custom class instead to produce the right form.
You mean you could not pass extra info in terms of keword arguments or that was not an option?
I don't know how. I can pass on keyword arguments when constructing a HTMLFile() object, if I construct 3 HTMLFile objects from the same file (fieldAdd.dtml), all three take on the keyword arguments of the last such construction, i.e.: a = HTMLFile('fieldAdd', globals(), fieldname="Foo") b = HTMLFile('fieldAdd', globals(), fieldname="Bar") c = HTMLFile('fieldAdd', globals(), fieldname="Baz") now, methods a, b and c all use fieldname 'Baz', for some reason. I don't know if this is a Zope bug or not.. I can't pass on keyword arguments later on when the methods are used, as they're called from Zope itself. So if that's possible I don't know how. [snip __roles__]
The __roles__ (or <method>___roles__) attribute is the fundamental attribute that holds the roles info for each method, class etc. (unless things changed radically in later versions. If you are not using ZPublisher directly you shouldn't need to mess with it.
I am manually adding 'FormHack' as a method to the Form class. FormHack is just a simple Python class. I assume HTMLFile derives from the right Zope classes so that it knows about __roles__, but FormHack doesn't.
Then again you are trying to do pretty unusual stuff so you might need an unusual solution ;-)
Right, this is all an attempt to reduce code duplication and to shield the Python programmer from lots of Zope's machinery, while creating new field subclasses. In this regard it's successful.
I haven't offered much help, but if I get some time tonight I will read Form.py.
Thanks, let's hope sufficient eyeballs indeed make all bugs shallow. :) Regards, Martijn
participants (2)
-
Martijn Faassen -
Pavlos Christoforou