You are not logged in Log in Join
You are here: Home » Members » Caseman » Using the File Precondition Property

Log in



Using the File Precondition Property


The precondition property of Zope file objects is a somewhat enigmatic beast that deserves better explanation. I know many mailing list entries exist on this subject, but it is not well documented elsewhere AFAIK. Therefore, I have taken this bull by the horns to show you a use I found for it that might shed some light on its functionality.

What is it?

The precondition property is just the name of a Zope object, generally a DTML method, somewhere in the aquisition path of the file object. When a request is made from a browser to retreive the file object from Zope, the precondition object is called before the file data is returned. This allows you to do some processing or checking before the file data goes to the client.

An important point to remember is that the precondition object is called (like with dtml-call) rather than rendered (like with dtml-var). This means that the precondition method will not itself return any content to the browser. So how, you ask, do you get it to do something useful? We'll get to that next.

What it can do

There are two main actions that a precondition can do to affect the result of requesting the file object. It can raise an exception which will essentially deny access to the file object or it can redirect the browser to another URL. The latter is useful when the object is referenced from another page like in the case of an image placed using the <IMG> tag.

Generally, you would want the precondition to check something to determine if it should take any action. The action could be as simple as verifying parameters passed through RESULT or a cookie or a complex as querying a database using a Z SQL method to determine the appropriate action. If the precondition takes no action either by raising an exception or redirecting the browser, then the file object data is returned as normal.

Real world example

I was working on a Zope application on my organization's intranet that allows users to make expense requests. The user fills out a form which is then checked by a supervisor. If the request is accepted then a copy of the request with the supervisor's signature is made available to the original requestor. The signed request is an HTML page generated using data from a database. The signature is an image stored in the ZODB.

The problem I faced was that I did not want anyone to be able to simply enter the URL for the signature image and have it come up. Although we are dealing with a known audience of "trusted" users, it would be all too easy to forge signed documents if this was allowed. Of course one alternative is to simply make the user enter a password to view the image and by consequence the signed document. I did not feel that this was a "user friendly" approach and our users have a hard enough time remembering their own network account passwords...

Precondition? Huh?

So, essentially what I needed was a transparent way to make sure that the signature was only inserted where it needed to be an no where else. Since the data was being pulled from a database, the authorization could come from there. Only the supervisor would have the ability to set the appropriate database flag, which was an authorization date field which defaults to null.

All that was left was figuring out how to process the authorization date in the image object itself. Processing it in the signed request document does not solve the problem of accessing the image directly. Since the URL of the image is emblazened prominently in the HTML source of any signed request, security by obscurity would not work at all (not that it ever does 8^).

It became apparent that image objects did not have this capability. I soon discovered that file objects could also contain images (only without the automatic <IMG> tag rendering), and I wondered what the precondition property did (it sounded promising). Sure enough, after digging around the mailing list archives, I found out how to use it to solve this problem.

Making it work

Ok, so we have a signature image and a DTML document that we want to insert it in. But we want to make sure it can only appear in this document and not any others. We also want to make sure you cannot view the image outside of the document by pointing a browser directly to the image URL.

Step 1: Put the image into a zope file object. Lets call it signature.

Step 2: Fill in the precondition property with the name of the method we will use to verify the authorization flag. For this example we will call it verify_sig.

Step 3: Create the verify_sig method in the same folder as the image file (or one above it). Put the following DTML code into it:

   <dtml-unless authorized>
      <dtml-raise type="Forbidden">
         You are not authorized to view this object