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 UserRegistrationForm, UserProfileForm, UserActivationForm, UserPasswordChangeForm 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 register(request): context = Context(request) # needs to be executed first because of time mesurement if parameter.get(parameter.USERS_SELF_REGISTRATION): context_adaption(context, request, _('Register')) if not request.POST: form = UserRegistrationForm() messages.info(request, _('If you already have an account, login here.') % {'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 here.') % {'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 here or you can register here.') % {'url_register': users.url_register(request), 'url_recover': users.url_password_recovery(request)}) else: messages.error(request, _('Login failed! You can do a password recorvery here.') % {'url_recover': users.url_password_recovery(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("/")