Project

General

Profile

0001-misc-create-session-substitution-variables-from-quer.patch

Frédéric Péters, 18 August 2015 09:12 AM

Download (6.91 KB)

View differences:

Subject: [PATCH] misc: create session substitution variables from query string
 (#7858)

 tests/test_form_pages.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++++
 wcs/qommon/publisher.py  | 29 ++++++++++++++++++++++++
 wcs/qommon/sessions.py   | 14 ++++++++++++
 wcs/root.py              |  1 +
 4 files changed, 101 insertions(+)
tests/test_form_pages.py
1 1
import pytest
2 2
import hashlib
3
import os
3 4

  
4 5
from wcs.qommon.ident.password_accounts import PasswordAccount
5 6
from wcs.formdef import FormDef
......
884 885
            '0_structured': [
885 886
                {'id': '1', 'more': 'foo', 'text': 'un'},
886 887
                {'id': '3', 'more': 'baz', 'text': 'trois'}]}
888

  
889
def test_form_page_query_string_prefill(pub):
890
    user = create_user(pub)
891
    formdef = create_formdef()
892
    formdef.data_class().wipe()
893
    formdef.fields = [fields.StringField(id='0', label='string',
894
        prefill={'type': 'formula', 'value': 'session_var_foo'})]
895
    formdef.store()
896

  
897
    # check it's empty if it doesn't exist
898
    resp = get_app(pub).get('/test/')
899
    assert resp.forms[0]['f0'].value == ''
900

  
901
    # check it's not set if it's not whitelisted
902
    resp = get_app(pub).get('/?session_var_foo=hello')
903
    assert resp.location == 'http://example.net/'
904
    resp = resp.follow()
905
    resp = resp.click('test')
906
    assert resp.forms[0]['f0'].value == ''
907

  
908
    # check it works
909
    open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w').write('''[options]
910
query_string_allowed_vars = foo,bar
911
''')
912

  
913
    resp = get_app(pub).get('/?session_var_foo=hello')
914
    assert resp.location == 'http://example.net/'
915
    resp = resp.follow()
916
    resp = resp.click('test')
917
    assert resp.forms[0]['f0'].value == 'hello'
918

  
919
    # check it survives a login
920
    resp = get_app(pub).get('/?session_var_foo=hello2')
921
    assert resp.location == 'http://example.net/'
922
    resp = resp.follow()
923
    resp = resp.click('Login')
924
    resp = resp.follow()
925
    resp.forms[0]['username'] = 'foo'
926
    resp.forms[0]['password'] = 'foo'
927
    resp = resp.forms[0].submit()
928
    resp = resp.follow()
929
    resp = resp.click('test')
930
    assert resp.forms[0]['f0'].value == 'hello2'
931

  
932
    # check repeated options are ignored
933
    resp = get_app(pub).get('/?session_var_foo=hello&session_var_foo=hello2')
934
    assert resp.location == 'http://example.net/'
935
    resp = resp.follow()
936
    resp = resp.click('test')
937
    assert resp.forms[0]['f0'].value == ''
938

  
939
    # check extra query string parameters are not lost
940
    resp = get_app(pub).get('/?session_var_foo=hello&foo=bar')
941
    assert resp.location == 'http://example.net/?foo=bar'
942

  
943
    os.unlink(os.path.join(pub.app_dir, 'site-options.cfg'))
wcs/qommon/publisher.py
578 578
        if request.get_environ('QOMMON_PAGE_TEMPLATE_KEY'):
579 579
            request.response.page_template_key = request.get_environ('QOMMON_PAGE_TEMPLATE_KEY')
580 580

  
581
        # handle session_var_<xxx> in query strings, add them to session and
582
        # redirect to same URL without the parameters
583
        if request.get_method() == 'GET' and request.form:
584
            query_string_allowed_vars = self.get_site_option(
585
                    'query_string_allowed_vars') or ''
586
            query_string_allowed_vars = [x.strip() for x in
587
                    query_string_allowed_vars.split(',')]
588
            had_session_variables = False
589
            session_variables = {}
590
            for k, v in request.form.items():
591
                if k.startswith('session_var_'):
592
                    had_session_variables = True
593
                    session_variable = str(k[len('session_var_'):])
594
                    # only add variable to session if it's a string, this
595
                    # handles the case of repeated parameters producing a
596
                    # list of values (by ignoring those parameters altogether).
597
                    if session_variable in query_string_allowed_vars and (
598
                            isinstance(v, str)):
599
                        session_variables[session_variable] = v
600
                    del request.form[k]
601
            if had_session_variables:
602
                self.start_request() # creates session
603
                request.session.add_extra_variables(**session_variables)
604
                self.finish_successful_request() # commits session
605
                new_query_string = ''
606
                if request.form:
607
                    new_query_string = '?' + urllib.urlencode(request.form)
608
                return redirect(request.get_path() + new_query_string)
609

  
581 610
        request.language = self.get_site_language()
582 611
        self.install_lang(request.language)
583 612
        self.substitutions.feed(self)
wcs/qommon/sessions.py
80 80
    ident_idp_token = None
81 81
    tempfiles = None
82 82
    jsonp_display_values = None
83
    extra_variables = None
83 84

  
84 85
    username = None # only set on password authentication
85 86

  
......
92 93
            self.ident_idp_token or \
93 94
            self.tempfiles or \
94 95
            self.jsonp_display_values or \
96
            self.extra_variables or \
95 97
            CaptchaSession.has_info(self) or \
96 98
            QuixoteSession.has_info(self)
97 99
    is_dirty = has_info
......
205 207
        value.fp = open(filename)
206 208
        return value
207 209

  
210
    def add_extra_variables(self, **kwargs):
211
        if not self.extra_variables:
212
            self.extra_variables = {}
213
        self.extra_variables.update(kwargs)
214

  
215
    def get_substitution_variables(self, prefix='session_var_'):
216
        d = {}
217
        if self.extra_variables:
218
            for k, v in self.extra_variables.items():
219
                d[prefix + k] = v
220
        return d
221

  
208 222

  
209 223
class QommonSessionManager(QuixoteSessionManager):
210 224
    def start_request(self):
wcs/root.py
283 283
        if not hasattr(response, 'breadcrumb'):
284 284
            response.breadcrumb = [ ('', _('Home')) ]
285 285

  
286
        get_publisher().substitutions.feed(get_session())
286 287
        get_publisher().substitutions.feed(get_request().user)
287 288
        get_publisher().substitutions.feed(NamedDataSource)
288 289

  
289
-