import logging from django.conf import settings from django.contrib.auth.views import ( LoginView as LoginViewBase, LogoutView, PasswordResetView as PasswordResetViewBase, PasswordResetDoneView as PasswordResetDoneViewBase, PasswordResetConfirmView as PasswordResetConfirmViewBase, PasswordResetCompleteView as PasswordResetCompleteViewBase, PasswordChangeView as PasswordChangeViewBase, PasswordChangeDoneView as PasswordChangeDoneViewBase ) from django.views.generic import TemplateView from registration.backends.default.views import ( RegistrationView as RegistrationViewBase, ResendActivationView as ResendActivationViewBase ) from django.contrib.messages.views import SuccessMessageMixin from django.http import JsonResponse from django.shortcuts import redirect, resolve_url from django.urls import reverse, reverse_lazy from django.utils.http import is_safe_url from django.utils.translation import ugettext_lazy as _ from core.views import ProtectedView from .forms import ( PasswordResetRequestForm, PasswordResetForm, RegistrationCompanyForm, AuthenticationForm, RegistrationForm) logger = logging.getLogger(__name__) # Create your views here. class LoginView(LoginViewBase): redirect_field_name = 'next' form_class = AuthenticationForm redirect_authenticated_user = True template_name = 'accounts_ext/authentication.html' def dispatch(self, request, *args, **kwargs): if self.request.user.is_authenticated: redirect_to = self.request.POST.get( self.redirect_field_name, self.request.GET.get(self.redirect_field_name, '') ) if not is_safe_url(url=redirect_to, host=self.request.get_host()): redirect_to = resolve_url(settings.LOGIN_REDIRECT_URL) if redirect_to == self.request.path: raise ValueError( "Redirection loop for authenticated user detected. Check that " "your LOGIN_REDIRECT_URL doesn't point to a login page." ) return redirect(redirect_to) return super().dispatch(request, *args, **kwargs) def render_done(self, form, **kwargs): """ This method gets called when all forms passed. The method should also re-validate all steps to prevent manipulation. If any form don't validate, `render_revalidation_failure` should get called. If everything is fine call `done`. """ final_form_list = [] # walk through the form list and try to validate the data again. for form_key in self.get_form_list(): form_obj = self.get_form(step=form_key, data=self.storage.get_step_data(form_key), files=self.storage.get_step_files( form_key)) form_obj.exclude_second_captcha_validation = True if not (form_key in self.idempotent_dict or form_obj.is_valid()): return self.render_revalidation_failure(form_key, form_obj, **kwargs) final_form_list.append(form_obj) # render the done view and reset the wizard before returning the # response. This is needed to prevent from rendering done with the # same data twice. done_response = self.done(final_form_list, **kwargs) self.storage.reset() return done_response def get_user(self): """ Returns the user authenticated by the AuthenticationForm. Returns False if not a valid user; see also issue #65. """ if not self.user_cache: form_obj = self.get_form(step='auth', data=self.storage.get_step_data('auth')) form_obj.exclude_second_captcha_validation = True self.user_cache = form_obj.is_valid() and form_obj.user_cache return self.user_cache def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['title'] = AuthenticationForm.title return context class ResetPasswordView(PasswordResetViewBase): form_class = PasswordResetRequestForm template_name = 'accounts_ext/reset_password.html' email_template_name = 'Reset password email' html_email_template_name = 'emails/reset_password_email.html' success_url = reverse_lazy('accounts_ext:reset_password_done') from_email = settings.DEFAULT_FROM_EMAIL subject_template_name = _('Сброс пароля') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['title'] = PasswordResetForm.title return context class ResetPasswordDoneView(PasswordResetDoneViewBase): template_name = 'accounts_ext/reset_password_done.html' class ResetPasswordConfirmView(PasswordResetConfirmViewBase): form_class = PasswordResetForm template_name = 'accounts_ext/reset_password_confirm.html' success_url = reverse_lazy('accounts_ext:reset_password_complete') def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['request'] = self.request return kwargs class ResetPasswordCompleteView(PasswordResetCompleteViewBase): template_name = 'accounts_ext/reset_password_complete.html' title = _('Password reset complete') class RegistrationView(RegistrationViewBase): http_method_names = ['get', 'post'] template_name = 'registration/registration.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) if self.request.POST: context['company_form'] = RegistrationCompanyForm(self.request.POST) else: context['company_form'] = RegistrationCompanyForm() context['title'] = RegistrationForm.title return context def form_valid(self, form): context = self.get_context_data() company_form = context.get('company_form') try: user = form.save() if company_form.is_valid(): company_form.save(user=user) else: logger.error("User {email} company has invalid data during registration") except Exception as e: logger.error(e) return self.form_invalid(form=form) return super().form_valid(form) class RegistrationDoneView(TemplateView): template_name = 'registration/registration_done.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['title'] = _('Отправка письма активации') return context class ResendActivationView(ResendActivationViewBase): template_name = 'registration/resend_activation.tml' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['title'] = _('Отправка письма активации') return context class ChangePasswordForm(PasswordChangeViewBase): template_name = 'accounts_ext/password_reset_change.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['title'] = _('Введение нового пароля') return context class ChangePasswordDoneForm(PasswordChangeDoneViewBase): template_name = 'accounts_ext/password_reset_change_done.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['title'] = _('Сброс пароля') return context class ProfileView(ProtectedView): template_name = 'accounts_ext/index.html'