Projet

Général

Profil

0001-tomerge.patch

Benjamin Dauvergne, 29 mars 2017 19:29

Télécharger (7,51 ko)

Voir les différences:

Subject: [PATCH] tomerge

 tests/test_fc_auth.py             | 90 +++++++++++++++++++++++++++++++++------
 wcs/qommon/ident/franceconnect.py | 13 ++----
 2 files changed, 80 insertions(+), 23 deletions(-)
tests/test_fc_auth.py
66 66
    # setup an hobo profile
67 67
    CmdCheckHobos().update_profile(PROFILE, pub)
68 68
    pub.cfg['users']['field_name'] = ['_prenoms', '_nom']
69
    pub.cfg['debug'] = {'logger': True}
69 70
    pub.user_class.wipe()
70 71
    pub.write_cfg()
71 72

  
......
106 107
    pub.write_cfg()
107 108

  
108 109

  
109
def test_fc_login_page():
110
def get_session(app):
111
    session_id = app.cookies.values()[0].strip('"')
112
    return get_session_manager().session_class.get(session_id)
113

  
114

  
115
def test_fc_login_page(caplog):
110 116
    setup_user_profile(pub)
111 117
    setup_fc_environment(pub)
112 118
    app = get_app(pub)
......
149 155
    assert user.name == 'John Doe'
150 156

  
151 157
    # Verify we are logged in
152
    session_id = app.cookies.values()[0].strip('"')
153
    session = get_session_manager().session_class.get(session_id)
158
    session = get_session(app)
154 159
    assert session.user == user.id
155 160
    assert session.extra_variables['fc_user_given_name'] == 'John'
156 161
    assert session.extra_variables['fc_user_family_name'] == 'Doe'
157 162
    assert session.extra_variables['fc_user_email'] == 'john.doe@example.com'
158 163
    assert session.extra_variables['fc_user_sub'] == 'ymca'
159
    assert session.display_message() == ''
160 164

  
161
    # Login existing user
162 165
    resp = app.get('/logout')
166

  
167
    # Test error handling path
168
    resp = app.get('/ident/fc/callback?%s' % urllib.urlencode({
169
        'state': state,
170
        'error': 'access_denied',
171
    }))
172
    assert 'user did not authorize login' in caplog.records[-1].message
173
    resp = app.get('/ident/fc/callback?%s' % urllib.urlencode({
174
        'state': state,
175
        'error': 'whatever',
176
    }))
177
    assert 'whatever' in caplog.records[-1].message
178

  
179
    # Login existing user
163 180
    resp = app.get('/login/')
164 181
    assert resp.status_int == 302
165 182
    assert resp.location.startswith('https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize')
......
175 192
        resp = app.get('/ident/fc/callback?%s' % urllib.urlencode({
176 193
            'code': '1234', 'state': state,
177 194
        }))
178
    new_session_id = app.cookies.values()[0].strip('"')
179
    assert session_id != new_session_id, 'no new session created'
180
    session = get_session_manager().session_class.get(new_session_id)
195
    new_session = get_session(app)
196
    assert session.id != new_session.id, 'no new session created'
181 197
    assert pub.user_class.count() == 1, 'existing user has not been used'
182
    session_id = app.cookies.values()[0].strip('"')
183
    session = get_session_manager().session_class.get(session_id)
184
    assert session.user == user.id
185
    assert session.display_message() == ''
198
    assert new_session.user == user.id
186 199

  
187 200
    # User with missing attributes
188 201
    resp = app.get('/logout')
......
207 220
            'code': '1234', 'state': state,
208 221
        }))
209 222
    assert pub.user_class.count() == 1, 'an invalid user (no email) has been created'
210
    session_id = app.cookies.values()[0].strip('"')
211
    session = get_session_manager().session_class.get(session_id)
223
    session = get_session(app)
212 224
    assert session.user is None
213 225
    assert 'FranceConnect authentication failed: missing name or email' in str(session.display_message())
214 226

  
......
242 254

  
243 255
    resp = resp.forms[0].submit('submit').follow()
244 256
    assert pub.cfg['fc'] == FC_CONFIG
257

  
258

  
259
def test_fc_settings_no_user_profile():
260
    FC_CONFIG = {
261
        'client_id': '123',
262
        'client_secret': 'xyz',
263
        'platform': 'dev-particulier',
264
        'scopes': 'identite_pivot',
265
        'user_field_mappings': [
266
            {
267
                'field_varname': '__name',
268
                'value': '[given_name ""] [family_name ""]',
269
                'verified': 'always',
270
            },
271
            {
272
                'field_varname': '__email',
273
                'value': '[email ""]',
274
                'verified': 'always',
275
            },
276
        ]
277

  
278
    }
279

  
280
    pub.cfg = {}
281
    pub.user_class.wipe()
282
    pub.write_cfg()
283
    app = get_app(pub)
284
    resp = app.get('/backoffice/settings/identification/')
285
    resp.forms[0]['methods$elementfc'].checked = True
286
    resp = resp.forms[0].submit().follow()
287

  
288
    assert 'FranceConnect' in resp.body
289
    resp = resp.click('FranceConnect')
290
    resp = resp.forms[0].submit('user_field_mappings$add_element')
291
    resp = resp.forms[0].submit('user_field_mappings$add_element')
292
    resp.forms[0]['client_id'].value = '123'
293
    resp.forms[0]['client_secret'].value = 'xyz'
294
    resp.forms[0]['platform'].value = 'Development citizens'
295
    resp.forms[0]['scopes'].value = 'identite_pivot'
296

  
297
    resp.forms[0]['user_field_mappings$element0$field_varname'] = '__name'
298
    resp.forms[0]['user_field_mappings$element0$value'] = '[given_name ""] [family_name ""]'
299
    resp.forms[0]['user_field_mappings$element0$verified'] = 'Always'
300

  
301
    resp.forms[0]['user_field_mappings$element2$field_varname'] = '__email'
302
    resp.forms[0]['user_field_mappings$element2$value'] = '[email ""]'
303
    resp.forms[0]['user_field_mappings$element2$verified'] = 'Always'
304

  
305
    resp = resp.forms[0].submit('submit').follow()
306
    assert pub.cfg['fc'] == FC_CONFIG
wcs/qommon/ident/franceconnect.py
398 398
            user.set_attributes_from_formdata(user.form_data)
399 399

  
400 400
    AUTHORIZATION_REQUEST_ERRORS = {
401
        'access_denied': N_('You refused the connection'),
401
        'access_denied': N_('user did not authorize login'),
402 402
    }
403 403

  
404 404
    def callback(self):
......
416 416
            # if no error parameter, we stay silent
417 417
            if error:
418 418
                # we log only errors whose user is not responsible
419
                msg = _(self.AUTHORIZATION_REQUEST_ERRORS.get(error))
420
                if not msg:
421
                    msg = _('FranceConnect authentication failed')
422
                    logger.error('FranceConnect authentication failed with an unknown error: %s',
423
                                 error)
424
                session.message = ('error', msg)
419
                msg = self.AUTHORIZATION_REQUEST_ERRORS.get(error)
420
                logger.error(_('FranceConnect authentication failed : %s'), _(msg) if msg else error)
425 421
            return redirect(next_url)
426 422
        access_token = self.get_access_token(request.form['code'])
427 423
        if not access_token:
......
451 447
        if not (user.name and user.email):
452 448
            # we didn't get useful attributes, forget it.
453 449
            logger.error('failed to get name and/or email attribute from FranceConnect')
454
            session.message = ('error',
455
                               _('FranceConnect authentication failed: missing name or email'))
456 450
            return redirect(next_url)
457 451

  
458 452
        user.store()
459 453
        session.set_user(user.id)
454
        session.id = None
460 455
        return redirect(next_url)
461
-