diff --git a/mayan/apps/authentication/forms.py b/mayan/apps/authentication/forms.py index ebc7e5233d..dd1c247f7e 100644 --- a/mayan/apps/authentication/forms.py +++ b/mayan/apps/authentication/forms.py @@ -23,8 +23,10 @@ class EmailAuthenticationForm(forms.Form): remember_me = forms.BooleanField(label=_('Remember me'), required=False) error_messages = { - 'invalid_login': _('Please enter a correct email and password. ' - 'Note that the password field is case-sensitive.'), + 'invalid_login': _( + 'Please enter a correct email and password. Note that the ' + 'password field is case-sensitive.' + ), 'inactive': _('This account is inactive.'), } @@ -56,8 +58,10 @@ class EmailAuthenticationForm(forms.Form): return self.cleaned_data def check_for_test_cookie(self): - warnings.warn('check_for_test_cookie is deprecated; ensure your login ' - 'view is CSRF-protected.', DeprecationWarning) + warnings.warn( + 'check_for_test_cookie is deprecated; ensure your login view ' + 'is CSRF-protected.', DeprecationWarning + ) def get_user_id(self): if self.user_cache: diff --git a/mayan/apps/authentication/templates/authentication/password_reset_complete.html b/mayan/apps/authentication/templates/authentication/password_reset_complete.html index 48b778dcb7..5d43c3fd41 100644 --- a/mayan/apps/authentication/templates/authentication/password_reset_complete.html +++ b/mayan/apps/authentication/templates/authentication/password_reset_complete.html @@ -14,8 +14,7 @@
-
{% trans 'Login page' %}
+
{% trans 'Login page' %}
- {% endblock content_plain %} diff --git a/mayan/apps/authentication/urls.py b/mayan/apps/authentication/urls.py index 81e8352c23..a0cfcb375b 100644 --- a/mayan/apps/authentication/urls.py +++ b/mayan/apps/authentication/urls.py @@ -1,43 +1,44 @@ from __future__ import unicode_literals -from django.conf import settings from django.conf.urls import url -from django.contrib.auth.views import logout from .views import ( - login_view, password_change_done, password_change_view, - password_reset_complete_view, password_reset_confirm_view, - password_reset_done_view, password_reset_view + MayanLoginView, MayanLogoutView, MayanPasswordChangeDoneView, + MayanPasswordChangeView, MayanPasswordResetCompleteView, + MayanPasswordResetConfirmView, MayanPasswordResetDoneView, + MayanPasswordResetView ) + urlpatterns = [ - url(regex=r'^login/$', name='login_view', view=login_view), + url(regex=r'^login/$', name='login_view', view=MayanLoginView.as_view()), url( - regex=r'^logout/$', kwargs={'next_page': settings.LOGIN_REDIRECT_URL}, - name='logout_view', view=logout + regex=r'^logout/$', name='logout_view', view=MayanLogoutView.as_view() ), url( regex=r'^password/change/$', name='password_change_view', - view=password_change_view + view=MayanPasswordChangeView.as_view() ), url( regex=r'^password/change/done/$', name='password_change_done', - view=password_change_done + view=MayanPasswordChangeDoneView.as_view() ), url( regex=r'^password/reset/$', name='password_reset_view', - view=password_reset_view + view=MayanPasswordResetView.as_view() ), url( regex=r'^password/reset/confirm/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', - name='password_reset_confirm_view', view=password_reset_confirm_view + name='password_reset_confirm_view', + view=MayanPasswordResetConfirmView.as_view() ), url( regex=r'^password/reset/complete/$', - name='password_reset_complete_view', view=password_reset_complete_view + name='password_reset_complete_view', + view=MayanPasswordResetCompleteView.as_view() ), url( regex=r'^password/reset/done/$', name='password_reset_done_view', - view=password_reset_done_view + view=MayanPasswordResetDoneView.as_view() ), ] diff --git a/mayan/apps/authentication/views.py b/mayan/apps/authentication/views.py index 0d038d9042..d698417c9e 100644 --- a/mayan/apps/authentication/views.py +++ b/mayan/apps/authentication/views.py @@ -1,19 +1,17 @@ from __future__ import absolute_import, unicode_literals -from django.conf import settings from django.contrib import messages -from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth.views import ( - login, password_change, password_reset, password_reset_complete, - password_reset_confirm, password_reset_done + LoginView, LogoutView, PasswordChangeDoneView, PasswordChangeView, + PasswordResetCompleteView, PasswordResetConfirmView, PasswordResetDoneView, + PasswordResetView ) from django.http import HttpResponseRedirect -from django.shortcuts import redirect, resolve_url -from django.urls import reverse -from django.utils.http import is_safe_url +from django.shortcuts import redirect +from django.urls import reverse, reverse_lazy from django.utils.translation import ugettext_lazy as _ -from stronghold.decorators import public +from stronghold.views import StrongholdPublicMixin import mayan from mayan.apps.common.settings import ( @@ -24,143 +22,108 @@ from .forms import EmailAuthenticationForm, UsernameAuthenticationForm from .settings import setting_login_method, setting_maximum_session_length -@public -def login_view(request): - """ - Control how the use is to be authenticated, options are 'email' and - 'username' - """ - success_url_allowed_hosts = set() - kwargs = {'template_name': 'authentication/login.html'} +class MayanLoginView(StrongholdPublicMixin, LoginView): + extra_context = { + 'appearance_type': 'plain' + } + template_name = 'authentication/login.html' + redirect_authenticated_user = True - if setting_login_method.value == 'email': - kwargs['authentication_form'] = EmailAuthenticationForm - else: - kwargs['authentication_form'] = UsernameAuthenticationForm + def form_valid(self, form): + result = super(MayanLoginView, self).form_valid(form=form) + remember_me = form.cleaned_data.get('remember_me') - allowed_hosts = {request.get_host()} - allowed_hosts.update(success_url_allowed_hosts) + # remember_me values: + # True - long session + # False - short session + # None - Form has no remember_me value and we let the session + # expiration default. - redirect_to = request.POST.get( - REDIRECT_FIELD_NAME, request.GET.get(REDIRECT_FIELD_NAME, '') - ) - - url_is_safe = is_safe_url( - url=redirect_to, - allowed_hosts=allowed_hosts, - require_https=request.is_secure(), - ) - - url = redirect_to if url_is_safe else '' - - if not request.user.is_authenticated: - extra_context = { - 'appearance_type': 'plain', - REDIRECT_FIELD_NAME: url or resolve_url(settings.LOGIN_REDIRECT_URL) - } - - result = login(request, extra_context=extra_context, **kwargs) - if request.method == 'POST': - form = kwargs['authentication_form'](request, data=request.POST) - if form.is_valid(): - if form.cleaned_data['remember_me']: - request.session.set_expiry( - setting_maximum_session_length.value - ) - else: - request.session.set_expiry(0) - return result - else: - return HttpResponseRedirect(resolve_url(settings.LOGIN_REDIRECT_URL)) - - -def password_change_view(request): - """ - Password change wrapper for better control - """ - extra_context = {'title': _('Current user password change')} - - if request.user.user_options.block_password_change: - messages.error( - request, _( - 'Changing the password is not allowed for this account.' + if remember_me is True: + self.request.session.set_expiry( + setting_maximum_session_length.value ) + elif remember_me is False: + self.request.session.set_expiry(0) + + return result + + def get_form_class(self): + if setting_login_method.value == 'email': + return EmailAuthenticationForm + else: + return UsernameAuthenticationForm + + +class MayanLogoutView(LogoutView): + """No current change or overrides, left here for future expansion""" + + +class MayanPasswordChangeDoneView(PasswordChangeDoneView): + def dispatch(self, *args, **kwargs): + messages.success( + message=_('Your password has been successfully changed.'), + request=self.request ) - return HttpResponseRedirect(reverse(setting_home_view.view)) - - return password_change( - request, extra_context=extra_context, - template_name='appearance/generic_form.html', - post_change_redirect=reverse(viewname='authentication:password_change_done'), - ) + return redirect(to='common:current_user_details') -def password_change_done(request): - """ - View called when the new user password has been accepted - """ - messages.success( - request, _('Your password has been successfully changed.') - ) - return redirect('common:current_user_details') +class MayanPasswordChangeView(PasswordChangeView): + extra_context = {'title': _('Current user password change')} + success_url = reverse_lazy(viewname='authentication:password_change_done') + template_name = 'appearance/generic_form.html' + + def dispatch(self, *args, **kwargs): + if self.request.user.user_options.block_password_change: + messages.error( + message=_( + 'Changing the password is not allowed for this account.' + ), request=self.request + ) + return HttpResponseRedirect( + redirect_to=reverse(viewname=setting_home_view.view) + ) + + return super(MayanPasswordChangeView, self).dispatch(*args, **kwargs) -@public -def password_reset_complete_view(request): +class MayanPasswordResetCompleteView(StrongholdPublicMixin, PasswordResetCompleteView): extra_context = { 'appearance_type': 'plain' } - - return password_reset_complete( - request=request, extra_context=extra_context, - template_name='authentication/password_reset_complete.html' - ) + template_name = 'authentication/password_reset_complete.html' -@public -def password_reset_confirm_view(request, uidb64=None, token=None): +class MayanPasswordResetConfirmView(StrongholdPublicMixin, PasswordResetConfirmView): extra_context = { 'appearance_type': 'plain' } - - return password_reset_confirm( - request=request, extra_context=extra_context, - template_name='authentication/password_reset_confirm.html', - post_reset_redirect=reverse( - 'authentication:password_reset_complete_view' - ), uidb64=uidb64, token=token + success_url = reverse_lazy( + viewname='authentication:password_reset_complete_view' ) + template_name = 'authentication/password_reset_confirm.html' -@public -def password_reset_done_view(request): +class MayanPasswordResetDoneView(StrongholdPublicMixin, PasswordResetDoneView): extra_context = { 'appearance_type': 'plain' } - - return password_reset_done( - request=request, extra_context=extra_context, - template_name='authentication/password_reset_done.html' - ) + template_name = 'authentication/password_reset_done.html' -@public -def password_reset_view(request): +class MayanPasswordResetView(StrongholdPublicMixin, PasswordResetView): + email_template_name = 'authentication/password_reset_email.html' extra_context = { 'appearance_type': 'plain' } - - return password_reset( - request=request, extra_context=extra_context, - email_template_name='authentication/password_reset_email.html', - extra_email_context={ - 'project_title': setting_project_title.value, - 'project_website': setting_project_url.value, - 'project_copyright': mayan.__copyright__, - 'project_license': mayan.__license__, - }, subject_template_name='authentication/password_reset_subject.txt', - template_name='authentication/password_reset_form.html', - post_reset_redirect=reverse( - 'authentication:password_reset_done_view' - ) + extra_email_context = { + 'project_copyright': mayan.__copyright__, + 'project_license': mayan.__license__, + 'project_title': setting_project_title.value, + 'project_website': setting_project_url.value + } + subject_template_name = 'authentication/password_reset_subject.txt' + success_url = reverse_lazy( + viewname='authentication:password_reset_done_view' ) + template_name = 'authentication/password_reset_form.html'