I now have a workaround, but I don't like it very much.  By checking
the length of request.vars before calling form.accepts(), I can force
the request formkey to match the session formkey, e.g.

    if len(request.vars):
        request.vars._formkey =  session['_formkey[page_create]']
    if form.accepts(request.vars,session):
        ... etc ...

The unwanted submit from the CKEditor image dialog is still occurring,
but forcing the keys to match when there's a real submit is avoiding
the failure in form.accepts().   I don't like it as a solution
because:
1. It relies on knowledge of web2py's internal form naming
conventions.
2. It only works if the unwanted submit has an empty request.vars
3. I suspect I may be defeating the purpose of the formkey and
possibly creating a security hole.

Is there a better way?

thanks,
Mike

On Jun 29, 6:10 pm, MikeEllis <michael.f.el...@gmail.com> wrote:
> This one still has me stumped so I'm taking the liberty of adding some
> more info to make it current in the discussions.  As I noted in the
> earlier post,  the problem has to to do with CKEditor's image
> insertion dialog somehow triggering a form submission.  This is really
> puzzling, because the link insertion dialog is nearly identical but
> doesn't trigger a submit.  Below is a modified version of the index
> function with some write statements to print the request vars and
> session formkeys.
>
> Any help much appreciated!
>
> def index():
>     form = SQLFORM(db.page, showid=False,keepvalues=True)
>     sys.stderr.write("\n\nsession formkey:
> %s"%session['_formkey[page_create]'])
>     sys.stderr.write("\nrequest.vars:%s"%repr(request.vars))
>     if form.accepts(request.vars,session):
>         response.flash = "Form accepted"
>         redirect(URL(r=request,f="show"))
>     elif form.errors:
>         response.flash = "Uh-oh!"
>     else:
>         response.flash = "Fill out the form"
>     sys.stderr.write("\n%s\n"%response.flash)
>     return dict(form=form)
>
> So when I visit the index page and use the CKEditor to insert a link,
> I see the following output in the console.
>
> (initial display)
> session formkey:bf5ec584-0ec9-4e74-90ff-ba53971ea2f5
> request.vars:<Storage {}>
> Fill out the form
>
> (after inserting link, clicking ok to insert dialog, then clicking
> submit)
> session formkey:f95327b1-6152-4fb3-abd2-00444c9cc298
> request.vars:<Storage {'body': '<p>\r\n\t<a href="http://web2py.com/
> book/static/tree.jpg">link</a></p>\r\n', '_formkey':
> 'f95327b1-6152-4fb3-abd2-00444c9cc298', '_formname': 'page_create'}>
>
> If I try the same thing except that this time I insert an image,  I
> get an extra submit and the session formkey gets out of sync with the
> request.vars formkey.
>
> (initial display)
> session formkey:76e5e1fe-365c-401d-aaac-f2a751c8873e
> request.vars:<Storage {}>
> Fill out the form
>
> (after inserting image and clicking ok in dialog)
> session formkey:a143b2f1-bc5c-41b0-90e6-ef01fdc8e913
> request.vars:<Storage {}>
> Fill out the form
>
> (after clicking Submit)
> session formkey:9ee58f15-c1cd-4fa1-8766-b69b9a4478ac
> request.vars:<Storage {'body': '<p>\r\n\t<img alt="" src="http://
> web2py.com/book/static/tree.jpg" style="width: 401px; height: 500px;
> " /></p>\r\n', '_formkey': 'a143b2f1-bc5c-41b0-90e6-ef01fdc8e913',
> '_formname': 'page_create'}>
> Fill out the form
>
> The formkeys don't match, so form.accepts fails and the data never
> gets into the table.
>
> Thanks,
> Mike
>
> On Jun 21, 2:01 pm, Michael Ellis <michael.f.el...@gmail.com> wrote:
>
>
>
> > Not sure if this is a web2py or ckeditor problem or just some
> > misunderstanding on my part.  Here's what's happening:
>
> > If I create a CKEditor instance in a SQLFORM, things work as expected until
> > I try to insert an image. Clicking the Ok button in ckeditor's image dialog
> > appears to be causing an immediate and unwanted form submission with a
> > formkey that doesn't match the real formkey. This doesn't raise a form
> > error. Instead it triggers the final else branch of the form.accepts logic
> > (see below) and the image along with any other text that was entered is
> > lost.
>
> > I recently ran into this in a larger app, but am able to reproduce it in the
> > following minimal model and controller. Has anyone else run into this and is
> > there a workaround other than switching the CKEditor to Source mode and
> > manually entering the <img> tag? I'm using web2py1.79.2 and CKEditor 3.3.1
> > (revision 5586) but have also seen the problem in CKEditor 3.2.
>
> > MODEL
> > db.define_table('page',
> >     Field('body', 'text'),
> >     )
>
> > def advanced_editor(field, value):
> >     eid = str(field).replace('.','_')
> >     return TEXTAREA(_id = eid, _name=field.name,
> >                     _class='text ckeditor', value=value,
> >                     _cols=80, _rows=10)
>
> > db.page.body.widget = advanced_editor
>
> > VIEW (default.py/index.html)
> > {{extend 'layout.html'}}
> > <script type="text/javascript"
> > src="{{=URL(request.application,'static','js/ckeditor/ckeditor.js')}}"></sc 
> > ript>
> > {{=BEAUTIFY(response._vars)}}
>
> > CONTROLLER
> > def index():
> >     form = SQLFORM(db.page, showid=False)
> >     if form.accepts(request.vars,session):
> >         response.flash = "Form accepted"
> >         redirect(URL(r=request,f="show"))
> >     elif form.errors:
> >         response.flash = "Uh-oh!"
> >     else:
> >         ## Trying to insert an image lands here.
> >         response.flash = "Fill out the form."
> >     return dict(form=form)
>
> > def show():
> >     shown = dict()
> >     for row in db(db.page.id>0).select():
> >         shown[row.id] = row.body
> >     return dict(shown=shown)
>
> > Thanks,
> > Mike

Reply via email to