From 2e7a556340ca5471ed50b7ea27b8df68fb6f7caa Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Wed, 12 Jan 2022 17:48:51 +0100 Subject: [PATCH] urls: move public view into their own prefix (#12932) --- src/authentic2/urls.py | 36 ++++++++++++++++++++++++++++------- tests/auth_fc/test_auth_fc.py | 2 +- tests/test_api.py | 2 +- tests/test_attribute_kinds.py | 12 ++++++------ tests/test_auth_oidc.py | 6 ++---- tests/test_csv_import.py | 2 +- tests/test_password_reset.py | 22 ++++++++++----------- tests/test_registration.py | 16 ++++++++-------- tests/test_utils.py | 4 ++-- tests/test_views.py | 8 ++++++++ 10 files changed, 69 insertions(+), 41 deletions(-) diff --git a/src/authentic2/urls.py b/src/authentic2/urls.py index a997f6a7..ca8d4d74 100644 --- a/src/authentic2/urls.py +++ b/src/authentic2/urls.py @@ -44,13 +44,6 @@ accounts_urlpatterns = [ views.registration_completion, name='registration_activate', ), - url(r'^register/$', views.RegistrationView.as_view(), name='registration_register'), - url(r'^register/complete/$', views.registration_complete, name='registration_complete'), - url( - r'^register/closed/$', - TemplateView.as_view(template_name='registration/registration_closed.html'), - name='registration_disallowed', - ), url(r'^delete/$', login_required(views.AccountDeleteView.as_view()), name='delete_account'), url( r'validate-deletion/(?P[\w: -]+)/$', @@ -81,6 +74,34 @@ accounts_urlpatterns = [ dj_auth_views.PasswordChangeDoneView.as_view(), name='password_change_done', ), + # permament redirections for views moved to /self/ + url(r'^register/$', RedirectView.as_view(permanent=True, pattern_name='registration_register')), + url(r'^register/complete/$', RedirectView.as_view(permanent=True, pattern_name='registration_complete')), + url(r'^register/closed/$', RedirectView.as_view(permanent=True, pattern_name='registration_disallowed')), + url( + r'^password/reset/confirm/(?P[A-Za-z0-9_ -]+)/$', + RedirectView.as_view(permanent=True, pattern_name='password_reset_confirm'), + ), + url(r'^password/reset/$', RedirectView.as_view(permanent=True, pattern_name='password_reset')), + url( + r'^password/reset/instructions/$', + RedirectView.as_view(permanent=True, pattern_name='password_reset_instructions'), + ), + url( + r'^password/reset/.*', + RedirectView.as_view(permanent=True, pattern_name='invalid-password-reset-urls'), + ), +] + +self_urlpatterns = [ + # Registration + url(r'^register/$', views.RegistrationView.as_view(), name='registration_register'), + url(r'^register/complete/$', views.registration_complete, name='registration_complete'), + url( + r'^register/closed/$', + TemplateView.as_view(template_name='registration/registration_closed.html'), + name='registration_disallowed', + ), # Password reset url( r'^password/reset/confirm/(?P[A-Za-z0-9_ -]+)/$', @@ -111,6 +132,7 @@ urlpatterns = [ url(r'^logout/$', views.logout, name='auth_logout'), url(r'^su/(?P[A-Za-z0-9_-]+)/$', views.su, name='su'), url(r'^accounts/', include(accounts_urlpatterns)), + url(r'^self/', include(self_urlpatterns)), url(r'^admin/', admin.site.urls), url(r'^idp/', include('authentic2.idp.urls')), url(r'^manage/', include('authentic2.manager.urls')), diff --git a/tests/auth_fc/test_auth_fc.py b/tests/auth_fc/test_auth_fc.py index a8a58d52..dd154294 100644 --- a/tests/auth_fc/test_auth_fc.py +++ b/tests/auth_fc/test_auth_fc.py @@ -546,7 +546,7 @@ def test_authorization_error(app, franceconnect): def test_registration_page(settings, app, franceconnect, hooks): assert User.objects.count() == 0 - assert app.get('/accounts/register/?service=portail&next=/idp/') + assert app.get('/self/register/?service=portail&next=/idp/') franceconnect.login_with_fc_fixed_params(app) # a new user has been created diff --git a/tests/test_api.py b/tests/test_api.py index 4d487ab7..2f7763c1 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1290,7 +1290,7 @@ def test_password_reset(app, ou1, admin, user_ou1, mailoutbox): assert len(mailoutbox) == 1 mail = mailoutbox[0] assert mail.to[0] == email - assert 'http://testserver/accounts/password/reset/confirm/' in mail.body + assert 'http://testserver/self/password/reset/confirm/' in mail.body assert_event('manager.user.password.reset.request', user=admin, api=True) diff --git a/tests/test_attribute_kinds.py b/tests/test_attribute_kinds.py index b46eb3a3..b9a7a0ec 100644 --- a/tests/test_attribute_kinds.py +++ b/tests/test_attribute_kinds.py @@ -34,7 +34,7 @@ def test_string(db, app, admin, mailoutbox): ) qs = User.objects.filter(first_name='John') - response = app.get('/accounts/register/') + response = app.get('/self/register/') form = response.form form.set('email', 'john.doe@example.com') response = form.submit().follow() @@ -80,7 +80,7 @@ def test_string(db, app, admin, mailoutbox): def test_fr_postcode(db, app, admin, mailoutbox): def register_john(): - response = app.get('/accounts/register/') + response = app.get('/self/register/') form = response.form form.set('email', 'john.doe@example.com') response = form.submit().follow() @@ -191,7 +191,7 @@ def test_phone_number(db, app, admin, mailoutbox, settings): settings.A2_EMAILS_ADDRESS_RATELIMIT = None def register_john(): - response = app.get('/accounts/register/') + response = app.get('/self/register/') form = response.form form.set('email', 'john.doe@example.com') response = form.submit().follow() @@ -271,7 +271,7 @@ def test_french_phone_number(db, app, admin, mailoutbox, settings): settings.A2_EMAILS_ADDRESS_RATELIMIT = None def register_john(): - response = app.get('/accounts/register/') + response = app.get('/self/register/') form = response.form form.set('email', 'john.doe@example.com') response = form.submit().follow() @@ -402,7 +402,7 @@ def test_french_phone_number(db, app, admin, mailoutbox, settings): def test_birthdate(db, app, admin, mailoutbox, freezer): def register_john(): - response = app.get('/accounts/register/') + response = app.get('/self/register/') form = response.form form.set('email', 'john.doe@example.com') response = form.submit().follow() @@ -508,7 +508,7 @@ def test_profile_image(db, app, admin, mailoutbox): def john(): return User.objects.get(first_name='John') - response = app.get('/accounts/register/') + response = app.get('/self/register/') form = response.form form.set('email', 'john.doe@example.com') response = form.submit().follow() diff --git a/tests/test_auth_oidc.py b/tests/test_auth_oidc.py index 6930ddb9..12822280 100644 --- a/tests/test_auth_oidc.py +++ b/tests/test_auth_oidc.py @@ -485,10 +485,8 @@ def test_sso(app, caplog, code, oidc_provider, oidc_provider_jwkset, hooks): with utils.check_log(caplog, "'error': 'invalid request'"): with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code): - response = app.get( - login_callback_url(oidc_provider), params={'code': 'yyyy', 'state': state} - ).maybe_follow() - assert 'Requête invalide' in response + response = app.get(login_callback_url(oidc_provider), params={'code': 'yyyy', 'state': state}) + assert 'Authentication on Server failed with error' in app.cookies['messages'] with utils.check_log(caplog, 'invalid id_token'): with oidc_provider_mock(oidc_provider, oidc_provider_jwkset, code, extra_id_token={'iss': None}): response = app.get(login_callback_url(oidc_provider), params={'code': code, 'state': state}) diff --git a/tests/test_csv_import.py b/tests/test_csv_import.py index a7ba3d77..a34a025c 100644 --- a/tests/test_csv_import.py +++ b/tests/test_csv_import.py @@ -559,7 +559,7 @@ tnoel@entrouvert.com,Thomas,Noël,''' assert importer.run() thomas = User.objects.get(email='tnoel@entrouvert.com') assert len(mail.outbox) == 1 - assert 'http://testserver/accounts/password/reset/confirm/' in mail.outbox[0].body + assert 'http://testserver/self/password/reset/confirm/' in mail.outbox[0].body password = thomas.password del mail.outbox[0] diff --git a/tests/test_password_reset.py b/tests/test_password_reset.py index bdfb329c..802e9b42 100644 --- a/tests/test_password_reset.py +++ b/tests/test_password_reset.py @@ -69,10 +69,10 @@ def test_reset_by_email(app, simple_user, mailoutbox, settings): def test_can_reset_by_username(app, db, simple_user, settings, mailoutbox): - resp = app.get('/accounts/password/reset/') + resp = app.get('/self/password/reset/') assert 'email_or_username' not in resp.form.fields settings.A2_USER_CAN_RESET_PASSWORD_BY_USERNAME = True - resp = app.get('/accounts/password/reset/') + resp = app.get('/self/password/reset/') assert 'email_or_username' in resp.form.fields resp.form.set('email_or_username', simple_user.username) @@ -94,7 +94,7 @@ def test_can_reset_by_username(app, db, simple_user, settings, mailoutbox): def test_can_reset_by_username_with_email(app, db, simple_user, settings, mailoutbox): settings.A2_USER_CAN_RESET_PASSWORD_BY_USERNAME = True - resp = app.get('/accounts/password/reset/') + resp = app.get('/self/password/reset/') resp.form.set('email_or_username', simple_user.email) resp = resp.form.submit().follow() assert 'An email has been sent to %s' % simple_user.username in resp @@ -102,7 +102,7 @@ def test_can_reset_by_username_with_email(app, db, simple_user, settings, mailou def test_reset_by_email_no_account(app, db, mailoutbox): - resp = app.get('/accounts/password/reset/') + resp = app.get('/self/password/reset/') resp.form.set('email', 'john.doe@example.com') resp = resp.form.submit().follow() @@ -114,7 +114,7 @@ def test_reset_by_email_no_account(app, db, mailoutbox): def test_can_reset_by_username_no_account(app, db, settings, mailoutbox): settings.A2_USER_CAN_RESET_PASSWORD_BY_USERNAME = True - resp = app.get('/accounts/password/reset/') + resp = app.get('/self/password/reset/') resp.form.set('email_or_username', 'john.doe') resp = resp.form.submit().follow() assert 'An email has been sent to john.doe' in resp @@ -124,7 +124,7 @@ def test_can_reset_by_username_no_account(app, db, settings, mailoutbox): def test_can_reset_by_username_no_account_email(app, db, settings, mailoutbox): settings.A2_USER_CAN_RESET_PASSWORD_BY_USERNAME = True - resp = app.get('/accounts/password/reset/') + resp = app.get('/self/password/reset/') resp.form.set('email_or_username', 'john.doe@example.com') resp = resp.form.submit().follow() assert 'An email has been sent to john.doe' in resp @@ -143,8 +143,8 @@ def test_user_exclude(app, simple_user, mailoutbox, settings): def test_old_url_redirect(app): - response = app.get('/accounts/password/reset/whatever') - assert response.location == '/accounts/password/reset/' + response = app.get('/self/password/reset/whatever') + assert response.location == '/self/password/reset/' response = response.follow() assert 'please reset your password again' in response @@ -165,9 +165,9 @@ def test_send_password_reset_email_no_account(app, db, mailoutbox, settings, reg for body in (mail.body, mail.alternatives[0][0]): assert 'no account was found associated with this address' in body if settings.REGISTRATION_OPEN: - assert 'http://testserver/accounts/register/' in body + assert 'http://testserver/self/register/' in body else: - assert 'http://testserver/accounts/register/' not in body + assert 'http://testserver/self/register/' not in body def test_send_password_reset_email_disabled_account(app, simple_user, mailoutbox): @@ -185,7 +185,7 @@ def test_send_password_reset_email_disabled_account(app, simple_user, mailoutbox def test_email_validation(app, db): - resp = app.get('/accounts/password/reset/') + resp = app.get('/self/password/reset/') resp.form.set('email', 'coin@') resp = resp.form.submit() assert 'Enter a valid email address.' in resp diff --git a/tests/test_registration.py b/tests/test_registration.py index f3888fa0..76d7c72f 100644 --- a/tests/test_registration.py +++ b/tests/test_registration.py @@ -393,7 +393,7 @@ def test_attribute_model(app, db, settings, mailoutbox): def test_registration_email_blacklist(app, settings, db): def test_register(email): - response = app.get('/accounts/register/') + response = app.get('/self/register/') assert 'email' in response.form.fields response.form.set('email', email) response = response.form.submit() @@ -427,7 +427,7 @@ def test_registration_confirm_data(app, settings, db, rf): models.Attribute.objects.filter(name='first_name').update(required=False) activation_url = utils_misc.build_activation_url( - rf.post('/accounts/register/'), + rf.post('/self/register/'), email='john.doe@example.com', next_url='/', first_name='John', @@ -439,7 +439,7 @@ def test_registration_confirm_data(app, settings, db, rf): response = app.get(activation_url, status=302) activation_url = utils_misc.build_activation_url( - rf.post('/accounts/register/'), + rf.post('/self/register/'), email='john.doe@example.com', next_url='/', last_name='Doe', @@ -452,7 +452,7 @@ def test_registration_confirm_data(app, settings, db, rf): assert set(response.context['form'].fields.keys()) == {'first_name', 'last_name'} activation_url = utils_misc.build_activation_url( - rf.post('/accounts/register/'), + rf.post('/self/register/'), email='john.doe@example.com', next_url='/', last_name='Doe', @@ -630,7 +630,7 @@ def test_registration_activate_passwords_not_equal(app, db, settings, mailoutbox def test_authentication_method(app, db, rf, hooks): activation_url = utils_misc.build_activation_url( - rf.post('/accounts/register/'), + rf.post('/self/register/'), email='john.doe@example.com', next_url='/', first_name='John', @@ -647,7 +647,7 @@ def test_authentication_method(app, db, rf, hooks): assert hooks.calls['event'][-1]['kwargs']['how'] == 'email' activation_url = utils_misc.build_activation_url( - rf.post('/accounts/register/'), + rf.post('/self/register/'), email='jane.doe@example.com', next_url='/', first_name='Jane', @@ -691,7 +691,7 @@ def test_registration_no_email_full_profile_no_password(app, db, rf, mailoutbox) 'authentication_method': 'france-connect', } - activation_url = utils_misc.build_activation_url(rf.post('/accounts/register/'), next_url='/', **data) + activation_url = utils_misc.build_activation_url(rf.post('/self/register/'), next_url='/', **data) response = app.get(activation_url) response.form.set('first_name', data['first_name']) @@ -778,7 +778,7 @@ def test_registration_email_not_verified_required_and_unrequired_attributes(app, 'authentication_method': 'france-connect', } - activation_url = utils_misc.build_activation_url(rf.post('/accounts/register/'), next_url='/', **data) + activation_url = utils_misc.build_activation_url(rf.post('/self/register/'), next_url='/', **data) response = app.get(activation_url) response.form.set('first_name', data['first_name']) diff --git a/tests/test_utils.py b/tests/test_utils.py index 97abdefb..3b7124bc 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -77,9 +77,9 @@ def test_same_origin(): def test_select_next_url(db, rf, settings): - request = rf.get('/accounts/register/', data={'next': '/admin/'}) + request = rf.get('/self/register/', data={'next': '/admin/'}) assert select_next_url(request, '/') == '/admin/' - request = rf.get('/accounts/register/', data={'next': 'http://example.com/'}) + request = rf.get('/self/register/', data={'next': 'http://example.com/'}) assert select_next_url(request, '/') == '/' settings.A2_REDIRECT_WHITELIST = ['//example.com/'] assert select_next_url(request, '/') == 'http://example.com/' diff --git a/tests/test_views.py b/tests/test_views.py index 5c7f6fa4..90839491 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -270,3 +270,11 @@ def test_views_login_display_a_cancel_button(app, settings): settings.A2_LOGIN_DISPLAY_A_CANCEL_BUTTON = True response = app.get(reverse('auth_login'), params={'next': '/foo/', 'nonce': 'xxx'}) assert response.html.find('button', {'class': 'cancel-button'}) + + +def test_redirect_views(app): + assert app.get('/accounts/register/').location == '/self/register/' + assert ( + app.get('/accounts/password/reset/confirm/abcd1234/').location + == '/self/password/reset/confirm/abcd1234/' + ) -- 2.34.1