diff --git a/cms/djangoapps/contentstore/views/public.py b/cms/djangoapps/contentstore/views/public.py index f48cb31486..71f5ee5512 100644 --- a/cms/djangoapps/contentstore/views/public.py +++ b/cms/djangoapps/contentstore/views/public.py @@ -46,7 +46,7 @@ def redirect_to_lms_login_for_admin(request): """ This view redirect the admin/login url to the site's login page. """ - return redirect('/login/?next=/admin') + return redirect('/login?next=/admin') def _build_next_param(request): diff --git a/cms/urls.py b/cms/urls.py index f5f2374cee..9828e9d0fb 100644 --- a/cms/urls.py +++ b/cms/urls.py @@ -49,7 +49,7 @@ LIBRARY_KEY_PATTERN = r'(?Plibrary-v1:[^/+]+\+[^/+]+)' # oauth2_urlpatterns needs to be first to override any other login and # logout related views. urlpatterns = oauth2_urlpatterns + [ - path('', include('openedx.core.djangoapps.user_authn.urls')), + path('', include('openedx.core.djangoapps.user_authn.urls_common')), path('', include('common.djangoapps.student.urls')), path('transcripts/upload', contentstore_views.upload_transcripts, name='upload_transcripts'), path('transcripts/download', contentstore_views.download_transcripts, name='download_transcripts'), diff --git a/openedx/core/djangoapps/user_authn/urls.py b/openedx/core/djangoapps/user_authn/urls.py index 98b09fec00..6b7807de0f 100644 --- a/openedx/core/djangoapps/user_authn/urls.py +++ b/openedx/core/djangoapps/user_authn/urls.py @@ -1,103 +1,17 @@ """ URLs for User Authentication """ -from django.conf import settings -from django.urls import include, path, re_path -from django.contrib.auth.views import PasswordResetCompleteView - -from .views import auth, auto_auth, login, login_form, logout, password_reset, register -from .views.password_reset import PasswordResetConfirmWrapper +from django.urls import include, path +from .views import auth, login, login_form urlpatterns = [ - # Registration - path('create_account', register.RegistrationView.as_view(), name='create_account'), - - path('api/user/v1/account/registration/', register.RegistrationView.as_view(), - name="user_api_registration" - ), - # `user_api` prefix is preserved for backwards compatibility. - path('user_api/v1/account/registration/', register.RegistrationView.as_view(), - name="user_api_registration_legacy"), - - # V2 is created to avoid backward compatibility issue with confirm_email - path('api/user/v2/account/registration/', register.RegistrationView.as_view(), - name="user_api_registration_v2" - ), - # legacy url - path('user_api/v2/account/registration/', register.RegistrationView.as_view(), - name="user_api_registration_v2_legacy"), - - # `api/user` prefix is preserved for backwards compatibility. - path('api/user/v1/validation/registration', register.RegistrationValidationView.as_view(), - name='registration_validation' - ), - - path('login_ajax', login.login_user, name="login_api"), - - re_path( - r'^api/user/(?Pv(1|2))/account/login_session/$', - login.LoginSessionView.as_view(), - name="user_api_login_session" - ), - # `user_api` prefix is preserved for backwards compatibility. - re_path(r'^user_api/(?Pv(1|2))/account/login_session/$', login.LoginSessionView.as_view(), - name="user_api_login_session_legacy"), - - # Login Refresh of JWT Cookies - path('login_refresh', login.login_refresh, name="login_refresh"), - - # WARNING: This is similar to auth_backends ^logout/$ (which has a - # trailing slash); LMS uses this view, but Studio links to the - # auth_backends logout view. - path('logout', logout.LogoutView.as_view(), name='logout'), - - path('api/user/v1/account/password_reset/', password_reset.PasswordResetView.as_view(), - name="user_api_password_reset" - ), - # legacy url - path('user_api/v1/account/password_reset/', password_reset.PasswordResetView.as_view(), - name="user_api_password_reset_legacy"), - - # Password reset api views. - path('password_reset/', password_reset.password_reset, name='password_reset'), - re_path( - r'^password_reset_confirm/(?P[0-9A-Za-z]+)-(?P.+)/$', - PasswordResetConfirmWrapper.as_view(), - name='password_reset_confirm', - ), - path('account/password', password_reset.password_change_request_handler, name='password_change_request'), - - # authn MFE flow - path('api/user/v1/account/password_reset/token/validate/', password_reset.PasswordResetTokenValidation.as_view(), - name="user_api_password_reset_token_validate" - ), - # legacy url - path('user_api/v1/account/password_reset/token/validate/', password_reset.PasswordResetTokenValidation.as_view(), - name="user_api_password_reset_token_validate_legacy"), - - # authn MFE reset flow - re_path( - r'^password/reset/(?P[0-9A-Za-z]+)-(?P.+)/$', - password_reset.LogistrationPasswordResetView.as_view(), - name='logistration_password_reset', - ), + # TODO move contents of urls_common here once CMS no longer has its own login + path('', include('openedx.core.djangoapps.user_authn.urls_common')), path('api/', include('openedx.core.djangoapps.user_authn.api.urls')), path('account/finish_auth', login.finish_auth, name='finish_auth'), path('auth/jwks.json', auth.get_public_signing_jwks, name='get_public_signing_jwks'), ] -# password reset django views (see above for password reset views) -urlpatterns += [ - path('password_reset_complete/', PasswordResetCompleteView.as_view(), - name='password_reset_complete', - ), -] - -# enable automatic login -if settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING'): - urlpatterns += [ - path('auto_auth', auto_auth.auto_auth), - ] # Backwards compatibility with old URL structure, but serve the new views urlpatterns += [ diff --git a/openedx/core/djangoapps/user_authn/urls_common.py b/openedx/core/djangoapps/user_authn/urls_common.py new file mode 100644 index 0000000000..bb735f7b29 --- /dev/null +++ b/openedx/core/djangoapps/user_authn/urls_common.py @@ -0,0 +1,111 @@ +""" +Common URLs for User Authentication + +Note: The split between urls.py and urls_common.py is hopefully temporary. +For now, this is needed because of difference in CMS and LMS that have +not yet been cleaned up. + +This is also home to urls for endpoints that have been consolidated from other djangoapps, +which leads to inconsistent prefixing. + +""" + + +from django.conf import settings +from django.contrib.auth.views import PasswordResetCompleteView +from django.urls import path, re_path + +from .views import auto_auth, login, logout, password_reset, register +from .views.password_reset import PasswordResetConfirmWrapper + +urlpatterns = [ + # Registration + path('create_account', register.RegistrationView.as_view(), name='create_account'), + + # Moved from user_api/legacy_urls.py + path('api/user/v1/account/registration/', register.RegistrationView.as_view(), + name="user_api_registration" + ), + # `user_api` prefix is preserved for backwards compatibility. + path('user_api/v1/account/registration/', register.RegistrationView.as_view(), + name="user_api_registration_legacy"), + + # V2 is created to avoid backward compatibility issue with confirm_email + path('api/user/v2/account/registration/', register.RegistrationView.as_view(), + name="user_api_registration_v2" + ), + # legacy url + path('user_api/v2/account/registration/', register.RegistrationView.as_view(), + name="user_api_registration_v2_legacy"), + + # Moved from user_api/urls.py + # `api/user` prefix is preserved for backwards compatibility. + path('api/user/v1/validation/registration', register.RegistrationValidationView.as_view(), + name='registration_validation' + ), + + path('login_ajax', login.login_user, name="login_api"), + + # Moved from user_api/legacy_urls.py + re_path( + r'^api/user/(?Pv(1|2))/account/login_session/$', + login.LoginSessionView.as_view(), + name="user_api_login_session" + ), + # `user_api` prefix is preserved for backwards compatibility. + re_path(r'^user_api/(?Pv(1|2))/account/login_session/$', login.LoginSessionView.as_view(), + name="user_api_login_session_legacy"), + + # Login Refresh of JWT Cookies + path('login_refresh', login.login_refresh, name="login_refresh"), + + # WARNING: This is similar to auth_backends ^logout/$ (which has a + # trailing slash); LMS uses this view, but Studio links to the + # auth_backends logout view. + path('logout', logout.LogoutView.as_view(), name='logout'), + + # Moved from user_api/legacy_urls.py + path('api/user/v1/account/password_reset/', password_reset.PasswordResetView.as_view(), + name="user_api_password_reset" + ), + # legacy url + path('user_api/v1/account/password_reset/', password_reset.PasswordResetView.as_view(), + name="user_api_password_reset_legacy"), + + # Password reset api views. + path('password_reset/', password_reset.password_reset, name='password_reset'), + re_path( + r'^password_reset_confirm/(?P[0-9A-Za-z]+)-(?P.+)/$', + PasswordResetConfirmWrapper.as_view(), + name='password_reset_confirm', + ), + path('account/password', password_reset.password_change_request_handler, name='password_change_request'), + + # authn MFE flow + path('api/user/v1/account/password_reset/token/validate/', password_reset.PasswordResetTokenValidation.as_view(), + name="user_api_password_reset_token_validate" + ), + # legacy url + path('user_api/v1/account/password_reset/token/validate/', password_reset.PasswordResetTokenValidation.as_view(), + name="user_api_password_reset_token_validate_legacy"), + + # authn MFE reset flow + re_path( + r'^password/reset/(?P[0-9A-Za-z]+)-(?P.+)/$', + password_reset.LogistrationPasswordResetView.as_view(), + name='logistration_password_reset', + ), +] + +# password reset django views (see above for password reset views) +urlpatterns += [ + path('password_reset_complete/', PasswordResetCompleteView.as_view(), + name='password_reset_complete', + ), +] + +# enable automatic login +if settings.FEATURES.get('AUTOMATIC_AUTH_FOR_TESTING'): + urlpatterns += [ + path('auto_auth', auto_auth.auto_auth), + ] diff --git a/openedx/core/djangoapps/user_authn/views/tests/test_auto_auth.py b/openedx/core/djangoapps/user_authn/views/tests/test_auto_auth.py index 3a0100f5ea..0346aee25a 100644 --- a/openedx/core/djangoapps/user_authn/views/tests/test_auto_auth.py +++ b/openedx/core/djangoapps/user_authn/views/tests/test_auto_auth.py @@ -27,7 +27,7 @@ class AutoAuthTestCase(UrlResetMixin, TestCase): """ Base class for AutoAuth Tests that properly resets the urls.py """ - URLCONF_MODULES = ['openedx.core.djangoapps.user_authn.urls'] + URLCONF_MODULES = ['openedx.core.djangoapps.user_authn.urls_common', 'openedx.core.djangoapps.user_authn.urls'] @ddt.ddt