From 4b5e9b37253ee890586dcfdb69db51846f95a77e Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 29 Mar 2017 19:29:08 +0200 Subject: [PATCH] tomerge --- tests/test_fc_auth.py | 90 +++++++++++++++++++++++++++++++++------ wcs/qommon/ident/franceconnect.py | 13 ++---- 2 files changed, 80 insertions(+), 23 deletions(-) diff --git a/tests/test_fc_auth.py b/tests/test_fc_auth.py index 5664b1d..c34edb7 100644 --- a/tests/test_fc_auth.py +++ b/tests/test_fc_auth.py @@ -66,6 +66,7 @@ def setup_user_profile(pub): # setup an hobo profile CmdCheckHobos().update_profile(PROFILE, pub) pub.cfg['users']['field_name'] = ['_prenoms', '_nom'] + pub.cfg['debug'] = {'logger': True} pub.user_class.wipe() pub.write_cfg() @@ -106,7 +107,12 @@ def setup_fc_environment(pub): pub.write_cfg() -def test_fc_login_page(): +def get_session(app): + session_id = app.cookies.values()[0].strip('"') + return get_session_manager().session_class.get(session_id) + + +def test_fc_login_page(caplog): setup_user_profile(pub) setup_fc_environment(pub) app = get_app(pub) @@ -149,17 +155,28 @@ def test_fc_login_page(): assert user.name == 'John Doe' # Verify we are logged in - session_id = app.cookies.values()[0].strip('"') - session = get_session_manager().session_class.get(session_id) + session = get_session(app) assert session.user == user.id assert session.extra_variables['fc_user_given_name'] == 'John' assert session.extra_variables['fc_user_family_name'] == 'Doe' assert session.extra_variables['fc_user_email'] == 'john.doe@example.com' assert session.extra_variables['fc_user_sub'] == 'ymca' - assert session.display_message() == '' - # Login existing user resp = app.get('/logout') + + # Test error handling path + resp = app.get('/ident/fc/callback?%s' % urllib.urlencode({ + 'state': state, + 'error': 'access_denied', + })) + assert 'user did not authorize login' in caplog.records[-1].message + resp = app.get('/ident/fc/callback?%s' % urllib.urlencode({ + 'state': state, + 'error': 'whatever', + })) + assert 'whatever' in caplog.records[-1].message + + # Login existing user resp = app.get('/login/') assert resp.status_int == 302 assert resp.location.startswith('https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize') @@ -175,14 +192,10 @@ def test_fc_login_page(): resp = app.get('/ident/fc/callback?%s' % urllib.urlencode({ 'code': '1234', 'state': state, })) - new_session_id = app.cookies.values()[0].strip('"') - assert session_id != new_session_id, 'no new session created' - session = get_session_manager().session_class.get(new_session_id) + new_session = get_session(app) + assert session.id != new_session.id, 'no new session created' assert pub.user_class.count() == 1, 'existing user has not been used' - session_id = app.cookies.values()[0].strip('"') - session = get_session_manager().session_class.get(session_id) - assert session.user == user.id - assert session.display_message() == '' + assert new_session.user == user.id # User with missing attributes resp = app.get('/logout') @@ -207,8 +220,7 @@ def test_fc_login_page(): 'code': '1234', 'state': state, })) assert pub.user_class.count() == 1, 'an invalid user (no email) has been created' - session_id = app.cookies.values()[0].strip('"') - session = get_session_manager().session_class.get(session_id) + session = get_session(app) assert session.user is None assert 'FranceConnect authentication failed: missing name or email' in str(session.display_message()) @@ -242,3 +254,53 @@ def test_fc_settings(): resp = resp.forms[0].submit('submit').follow() assert pub.cfg['fc'] == FC_CONFIG + + +def test_fc_settings_no_user_profile(): + FC_CONFIG = { + 'client_id': '123', + 'client_secret': 'xyz', + 'platform': 'dev-particulier', + 'scopes': 'identite_pivot', + 'user_field_mappings': [ + { + 'field_varname': '__name', + 'value': '[given_name ""] [family_name ""]', + 'verified': 'always', + }, + { + 'field_varname': '__email', + 'value': '[email ""]', + 'verified': 'always', + }, + ] + + } + + pub.cfg = {} + pub.user_class.wipe() + pub.write_cfg() + app = get_app(pub) + resp = app.get('/backoffice/settings/identification/') + resp.forms[0]['methods$elementfc'].checked = True + resp = resp.forms[0].submit().follow() + + assert 'FranceConnect' in resp.body + resp = resp.click('FranceConnect') + resp = resp.forms[0].submit('user_field_mappings$add_element') + resp = resp.forms[0].submit('user_field_mappings$add_element') + resp.forms[0]['client_id'].value = '123' + resp.forms[0]['client_secret'].value = 'xyz' + resp.forms[0]['platform'].value = 'Development citizens' + resp.forms[0]['scopes'].value = 'identite_pivot' + + resp.forms[0]['user_field_mappings$element0$field_varname'] = '__name' + resp.forms[0]['user_field_mappings$element0$value'] = '[given_name ""] [family_name ""]' + resp.forms[0]['user_field_mappings$element0$verified'] = 'Always' + + resp.forms[0]['user_field_mappings$element2$field_varname'] = '__email' + resp.forms[0]['user_field_mappings$element2$value'] = '[email ""]' + resp.forms[0]['user_field_mappings$element2$verified'] = 'Always' + + resp = resp.forms[0].submit('submit').follow() + assert pub.cfg['fc'] == FC_CONFIG diff --git a/wcs/qommon/ident/franceconnect.py b/wcs/qommon/ident/franceconnect.py index b0ddbd0..23e3461 100644 --- a/wcs/qommon/ident/franceconnect.py +++ b/wcs/qommon/ident/franceconnect.py @@ -398,7 +398,7 @@ class FCAuthMethod(AuthMethod): user.set_attributes_from_formdata(user.form_data) AUTHORIZATION_REQUEST_ERRORS = { - 'access_denied': N_('You refused the connection'), + 'access_denied': N_('user did not authorize login'), } def callback(self): @@ -416,12 +416,8 @@ class FCAuthMethod(AuthMethod): # if no error parameter, we stay silent if error: # we log only errors whose user is not responsible - msg = _(self.AUTHORIZATION_REQUEST_ERRORS.get(error)) - if not msg: - msg = _('FranceConnect authentication failed') - logger.error('FranceConnect authentication failed with an unknown error: %s', - error) - session.message = ('error', msg) + msg = self.AUTHORIZATION_REQUEST_ERRORS.get(error) + logger.error(_('FranceConnect authentication failed : %s'), _(msg) if msg else error) return redirect(next_url) access_token = self.get_access_token(request.form['code']) if not access_token: @@ -451,10 +447,9 @@ class FCAuthMethod(AuthMethod): if not (user.name and user.email): # we didn't get useful attributes, forget it. logger.error('failed to get name and/or email attribute from FranceConnect') - session.message = ('error', - _('FranceConnect authentication failed: missing name or email')) return redirect(next_url) user.store() session.set_user(user.id) + session.id = None return redirect(next_url) -- 2.1.4