0001-forms-prevent-autosave-from-overwriting-session-s-da.patch
tests/form_pages/test_all.py | ||
---|---|---|
4376 | 4376 |
assert formdef.data_class().select()[0].data['3_display'] == 'barbar' |
4377 | 4377 | |
4378 | 4378 | |
4379 |
def test_form_autosave_never_overwrite(mocker, pub, settings): |
|
4380 |
create_user(pub) |
|
4381 | ||
4382 |
formdef = create_formdef() |
|
4383 |
formdef.data_class().wipe() |
|
4384 | ||
4385 |
formdef.fields = [ |
|
4386 |
fields.PageField(id='0', label='1st page', type='page'), |
|
4387 |
fields.StringField(id='1', label='string1'), |
|
4388 |
fields.PageField(id='2', label='2nd page', type='page'), |
|
4389 |
fields.StringField(id='3', label='string2'), |
|
4390 |
] |
|
4391 |
formdef.store() |
|
4392 | ||
4393 |
app = get_app(pub) |
|
4394 |
login(app, username='foo', password='foo') |
|
4395 | ||
4396 |
resp = app.get('/test/') |
|
4397 |
resp.form.set('f1', '1') |
|
4398 |
# go to the second page |
|
4399 |
resp = resp.form.submit('submit') |
|
4400 |
resp.form.set('f3', '1') |
|
4401 |
# autosave wrong data |
|
4402 |
autosave_data = dict(resp.form.submit_fields()) |
|
4403 |
autosave_data['f3'] = 'wtf!' |
|
4404 |
resp_autosave = app.post('/test/autosave', params=autosave_data) |
|
4405 |
assert resp_autosave.json == {'result': 'success'} |
|
4406 |
# check the draft is fucked |
|
4407 |
data = formdef.data_class().select()[0].data |
|
4408 |
assert data['3'] == 'wtf!' |
|
4409 |
# now finish submitting |
|
4410 |
resp = resp.form.submit('submit') # -> validation page |
|
4411 |
# autosave wrong data |
|
4412 |
# _ajax_form_token is just a form_token, so take the current one to |
|
4413 |
# simulate a rogue autosave from the second page |
|
4414 |
autosave_data['_ajax_form_token'] = resp.form['_form_id'].value |
|
4415 |
resp_autosave = app.post('/test/autosave', params=autosave_data) |
|
4416 |
assert resp_autosave.json == {'result': 'success'} |
|
4417 |
data = formdef.data_class().select()[0].data |
|
4418 |
assert data['3'] == 'wtf!' |
|
4419 |
# validate |
|
4420 |
resp = resp.form.submit('submit') # -> submit |
|
4421 | ||
4422 |
# great everything is still fine in the end |
|
4423 |
assert formdef.data_class().select()[0].data == {'1': '1', '3': '1'} |
|
4424 | ||
4425 | ||
4379 | 4426 |
def test_form_string_field_autocomplete(pub): |
4380 | 4427 |
formdef = create_formdef() |
4381 | 4428 |
formdef.fields = [fields.StringField(id='0', label='string', type='string', required=False)] |
wcs/forms/root.py | ||
---|---|---|
1299 | 1299 | |
1300 | 1300 |
def autosave(self): |
1301 | 1301 |
get_response().set_content_type('application/json') |
1302 |
get_request().ignore_session = True |
|
1302 | 1303 | |
1303 | 1304 |
def result_error(reason): |
1304 |
get_request().ignore_session = True |
|
1305 | 1305 |
return json.dumps({'result': 'error', 'reason': reason}) |
1306 | 1306 | |
1307 | 1307 |
ajax_form_token = get_request().form.get('_ajax_form_token') |
... | ... | |
1360 | 1360 | |
1361 | 1361 |
def save_draft(self, data, page_no=None): |
1362 | 1362 |
filled = self.get_current_draft() or self.formdef.data_class()() |
1363 |
new_draft = bool(filled.id is None) |
|
1363 | 1364 |
if filled.id and filled.status != 'draft': |
1364 | 1365 |
raise SubmittedDraftException() |
1365 | 1366 |
filled.data = data |
... | ... | |
1378 | 1379 |
filled.store() |
1379 | 1380 | |
1380 | 1381 |
if not filled.user_id: |
1381 |
get_session().mark_anonymous_formdata(filled) |
|
1382 |
if get_session().mark_anonymous_formdata(filled): |
|
1383 |
get_session().store() |
|
1382 | 1384 | |
1383 |
data['draft_formdata_id'] = filled.id |
|
1385 |
if new_draft: |
|
1386 |
data['draft_formdata_id'] = filled.id |
|
1387 |
get_session().store() |
|
1384 | 1388 |
self.set_tracking_code(filled, data) |
1385 | 1389 | |
1386 | 1390 |
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 |
- |