on our sprint in Bad Sulza we looked at the handling of interface invariants in z3c.form. There we found a problem in the validation.
Look at the following example.

class IMeetingTime(zope.interface.Interface):
    start = zope.schema.Datetime(title=u'start time')
    end = zope.schema.Datetime(title=u'end time')

    def start_before_end(obj):
        if obj.start > obj.end:
raise zope.interface.Invalid('start time must be before end time')

If only the end field is displayed in a form and the end date is set to value smaller than start, the invariant does not prevent saving the form, so it is possible to save invalid data.

This happens because accessing obj.start leads to an exception z3c.form.validator.NoInputData which is swallowed in z3c.form.validator.InvariantsValidator.validateObject().

Possible solutions:

- The invariant expects to get an object for checking but it gets a z3c.form.validator.Data object which only contains the data the user entered. So this Data object could look up the missing value on the real object which is accessible on the __context__ attribute on the Data object.

- Change the order things are done:

  1. set a save-point (non-optimistic)

  2. write the values the user entered on the object

  3. validate invariants

  4. If an invariant raises an exception, roll back to the save-point.

This solution requests that the back-end supports non-optimistic save-points. But we can get rid of the Data class.

We'll start an implementation of the second approach on a branch of z3c.form now to show if it works.

Any thoughts?

Yours sincerely,
Michael Howitz

gocept gmbh & co. kg · forsterstrasse 29 · 06112 halle/saale
www.gocept.com · fon: +49 345 12298898 · fax: +49 345 12298891

Zope3-dev mailing list
Unsub: http://mail.zope.org/mailman/options/zope3-dev/archive%40mail-archive.com

Reply via email to