[Zope-dev] Another fix for UserDB
Phillip J. Eby
pje@telecommunity.com
Tue, 22 Jun 1999 12:07:48 -0500
When you use UserDB cookie authentication to log in on a URL that is a GET
form with a query string, the page you were originally going to acts as
though the query string weren't there. That's because cgi.FieldStorage
only pays attention to the query string as a source of fields if the
request is a GET or HEAD, and the default login document for UserDB has a
POST method. Further, if you log in to a page that is a POST form, the
field data from the original POST will be gone. There is, however, a
simple solution to both problems. First, change the ACTION="" attribute of
the FORM tag to remove the
<!--#if QUERY_STRING-->?<!--#var QUERY_STRING--><!--#/if-->
block. It is superfluous, since Zope will subsequently ignore the query
string anyway.
Second, add the following block somewhere within the FORM block
(indentation added for clarity):
<!--#in "REQUEST.form.items()"-->
<!--#if "_['sequence-key'] not in ('__ac_name','__ac_password')"-->
<input type="hidden"
name="<!--#var sequence-key html_quote-->"
value="<!--#var sequence-item html_quote-->">
<!--#/if-->
<!--#/in-->
This will add in any form variables from the original request, whether they
came from the query string or a POST form. The loop checks and excludes
__ac_name and __ac_password from the hidden fields, in case the page is
being redisplayed due to a bad login.
Note that this is only a partial fix, however. For example, it doesn't
check for multi-valued fields such as tokens, lines, lists, etc. And
non-string fields (e.g. integers) will turn into strings. :( So short of
writing an ExternalMethod to marshal arbitrary objects into hidden fields,
this is as good as it gets. If at some point I write code that can do the
marshalling, I'll post it here. Meanwhile, this is good enough for the
relatively small number of entry points in my existing apps.