Projet

Général

Profil

0001-pass-id_token-on-logout-from-FranceConnect-fixes-289.patch

Benjamin Dauvergne, 14 décembre 2018 01:45

Télécharger (4,46 ko)

Voir les différences:

Subject: [PATCH] pass id_token on logout from FranceConnect (fixes #28997)

 tests/test_fc_auth.py             |  8 +++++---
 wcs/qommon/ident/franceconnect.py | 12 +++++++++---
 wcs/root.py                       |  5 ++---
 3 files changed, 16 insertions(+), 9 deletions(-)
tests/test_fc_auth.py
168 168
    assert session.extra_user_variables['fc_sub'] == 'ymca'
169 169

  
170 170
    resp = app.get('/logout')
171
    assert resp.location.endswith('/ident/fc/logout')
172
    resp = resp.follow()
173
    assert resp.location == 'https://fcp.integ01.dev-franceconnect.fr/api/v1/logout?post_logout_redirect_uri=http%3A%2F%2Fexample.net'
171
    splitted = urlparse.urlsplit(resp.location)
172
    assert urlparse.urlunsplit((splitted.scheme, splitted.netloc, splitted.path, '', '')) \
173
        == 'https://fcp.integ01.dev-franceconnect.fr/api/v1/logout'
174
    assert urlparse.parse_qs(splitted.query)['post_logout_redirect_uri'] == ['http://example.net']
175
    assert urlparse.parse_qs(splitted.query)['id_token_hint']
174 176
    assert not get_session(app)
175 177

  
176 178
    # Test error handling path
wcs/qommon/ident/franceconnect.py
327 327
            return None
328 328
        # check id_token nonce
329 329
        id_token = result['id_token']
330
        access_token = result['access_token']
330 331
        header, payload, signature = id_token.split('.')
331 332
        payload = json_loads(base64url_decode(payload))
332 333
        nonce = hashlib.sha256(str(session.id)).hexdigest()
333 334
        if payload['nonce'] != nonce:
334 335
            logger.error('FranceConnect returned nonce did not match')
335 336
            return None
336
        return result['access_token']
337
        return access_token, id_token
337 338

  
338 339
    def get_user_info(self, access_token):
339 340
        logger = get_logger()
......
436 437
                logger.error(_('FranceConnect authentication failed: %s'),
437 438
                             _(msg) if msg else error)
438 439
            return redirect(next_url)
439
        access_token = self.get_access_token(request.form['code'])
440
        access_token, id_token = self.get_access_token(request.form['code'])
440 441
        if not access_token:
441 442
            return redirect(next_url)
442 443
        user_info = self.get_user_info(access_token)
......
448 449
        session_var_fc_user = {}
449 450
        for key in flattened_user_info:
450 451
            session_var_fc_user['fc_' + key] = flattened_user_info[key]
451

  
452
        session_var_fc_user['fc_access_token'] = access_token
453
        session_var_fc_user['fc_id_token'] = id_token
452 454
        #  Lookup or create user
453 455
        sub = user_info['sub']
454 456
        user = None
......
471 473
        return redirect(next_url)
472 474

  
473 475
    def logout(self):
476
        session = get_session()
477
        id_token = session.extra_user_variables['fc_id_token']
478
        get_session_manager().expire_session()
474 479
        logout_url = self.get_logout_url()
475 480
        post_logout_redirect_uri = get_publisher().get_frontoffice_url()
476 481
        logout_url += '?' + urllib.urlencode({
482
            'id_token_hint': id_token,
477 483
            'post_logout_redirect_uri': post_logout_redirect_uri,
478 484
        })
479 485
        return redirect(logout_url)
wcs/root.py
265 265
            return redirect(get_publisher().get_root_url())
266 266
        ident_methods = get_cfg('identification', {}).get('methods', [])
267 267

  
268
        if 'fc' in ident_methods and session.extra_user_variables and 'fc_sub' in session.extra_user_variables:
269
            get_session_manager().expire_session()
270
            return redirect(get_publisher().get_root_url() + 'ident/fc/logout')
268
        if 'fc' in ident_methods and session.extra_user_variables and 'fc_id_token' in session.extra_user_variables:
269
            return get_publisher().ident_methods['fc']().logout()
271 270

  
272 271
        if not 'idp' in ident_methods:
273 272
            get_session_manager().expire_session()
274
-