296 lines
13 KiB
Python
296 lines
13 KiB
Python
from .context import context_adaption
|
|
from django.shortcuts import render, redirect
|
|
from django.conf import settings
|
|
from django.contrib import messages
|
|
from django.contrib.auth import authenticate
|
|
from django.contrib.auth import login as django_login
|
|
from django.contrib.auth import logout as django_logout
|
|
from django.contrib.auth.decorators import login_required
|
|
from django.contrib.auth.forms import AuthenticationForm
|
|
from django.contrib.auth.models import User
|
|
from django.utils.encoding import force_str
|
|
from django.utils.http import urlsafe_base64_decode
|
|
from django.utils.translation import gettext as _
|
|
from .forms import PasswordRecoverForm, UserRegistrationForm, UserProfileForm, UserActivationForm, UserPasswordChangeForm, PasswordRecoverChangeForm
|
|
import logging
|
|
from .models import get_userprofile
|
|
from themes import Context
|
|
from . tokens import generate_token
|
|
import users
|
|
from users import emails
|
|
from users import parameter
|
|
|
|
logger = logging.getLogger(settings.ROOT_LOGGER_NAME).getChild(__name__)
|
|
|
|
|
|
def password_recovery(request):
|
|
messages.error(request, "Password recovery is not yet implemented!")
|
|
return redirect(request.GET.get('next') or '/')
|
|
|
|
|
|
@login_required
|
|
def profile(request):
|
|
context = Context(request) # needs to be executed first because of time mesurement
|
|
profile = get_userprofile(request.user)
|
|
# External Additional forms
|
|
ext_profiles = parameter.get(parameter.USERS_PROFILE_ADDITIONS)
|
|
# change class to instance
|
|
ext_profiles = {key: ext_profiles[key](request) for key in ext_profiles}
|
|
if request.POST:
|
|
form_userprofile = UserProfileForm(request.POST, instance=profile)
|
|
form_userchange = UserPasswordChangeForm(request)
|
|
ext_valid = [form.is_valid() for form in ext_profiles.values()]
|
|
if form_userprofile.is_valid() and form_userchange.is_valid() and not False in ext_valid:
|
|
form_userprofile.save()
|
|
form_userchange.save()
|
|
for form in ext_profiles.values():
|
|
form.save()
|
|
return redirect(request.GET.get('next') or '/')
|
|
else:
|
|
form_userprofile = UserProfileForm(instance=profile)
|
|
form_userchange = UserPasswordChangeForm(request)
|
|
context_adaption(
|
|
context,
|
|
request,
|
|
_('Profile for %(username)s') % {'username': request.user.username},
|
|
form_userprofile=form_userprofile,
|
|
form_userchange=form_userchange,
|
|
ext_profiles=ext_profiles,
|
|
)
|
|
return render(request, 'users/profile.html', context=context)
|
|
|
|
|
|
def recover(request):
|
|
context = Context(request) # needs to be executed first because of time mesurement
|
|
if parameter.get(parameter.USERS_PASSWORD_RECOVERY) or request.user.is_superuser:
|
|
context_adaption(context, request, _('Password Recovery'))
|
|
if not request.POST:
|
|
form = PasswordRecoverForm(request)
|
|
else:
|
|
username = request.POST.get("username")
|
|
try:
|
|
user = User.objects.get(username=username)
|
|
except User.DoesNotExist:
|
|
pass # hide non existing user (just do nothing)
|
|
else:
|
|
profile = get_userprofile(user)
|
|
if profile.mail_validated:
|
|
emails.send_recover_mail(user, request)
|
|
#
|
|
messages.info(request, _("If the user exists, you will get a reover email."))
|
|
return redirect("users-login")
|
|
context['form'] = form
|
|
return render(request, 'users/recover.html', context)
|
|
else:
|
|
messages.info(request, _("Password recovery is deactivated. Contact your system administrator."))
|
|
return redirect('users-login')
|
|
|
|
|
|
def register(request):
|
|
context = Context(request) # needs to be executed first because of time mesurement
|
|
if parameter.get(parameter.USERS_SELF_REGISTRATION) or request.user.is_superuser:
|
|
context_adaption(context, request, _('Register'))
|
|
if not request.POST:
|
|
form = UserRegistrationForm()
|
|
messages.info(request, _('If you already have an account, login <a href="%(url)s">here</a>.') % {'url': users.url_login(request)})
|
|
else:
|
|
form = UserRegistrationForm(request.POST)
|
|
if form.is_valid():
|
|
# Deactivate the user, if validation or activation is required
|
|
if parameter.get(parameter.USERS_MAIL_VALIDATION) or parameter.get(parameter.USERS_ADMIN_ACTIVATION):
|
|
form.instance.is_active = False
|
|
form.save()
|
|
# Send welcome message
|
|
emails.send_welcome_mail(form.instance)
|
|
if parameter.get(parameter.USERS_MAIL_VALIDATION):
|
|
emails.send_validation_mail(form.instance, request)
|
|
# Add success message
|
|
messages.success(request, parameter.registration_flow_description(form.cleaned_data.get('username')))
|
|
return redirect('users-login')
|
|
else:
|
|
messages.error(request, _('Registration failed!'))
|
|
context['form'] = form
|
|
return render(request, 'users/register.html', context)
|
|
else:
|
|
messages.info(request, _("Self registration is deactivated. Contact your system administrator."))
|
|
return redirect('users-login')
|
|
|
|
|
|
def login(request):
|
|
context = Context(request) # needs to be executed first because of time mesurement
|
|
context_adaption(context, request, _('Login'))
|
|
if not request.POST:
|
|
form = AuthenticationForm()
|
|
if parameter.get(parameter.USERS_SELF_REGISTRATION):
|
|
messages.info(request, _('If you don\'t have an acount, register <a href="%(url)s">here</a>.') % {'url': users.url_register(request)})
|
|
else:
|
|
form = AuthenticationForm(request, data=request.POST)
|
|
if form.is_valid():
|
|
username = form.cleaned_data.get('username')
|
|
user = authenticate(username=username, password=form.cleaned_data.get('password'))
|
|
django_login(request, user)
|
|
messages.success(request, _('You are now logged in as %(username)s.') % {'username': username})
|
|
return redirect(request.GET.get('next') or '/')
|
|
else:
|
|
username = form.cleaned_data.get('username')
|
|
try:
|
|
user = User.objects.get(username=username)
|
|
except User.DoesNotExist:
|
|
is_active = True
|
|
else:
|
|
is_active = user.is_active
|
|
if is_active:
|
|
if parameter.get(parameter.USERS_SELF_REGISTRATION):
|
|
messages.error(request, _('Login failed! You can do a password recorvery <a href="%(url_recover)s">here</a> or you can register <a href="%(url_register)s">here</a>.') %
|
|
{'url_register': users.url_register(request), 'url_recover': users.url_recover(request)})
|
|
else:
|
|
messages.error(request, _('Login failed! You can do a password recorvery <a href="%(url_recover)s">here</a>.') %
|
|
{'url_recover': users.url_recover(request)})
|
|
else:
|
|
messages.info(request, _("The account is deactivated. Confirm your email adress and wait for the administrator to activate your account."))
|
|
|
|
context['form'] = form
|
|
return render(request, 'users/login.html', context)
|
|
|
|
|
|
def logout(request):
|
|
messages.success(request, _('You are no longer logged in as %(username)s.') % {'username': request.user.username})
|
|
session_cache = {}
|
|
try:
|
|
for variable in settings.PERSISTENT_SESSION_VARIABLES:
|
|
value = request.session.get(variable)
|
|
if value is not None:
|
|
session_cache[variable] = value
|
|
except AttributeError:
|
|
pass # PERSISTENT_SESSION_VARIABLES are possibly not defined in the settings
|
|
django_logout(request)
|
|
for variable in session_cache:
|
|
request.session[variable] = session_cache[variable]
|
|
return redirect(request.GET.get('next') or '/')
|
|
|
|
|
|
def validate(request, uidb64, token):
|
|
context = Context(request) # needs to be executed first because of time mesurement
|
|
try:
|
|
uid = force_str(urlsafe_base64_decode(uidb64))
|
|
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
|
|
uid = None
|
|
myuser = None
|
|
else:
|
|
try:
|
|
myuser = User.objects.get(pk=uid)
|
|
except User.DoesNotExist:
|
|
myuser = None
|
|
|
|
if myuser is not None and generate_token.check_token(myuser, token):
|
|
up = get_userprofile(myuser)
|
|
if up.mail_pending:
|
|
# change of email-address
|
|
myuser.email = up.mail_pending
|
|
myuser.save()
|
|
up.mail_pending = None
|
|
up.save()
|
|
messages.success(request, _("Your new email address is now active."))
|
|
return redirect("/")
|
|
else:
|
|
# Store mail validation to user profile
|
|
profile = get_userprofile(myuser)
|
|
profile.mail_validated = True
|
|
profile.save()
|
|
if not parameter.get(parameter.USERS_ADMIN_ACTIVATION):
|
|
# Activate user
|
|
myuser.is_active = True
|
|
myuser.save()
|
|
messages.success(request, _("Your Account has been activated."))
|
|
return redirect('users-login')
|
|
else:
|
|
emails.send_activation_mail(myuser, request)
|
|
messages.success(request, _("Your Email has been validated. Wait for the administrator to activate your account"))
|
|
return redirect("/")
|
|
else:
|
|
context_adaption(
|
|
context,
|
|
request,
|
|
_('Validation failed'),
|
|
)
|
|
messages.info(request, _("Vaildation failed. The system administrator will be informed."))
|
|
emails.send_validation_failed(uid, token)
|
|
return redirect("/")
|
|
|
|
|
|
@login_required
|
|
def activate(request, pk):
|
|
context = Context(request) # needs to be executed first because of time mesurement
|
|
if not request.POST:
|
|
if request.user.is_superuser:
|
|
user_to_be_activated = User.objects.get(pk=pk)
|
|
if not user_to_be_activated.is_active:
|
|
user_to_be_activated.is_active = True
|
|
form = UserActivationForm(instance=user_to_be_activated)
|
|
context_adaption(
|
|
context,
|
|
request,
|
|
_('Activation of user: %s') % f"{user_to_be_activated.username} - {user_to_be_activated.email}",
|
|
form=form,
|
|
)
|
|
return render(request, 'users/activate.html', context)
|
|
else:
|
|
messages.error(request, _("The user %s is already active.") % user_to_be_activated.username)
|
|
else:
|
|
messages.error(request, _("You are no administrator. Log in as administrator and try again!"))
|
|
else:
|
|
submit = request.POST.get("submit")
|
|
delete = request.POST.get("delete")
|
|
user_to_be_activated = User.objects.get(pk=pk)
|
|
if submit:
|
|
form = UserActivationForm(request.POST, instance=user_to_be_activated)
|
|
if form.is_valid():
|
|
form.save()
|
|
messages.info(request, _("User permissions changed."))
|
|
else:
|
|
messages.error(request, _("Error while processing user change form"))
|
|
if delete:
|
|
user_to_be_activated.delete()
|
|
messages.info(request, _("User deleted."))
|
|
return redirect("/")
|
|
|
|
|
|
def recover_token(request, uidb64, token):
|
|
context = Context(request) # needs to be executed first because of time mesurement
|
|
try:
|
|
uid = force_str(urlsafe_base64_decode(uidb64))
|
|
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
|
|
uid = None
|
|
myuser = None
|
|
else:
|
|
try:
|
|
myuser = User.objects.get(pk=uid)
|
|
except User.DoesNotExist:
|
|
myuser = None
|
|
|
|
if myuser is not None and generate_token.check_token(myuser, token):
|
|
if request.POST:
|
|
form = PasswordRecoverChangeForm(myuser, data=request.POST)
|
|
if form.is_valid():
|
|
form.save()
|
|
return redirect(request.GET.get('next') or 'users-login')
|
|
else:
|
|
form = PasswordRecoverChangeForm(myuser)
|
|
#
|
|
context_adaption(
|
|
context,
|
|
request,
|
|
_('Password recovery for %(username)s') % {'username': myuser.username},
|
|
form=form,
|
|
)
|
|
return render(request, 'users/recover.html', context=context)
|
|
else:
|
|
context_adaption(
|
|
context,
|
|
request,
|
|
_('Recovery failed'),
|
|
)
|
|
messages.info(request, _("Recovery failed. The system administrator will be informed."))
|
|
emails.send_recover_failed(uid, token)
|
|
return redirect("/")
|