0001-forms-prevent-autosave-from-overwriting-session-s-da.patch
tests/form_pages/test_all.py | ||
---|---|---|
4567 | 4567 |
assert formdef.data_class().select()[0].data['3_display'] == 'barbar' |
4568 | 4568 | |
4569 | 4569 | |
4570 |
def test_form_autosave_never_overwrite(mocker, pub, settings): |
|
4571 |
create_user(pub) |
|
4572 | ||
4573 |
formdef = create_formdef() |
|
4574 |
formdef.data_class().wipe() |
|
4575 | ||
4576 |
formdef.fields = [ |
|
4577 |
fields.PageField(id='0', label='1st page', type='page'), |
|
4578 |
fields.StringField(id='1', label='string1'), |
|
4579 |
fields.PageField(id='2', label='2nd page', type='page'), |
|
4580 |
fields.StringField(id='3', label='string2'), |
|
4581 |
] |
|
4582 |
formdef.store() |
|
4583 | ||
4584 |
app = get_app(pub) |
|
4585 |
login(app, username='foo', password='foo') |
|
4586 | ||
4587 |
resp = app.get('/test/') |
|
4588 |
resp.form.set('f1', '1') |
|
4589 |
# go to the second page |
|
4590 |
resp = resp.form.submit('submit') |
|
4591 |
resp.form.set('f3', '1') |
|
4592 |
# autosave wrong data |
|
4593 |
autosave_data = dict(resp.form.submit_fields()) |
|
4594 |
autosave_data['f3'] = 'wtf!' |
|
4595 |
resp_autosave = app.post('/test/autosave', params=autosave_data) |
|
4596 |
assert resp_autosave.json == {'result': 'success'} |
|
4597 |
# check the draft is fucked |
|
4598 |
data = formdef.data_class().select()[0].data |
|
4599 |
assert data['3'] == 'wtf!' |
|
4600 |
# now finish submitting |
|
4601 |
resp = resp.form.submit('submit') # -> validation page |
|
4602 |
# autosave wrong data |
|
4603 |
# _ajax_form_token is just a form_token, so take the current one to |
|
4604 |
# simulate a rogue autosave from the second page |
|
4605 |
autosave_data['_ajax_form_token'] = resp.form['_form_id'].value |
|
4606 |
resp_autosave = app.post('/test/autosave', params=autosave_data) |
|
4607 |
assert resp_autosave.json == {'result': 'success'} |
|
4608 |
data = formdef.data_class().select()[0].data |
|
4609 |
assert data['3'] == 'wtf!' |
|
4610 |
# validate |
|
4611 |
resp = resp.form.submit('submit') # -> submit |
|
4612 | ||
4613 |
# great everything is still fine in the end |
|
4614 |
assert formdef.data_class().select()[0].data == {'1': '1', '3': '1'} |
|
4615 | ||
4616 | ||
4570 | 4617 |
def test_form_string_field_autocomplete(pub): |
4571 | 4618 |
formdef = create_formdef() |
4572 | 4619 |
formdef.fields = [fields.StringField(id='0', label='string', type='string', required=False)] |
wcs/forms/root.py | ||
---|---|---|
1354 | 1354 | |
1355 | 1355 |
def autosave(self): |
1356 | 1356 |
get_response().set_content_type('application/json') |
1357 |
get_request().ignore_session = True |
|
1357 | 1358 | |
1358 | 1359 |
def result_error(reason): |
1359 |
get_request().ignore_session = True |
|
1360 | 1360 |
return json.dumps({'result': 'error', 'reason': reason}) |
1361 | 1361 | |
1362 | 1362 |
ajax_form_token = get_request().form.get('_ajax_form_token') |
... | ... | |
1418 | 1418 | |
1419 | 1419 |
def save_draft(self, data, page_no=None): |
1420 | 1420 |
filled = self.get_current_draft() or self.formdef.data_class()() |
1421 |
new_draft = bool(filled.id is None) |
|
1421 | 1422 |
if filled.id and filled.status != 'draft': |
1422 | 1423 |
raise SubmittedDraftException() |
1423 | 1424 |
filled.data = data |
... | ... | |
1436 | 1437 |
filled.store() |
1437 | 1438 | |
1438 | 1439 |
if not filled.user_id: |
1439 |
get_session().mark_anonymous_formdata(filled) |
|
1440 |
if get_session().mark_anonymous_formdata(filled): |
|
1441 |
get_session().store() |
|
1440 | 1442 | |
1441 |
data['draft_formdata_id'] = filled.id |
|
1443 |
if new_draft: |
|
1444 |
data['draft_formdata_id'] = filled.id |
|
1445 |
get_session().store() |
|
1442 | 1446 |
self.set_tracking_code(filled, data) |
1443 | 1447 | |
1444 | 1448 |
get_logger().info('form %s - saving draft (id: %s)' % (self.formdef.name, filled.id)) |
wcs/sessions.py | ||
---|---|---|
59 | 59 |
def mark_anonymous_formdata(self, formdata): |
60 | 60 |
if not self.anonymous_formdata_keys: |
61 | 61 |
self.anonymous_formdata_keys = {} |
62 |
self.anonymous_formdata_keys[formdata.get_object_key()] = True |
|
62 |
key = formdata.get_object_key() |
|
63 |
if key not in self.anonymous_formdata_keys: |
|
64 |
self.anonymous_formdata_keys[key] = True |
|
65 |
return True |
|
66 |
return False |
|
63 | 67 | |
64 | 68 |
def is_anonymous_submitter(self, formdata): |
65 | 69 |
if not self.anonymous_formdata_keys: |
66 |
- |