Newer
Older
from django.conf import settings
from django.contrib import messages
from django.contrib.auth import get_user_model, login, update_session_auth_hash
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import AdminPasswordChangeForm
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.contrib.auth.views import SuccessURLAllowedHostsMixin
from django.http import HttpResponseRedirect
from django.shortcuts import redirect, render, resolve_url
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.utils.http import is_safe_url, urlsafe_base64_decode
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.debug import sensitive_post_parameters
from django.views.generic.base import TemplateView
from two_factor.views import LoginView as TwoFactorLoginView
from wagtail.admin.views.account import password_management_enabled
from .decorators import require_oauth_whitelist
from .forms import BecomeUserForm, ProfileForm
class LoginView(SuccessURLAllowedHostsMixin, TwoFactorLoginView):
redirect_authenticated_user = False
@method_decorator(sensitive_post_parameters())
@method_decorator(csrf_protect)
@method_decorator(never_cache)
def dispatch(self, request, *args, **kwargs):
if self.redirect_authenticated_user and self.request.user.is_authenticated:
redirect_to = self.get_success_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 HttpResponseRedirect(redirect_to)
return super().dispatch(request, *args, **kwargs)
def get_success_url(self):
url = self.get_redirect_url()
return url or resolve_url(settings.LOGIN_REDIRECT_URL)
def get_redirect_url(self):
"""Return the user-originating redirect URL if it's safe."""
redirect_to = self.request.POST.get(
self.redirect_field_name,
self.request.GET.get(self.redirect_field_name, '')
)
url_is_safe = is_safe_url(
url=redirect_to,
allowed_hosts=self.get_success_url_allowed_hosts(),
require_https=self.request.is_secure(),
)
return redirect_to if url_is_safe else ''
@method_decorator(login_required, name='dispatch')
class AccountView(UpdateView):
form_class = ProfileForm
template_name = 'users/account.html'
def get_object(self):
return self.request.user
def get_success_url(self,):
return reverse_lazy('users:account')
def get_context_data(self, **kwargs):
if self.request.user.is_superuser:
swappable_form = BecomeUserForm()
show_change_password = password_management_enabled() and self.request.user.has_usable_password(),
return super().get_context_data(
show_change_password=show_change_password,
**kwargs,
)
id = request.POST['user']
if request.POST and id:
return login_with_id(request, id)
return redirect('users:account')
@require_oauth_whitelist
def oauth(request):
"""Generic, empty view for the OAuth associations."""
return TemplateResponse(request, 'users/oauth.html', {})
class ActivationView(TemplateView):
def get(self, request, *args, **kwargs):
user = self.get_user(kwargs.get('uidb64'))
if self.valid(user, kwargs.get('token')):
user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)
return redirect('users:activate_password')
return render(request, 'users/activation/invalid.html')
Verify that the activation token is valid and within the
permitted activation time window.
"""
token_generator = PasswordResetTokenGenerator()
return user is not None and token_generator.check_token(user, token)
"""
Given the verified uid, look up and return the
corresponding user account if it exists, or ``None`` if it
doesn't.
"""
try:
user = User.objects.get(**{
Fredrik Jonsson
committed
'pk': force_text(urlsafe_base64_decode(uidb64))
})
return user
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
return None
def create_password(request):
"""
A custom view for the admin password change form used for account activation.
"""
if request.method == 'POST':
form = AdminPasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, user) # Important!
messages.success(request, 'Your password was successfully updated!')
return redirect('users:account')
else:
messages.error(request, 'Please correct the errors below.')
else:
form = AdminPasswordChangeForm(request.user)
return render(request, 'users/change_password.html', {
'form': form
})