Projet

Général

Profil

0001-misc-expose-session-identifier-in-substitution-varia.patch

Frédéric Péters, 27 juin 2018 12:47

Télécharger (6,03 ko)

Voir les différences:

Subject: [PATCH] misc: expose session identifier in substitution variables
 (#24778)

 tests/test_form_pages.py |  2 --
 tests/test_sessions.py   | 40 ++++++++++++++++++++++++++++++++++++++++
 wcs/forms/root.py        |  5 +++++
 wcs/qommon/sessions.py   | 16 +++++++++++++---
 4 files changed, 58 insertions(+), 5 deletions(-)
tests/test_form_pages.py
4239 4239
    formdef = create_formdef()
4240 4240
    app = get_app(pub)
4241 4241
    resp = app.get('/test/', status=200)
4242
    resp = resp.form.submit('submit')
4243 4242
    assert resp.headers['Set-Cookie'].startswith('wcs-')
4244 4243
    assert 'httponly' in resp.headers['Set-Cookie']
4245 4244
    assert not 'secure' in resp.headers['Set-Cookie']
4246 4245

  
4247 4246
    app = get_app(pub, https=True)
4248 4247
    resp = app.get('/test/', status=200)
4249
    resp = resp.form.submit('submit')
4250 4248
    assert resp.headers['Set-Cookie'].startswith('wcs-')
4251 4249
    assert 'httponly' in resp.headers['Set-Cookie']
4252 4250
    assert 'secure' in resp.headers['Set-Cookie']
tests/test_sessions.py
7 7

  
8 8
from wcs.qommon.ident.password_accounts import PasswordAccount
9 9
from wcs.qommon.http_request import HTTPRequest
10
from wcs.formdef import FormDef
11
from wcs import fields
10 12

  
11 13
from utilities import create_temporary_pub, clean_temporary_pub, get_app, login
12 14

  
......
159 161
    resp = login_form.submit()
160 162
    assert resp.status_int == 302
161 163
    assert pub.session_manager.session_class.count() == 2
164

  
165
def test_session_substitution_variables(pub, user, app):
166
    pub.session_manager.session_class.wipe()
167
    resp = app.get('/')
168

  
169
    formdef = FormDef()
170
    formdef.name = 'foobar'
171
    formdef.fields = [fields.CommentField(id='7', label='Hello [session_id]', type='comment')]
172
    formdef.store()
173

  
174
    resp = app.get('/foobar/')
175
    assert pub.session_manager.session_class.count() == 1
176
    session_id = pub.session_manager.session_class.select()[0].id
177
    assert 'Hello %s' % session_id in resp.body
178

  
179
    login(app, username='foo', password='foo')
180
    assert pub.session_manager.session_class.count() == 2
181
    session_id = [x for x in pub.session_manager.session_class.select() if x.id != session_id][0].id
182
    resp = app.get('/foobar/')
183
    assert 'Hello %s' % session_id in resp.body
184

  
185
def test_session_substitution_variables_1st_page_condition(pub, user, app):
186
    pub.session_manager.session_class.wipe()
187
    resp = app.get('/')
188

  
189
    formdef = FormDef()
190
    formdef.name = 'foobar'
191
    formdef.fields = [fields.PageField(id='0', label='1st PAGE', type='page',
192
            condition={'type': 'python', 'value': 'vars().get("session_id") is not None'}),
193
            fields.CommentField(id='7', label='COM1 [session_id]', type='comment'),
194
            fields.PageField(id='8', label='2nd PAGE', type='page'),
195
            fields.CommentField(id='9', label='COM2 [session_id]', type='comment')]
196
    formdef.store()
197

  
198
    resp = app.get('/foobar/')
199
    assert pub.session_manager.session_class.count() == 1
200
    session_id = pub.session_manager.session_class.select()[0].id
201
    assert 'COM1' in resp.body
wcs/forms/root.py
516 516
            return redirect(self.check_disabled())
517 517

  
518 518
        session = get_session()
519
        if not session.id:
520
            # force session to be written down, this is required so
521
            # [session_var_id] is available on the first page.
522
            session.force()
523

  
519 524
        if self.formdef.enable_tracking_codes:
520 525
            if get_request().form.get('_ajax_form_token'):
521 526
                # _ajax_form_token is immediately removed, this prevents
wcs/qommon/sessions.py
89 89
    jsonp_display_values = None
90 90
    extra_variables = None
91 91
    expire = None
92
    forced = False
92 93
    # should only be overwritten by authentication methods
93 94
    extra_user_variables = None
94 95

  
95 96
    username = None # only set on password authentication
96 97

  
98
    def force(self):
99
        # add some data in the session, it will force a cookie to be set, this
100
        # is used so we get a session identifier fixed even on the first page
101
        # of a form.
102
        self.forced = True
103
        get_session_manager().maintain_session(self)
104

  
97 105
    def set_expire(self, expire):
98 106
        self.expire = expire
99 107

  
......
126 134
            CaptchaSession.has_info(self) or \
127 135
            self.expire or \
128 136
            self.extra_user_variables or \
137
            self.forced or \
129 138
            QuixoteSession.has_info(self)
130 139
    is_dirty = has_info
131 140

  
......
313 322
            self.extra_variables = {}
314 323
        self.extra_variables.update(kwargs)
315 324

  
316
    def get_substitution_variables(self, prefix='session_var_'):
325
    def get_substitution_variables(self, prefix='session_'):
317 326
        d = {}
327
        d[prefix + 'id'] = self.id
318 328
        if self.extra_variables:
319 329
            for k, v in self.extra_variables.items():
320
                d[prefix + k] = v
330
                d[prefix + 'var_' + k] = v
321 331
        if self.extra_user_variables:
322 332
            for k, v in self.extra_user_variables.items():
323
                d[prefix + 'user_' + k] = v
333
                d[prefix + 'var_user_' + k] = v
324 334
        return d
325 335

  
326 336
    @classmethod
327
-