2023-04-18 19:13:30 +00:00
|
|
|
"""
|
|
|
|
|
Views of RepApp.
|
|
|
|
|
"""
|
|
|
|
|
import datetime
|
2023-04-23 11:56:52 +00:00
|
|
|
import random
|
|
|
|
|
import string
|
2023-04-24 16:02:43 +00:00
|
|
|
import time
|
2023-04-25 12:17:59 +00:00
|
|
|
import os
|
2023-04-19 19:28:59 +00:00
|
|
|
from hashlib import sha256
|
2023-04-25 12:17:59 +00:00
|
|
|
from django.template.loader import render_to_string
|
|
|
|
|
from django.urls import reverse
|
|
|
|
|
from django.core.mail import send_mail
|
|
|
|
|
from django.contrib import messages
|
2023-04-18 18:04:32 +00:00
|
|
|
from django.views import generic
|
2023-04-19 19:28:59 +00:00
|
|
|
from django.urls import reverse_lazy
|
|
|
|
|
from django.shortcuts import get_object_or_404, render
|
2023-05-03 06:26:24 +00:00
|
|
|
from django.http import HttpResponseRedirect, HttpResponse
|
2023-04-23 11:56:52 +00:00
|
|
|
from django.core.exceptions import PermissionDenied
|
|
|
|
|
from django.contrib.auth.decorators import login_required
|
2023-04-24 16:02:43 +00:00
|
|
|
from django.contrib.auth import authenticate, login
|
|
|
|
|
from django.utils.timezone import now
|
2023-04-19 19:28:59 +00:00
|
|
|
from .forms import RegisterDevice, RegisterGuest
|
2023-05-03 06:26:24 +00:00
|
|
|
from .models import (Cafe, Device, Guest, OneTimeLogin,
|
|
|
|
|
CustomUser, Organisator, Reparateur)
|
|
|
|
|
from . import mail_interface
|
2023-04-25 12:17:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def send_one_time_login_mail(secret, mail, request):
|
2023-04-28 09:54:13 +00:00
|
|
|
"""
|
|
|
|
|
Send a mail with a one time login link.
|
|
|
|
|
"""
|
2023-04-25 12:17:59 +00:00
|
|
|
url = request.build_absolute_uri(
|
|
|
|
|
f'/onetimelogin/{secret}/')
|
|
|
|
|
subject = render_to_string(
|
|
|
|
|
'repapp/mail/mail_one_time_login_subject.html').replace('\n', '')
|
|
|
|
|
text = render_to_string('repapp/mail/mail_one_time_login_text.html', {
|
|
|
|
|
'link': url,
|
|
|
|
|
})
|
|
|
|
|
html = render_to_string('repapp/mail/mail_one_time_login_html.html', {
|
|
|
|
|
'link': url,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ok = send_mail(
|
|
|
|
|
subject=subject,
|
|
|
|
|
message=text,
|
|
|
|
|
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
|
|
|
|
recipient_list=[mail],
|
|
|
|
|
fail_silently=True,
|
|
|
|
|
html_message=html
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if ok > 0:
|
|
|
|
|
messages.add_message(request, messages.INFO,
|
|
|
|
|
'Sie haben einen neuen Login per eMail erhalten.')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def send_confirmation_mails(device, guest, cafe, request):
|
2023-04-28 09:54:13 +00:00
|
|
|
"""
|
|
|
|
|
Send confirmation mails for device registration.
|
|
|
|
|
"""
|
2023-04-25 12:17:59 +00:00
|
|
|
organizers = []
|
|
|
|
|
for organizer in Organisator.objects.all():
|
|
|
|
|
organizers.append(organizer.mail)
|
|
|
|
|
|
|
|
|
|
text = render_to_string('repapp/mail/notice_new_device.html', {
|
|
|
|
|
'guest': device.guest,
|
|
|
|
|
'device': device,
|
|
|
|
|
'cafe': device.cafe,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
send_mail(
|
|
|
|
|
subject=f"Neues Gerät { device.device }",
|
|
|
|
|
message=text,
|
|
|
|
|
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
|
|
|
|
recipient_list=organizers,
|
|
|
|
|
fail_silently=True
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
path = reverse('view_device', kwargs={
|
|
|
|
|
'device_identifier': device.identifier})
|
|
|
|
|
url = request.build_absolute_uri(path)
|
|
|
|
|
secret = create_one_time_login(guest.user, url)
|
|
|
|
|
login_url = request.build_absolute_uri(f'/onetimelogin/{secret}/')
|
|
|
|
|
|
|
|
|
|
subject = render_to_string('repapp/mail/mail_register_device_subject.html', {
|
|
|
|
|
'cafe': cafe,
|
|
|
|
|
}).replace('\n', '')
|
|
|
|
|
text = render_to_string('repapp/mail/mail_register_device_text.html', {
|
|
|
|
|
'guest': guest,
|
|
|
|
|
'device': device,
|
|
|
|
|
'cafe': cafe,
|
|
|
|
|
'login_url': login_url,
|
|
|
|
|
})
|
|
|
|
|
html = render_to_string('repapp/mail/mail_register_device_html.html', {
|
|
|
|
|
'guest': guest,
|
|
|
|
|
'device': device,
|
|
|
|
|
'cafe': cafe,
|
|
|
|
|
'login_url': login_url,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
mail_count = send_mail(
|
|
|
|
|
subject=subject,
|
|
|
|
|
message=text,
|
|
|
|
|
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
|
|
|
|
recipient_list=[f"{guest.mail}"],
|
|
|
|
|
fail_silently=True,
|
|
|
|
|
html_message=html
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if mail_count > 0:
|
|
|
|
|
device.confirmed = True
|
|
|
|
|
device.save()
|
|
|
|
|
else:
|
|
|
|
|
messages.add_message(request, messages.ERROR,
|
|
|
|
|
'Fehler beim senden der Bestätigungs-eMail!')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def send_guest_account_mail(guest, password, request):
|
2023-04-28 09:54:13 +00:00
|
|
|
"""
|
|
|
|
|
Send guest user account created mail.
|
|
|
|
|
"""
|
2023-04-25 12:17:59 +00:00
|
|
|
url = request.build_absolute_uri('/guest/profile/')
|
|
|
|
|
subject = render_to_string(
|
|
|
|
|
'repapp/mail/mail_new_guest_subject.html').replace('\n', '')
|
|
|
|
|
text = render_to_string('repapp/mail/mail_new_guest_text.html', {
|
|
|
|
|
'link': url,
|
|
|
|
|
'username': guest.user.email,
|
|
|
|
|
'password': password,
|
|
|
|
|
})
|
|
|
|
|
html = render_to_string('repapp/mail/mail_new_guest_html.html', {
|
|
|
|
|
'link': url,
|
|
|
|
|
'username': guest.user.email,
|
|
|
|
|
'password': password,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ok = send_mail(
|
|
|
|
|
subject=subject,
|
|
|
|
|
message=text,
|
|
|
|
|
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
|
|
|
|
recipient_list=[f"{guest.user.email}"],
|
|
|
|
|
fail_silently=True,
|
|
|
|
|
html_message=html
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if ok > 0:
|
|
|
|
|
messages.add_message(request, messages.INFO,
|
|
|
|
|
'Sie haben ihre Benutzerdaten per eMail erhalten.')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def is_member(user):
|
2023-04-28 09:54:13 +00:00
|
|
|
"""
|
|
|
|
|
Test is a user is a Repair-Café member.
|
|
|
|
|
"""
|
2023-04-25 12:17:59 +00:00
|
|
|
organisator = Organisator.objects.filter(mail=user.email).first()
|
|
|
|
|
reparateur = Reparateur.objects.filter(mail=user.email).first()
|
|
|
|
|
return organisator or reparateur
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_one_time_login(user, url) -> str:
|
|
|
|
|
"""
|
2023-04-28 09:54:13 +00:00
|
|
|
create_one_time_login creates a one time login object for guest user logins.
|
2023-04-25 12:17:59 +00:00
|
|
|
"""
|
|
|
|
|
secret = sha256(
|
|
|
|
|
f'{user.email}{url}{datetime.datetime.now()}{random.randint(0,9999999)}'.encode(
|
|
|
|
|
'utf-8')
|
|
|
|
|
).hexdigest()
|
2023-04-25 19:04:13 +00:00
|
|
|
secret_hash = sha256(secret.encode('utf-8')).hexdigest()
|
2023-04-25 12:17:59 +00:00
|
|
|
otl = OneTimeLogin(
|
2023-04-25 19:04:13 +00:00
|
|
|
secret=secret_hash,
|
2023-04-25 12:17:59 +00:00
|
|
|
user=user,
|
|
|
|
|
url=url,
|
|
|
|
|
)
|
|
|
|
|
otl.save()
|
|
|
|
|
return secret
|
2023-04-18 18:04:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class IndexView(generic.ListView):
|
2023-04-18 19:13:30 +00:00
|
|
|
"""
|
|
|
|
|
The IndexView lists all future Repair-Cafés.
|
|
|
|
|
"""
|
2023-04-18 18:04:32 +00:00
|
|
|
template_name = "repapp/index.html"
|
|
|
|
|
|
|
|
|
|
def get_queryset(self):
|
2023-04-20 18:52:24 +00:00
|
|
|
messages.add_message(self.request, messages.INFO,
|
|
|
|
|
'Dies ist eine Test. Leider können sie sich hier noch nicht anmelden.')
|
2023-04-18 19:13:30 +00:00
|
|
|
return Cafe.objects.filter(event_date__gte=datetime.date.today())
|
|
|
|
|
|
|
|
|
|
|
2023-04-19 19:28:59 +00:00
|
|
|
class RegisterDeviceFormView(generic.edit.FormView):
|
2023-04-24 16:02:43 +00:00
|
|
|
"""
|
|
|
|
|
RegisterDeviceFormView shows the form for registering new devices.
|
|
|
|
|
"""
|
2023-04-19 19:28:59 +00:00
|
|
|
template_name = "repapp/register_device.html"
|
|
|
|
|
form_class = RegisterDevice
|
|
|
|
|
|
|
|
|
|
def form_valid(self, form):
|
2023-04-20 18:52:24 +00:00
|
|
|
cafe = self.kwargs['cafe']
|
|
|
|
|
cafe = get_object_or_404(Cafe, pk=cafe)
|
2023-04-19 19:28:59 +00:00
|
|
|
mail = form.cleaned_data['mail']
|
|
|
|
|
device = form.cleaned_data['device']
|
|
|
|
|
identifier = sha256(
|
|
|
|
|
f'{device}{mail}{datetime.datetime.now()}'.encode('utf-8')
|
|
|
|
|
).hexdigest()
|
|
|
|
|
device = Device(
|
|
|
|
|
identifier=identifier,
|
|
|
|
|
device=device,
|
2023-04-21 16:24:31 +00:00
|
|
|
manufacturer=form.cleaned_data['manufacturer'],
|
2023-04-19 19:28:59 +00:00
|
|
|
error=form.cleaned_data['error'],
|
|
|
|
|
follow_up=form.cleaned_data['follow_up'],
|
2023-04-21 16:24:31 +00:00
|
|
|
device_picture=self.request.FILES.get("device_picture", None),
|
|
|
|
|
type_plate_picture=self.request.FILES.get(
|
|
|
|
|
"type_plate_picture", None),
|
2023-04-20 18:52:24 +00:00
|
|
|
cafe=cafe,
|
2023-04-21 16:24:31 +00:00
|
|
|
confirmed=False,
|
2023-04-19 19:28:59 +00:00
|
|
|
)
|
|
|
|
|
device.save()
|
|
|
|
|
|
|
|
|
|
guest = Guest.objects.filter(mail=mail).first()
|
2023-05-03 06:26:24 +00:00
|
|
|
user = CustomUser.objects.filter(email=mail).first()
|
2023-04-19 19:28:59 +00:00
|
|
|
|
2023-05-03 06:26:24 +00:00
|
|
|
if guest and user:
|
2023-04-20 18:52:24 +00:00
|
|
|
device.guest = guest
|
2023-04-19 19:28:59 +00:00
|
|
|
device.save()
|
2023-04-21 16:24:31 +00:00
|
|
|
|
2023-05-03 06:26:24 +00:00
|
|
|
guest.user = user
|
|
|
|
|
guest.save()
|
|
|
|
|
|
2023-04-21 16:24:31 +00:00
|
|
|
send_confirmation_mails(device, guest, cafe, self.request)
|
|
|
|
|
|
|
|
|
|
resp = HttpResponseRedirect(
|
2023-04-19 19:28:59 +00:00
|
|
|
reverse_lazy('register_device_final', kwargs={
|
2023-04-20 18:52:24 +00:00
|
|
|
'cafe': cafe.pk,
|
2023-04-21 16:24:31 +00:00
|
|
|
'device_identifier': device.identifier})
|
2023-04-19 19:28:59 +00:00
|
|
|
)
|
2023-04-21 16:24:31 +00:00
|
|
|
return resp
|
2023-04-19 19:28:59 +00:00
|
|
|
else:
|
|
|
|
|
return HttpResponseRedirect(
|
|
|
|
|
reverse_lazy('register_guest', kwargs={
|
2023-04-20 18:52:24 +00:00
|
|
|
'cafe': cafe.pk,
|
2023-04-21 16:24:31 +00:00
|
|
|
'device_identifier': device.identifier,
|
2023-04-19 19:28:59 +00:00
|
|
|
'mail': mail})
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
2023-04-20 18:52:24 +00:00
|
|
|
cafe = self.kwargs['cafe']
|
|
|
|
|
cafe = get_object_or_404(Cafe, pk=cafe)
|
2023-04-19 19:28:59 +00:00
|
|
|
|
|
|
|
|
context = super(RegisterDeviceFormView, self).get_context_data(
|
|
|
|
|
**kwargs
|
|
|
|
|
)
|
|
|
|
|
context["cafe"] = cafe
|
|
|
|
|
return context
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RegisterGuestFormView(generic.edit.FormView):
|
2023-04-24 19:03:56 +00:00
|
|
|
"""
|
|
|
|
|
View for registering a new guest.
|
|
|
|
|
"""
|
2023-04-19 19:28:59 +00:00
|
|
|
template_name = "repapp/register_guest.html"
|
|
|
|
|
form_class = RegisterGuest
|
|
|
|
|
|
|
|
|
|
def form_valid(self, form):
|
2023-04-20 18:52:24 +00:00
|
|
|
cafe = self.kwargs['cafe']
|
|
|
|
|
cafe = get_object_or_404(Cafe, pk=cafe)
|
2023-04-19 19:28:59 +00:00
|
|
|
|
2023-04-21 16:24:31 +00:00
|
|
|
device_identifier = self.kwargs['device_identifier']
|
|
|
|
|
device = get_object_or_404(Device, identifier=device_identifier)
|
2023-04-19 19:28:59 +00:00
|
|
|
|
|
|
|
|
name = form.cleaned_data['name']
|
2023-04-23 11:56:52 +00:00
|
|
|
mail = self.kwargs['mail']
|
2023-04-19 19:28:59 +00:00
|
|
|
residence = form.cleaned_data['residence']
|
|
|
|
|
identifier = sha256(
|
|
|
|
|
f'{name}{residence}{datetime.datetime.now()}'.encode('utf-8')
|
|
|
|
|
).hexdigest()
|
|
|
|
|
guest = Guest(
|
|
|
|
|
identifier=identifier,
|
|
|
|
|
name=name,
|
|
|
|
|
phone=form.cleaned_data['phone'],
|
|
|
|
|
residence=residence,
|
2023-04-23 11:56:52 +00:00
|
|
|
mail=mail,
|
2023-04-19 19:28:59 +00:00
|
|
|
)
|
|
|
|
|
guest.save()
|
|
|
|
|
|
2023-04-20 18:52:24 +00:00
|
|
|
device.guest = guest
|
2023-04-19 19:28:59 +00:00
|
|
|
device.save()
|
|
|
|
|
|
2023-04-23 11:56:52 +00:00
|
|
|
if not CustomUser.objects.filter(email=mail).exists():
|
|
|
|
|
password = ''.join(random.choice(string.ascii_letters)
|
|
|
|
|
for i in range(10))
|
2023-04-25 18:47:53 +00:00
|
|
|
|
|
|
|
|
username = name
|
|
|
|
|
i = 1
|
|
|
|
|
while CustomUser.objects.filter(username=username).first():
|
|
|
|
|
username = f'{name}{i}'
|
|
|
|
|
i = i + 1
|
|
|
|
|
|
2023-04-23 11:56:52 +00:00
|
|
|
user = CustomUser.objects.create_user(
|
2023-04-25 18:47:53 +00:00
|
|
|
username=username,
|
2023-04-23 11:56:52 +00:00
|
|
|
email=mail,
|
2023-04-24 19:03:56 +00:00
|
|
|
)
|
|
|
|
|
user.set_password(password)
|
2023-04-23 11:56:52 +00:00
|
|
|
user.save()
|
|
|
|
|
|
2023-04-25 07:14:26 +00:00
|
|
|
guest.user = user
|
|
|
|
|
guest.save()
|
|
|
|
|
|
2023-04-24 16:02:43 +00:00
|
|
|
send_guest_account_mail(guest, password, self.request)
|
2023-04-23 11:56:52 +00:00
|
|
|
|
2023-04-21 16:24:31 +00:00
|
|
|
send_confirmation_mails(device, guest, cafe, self.request)
|
|
|
|
|
|
2023-04-19 19:28:59 +00:00
|
|
|
return HttpResponseRedirect(
|
|
|
|
|
reverse_lazy('register_device_final', kwargs={
|
2023-04-20 18:52:24 +00:00
|
|
|
'cafe': cafe.pk,
|
2023-04-21 16:24:31 +00:00
|
|
|
'device_identifier': device.identifier})
|
2023-04-19 19:28:59 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def get_context_data(self, **kwargs):
|
2023-04-20 18:52:24 +00:00
|
|
|
cafe = self.kwargs['cafe']
|
|
|
|
|
cafe = get_object_or_404(Cafe, pk=cafe)
|
2023-04-19 19:28:59 +00:00
|
|
|
|
2023-04-21 16:24:31 +00:00
|
|
|
device_identifier = self.kwargs['device_identifier']
|
|
|
|
|
device = get_object_or_404(Device, identifier=device_identifier)
|
2023-04-19 19:28:59 +00:00
|
|
|
|
2023-04-25 07:14:26 +00:00
|
|
|
mail = self.kwargs['mail']
|
|
|
|
|
guest = Guest.objects.filter(mail=mail).first()
|
|
|
|
|
if guest:
|
|
|
|
|
return HttpResponseRedirect(
|
|
|
|
|
reverse_lazy('register_device_final', kwargs={
|
|
|
|
|
'cafe': cafe.pk,
|
|
|
|
|
'device_identifier': device.identifier})
|
|
|
|
|
)
|
|
|
|
|
|
2023-04-19 19:28:59 +00:00
|
|
|
context = super(RegisterGuestFormView, self).get_context_data(
|
|
|
|
|
**kwargs
|
2023-04-18 19:13:30 +00:00
|
|
|
)
|
2023-04-19 19:28:59 +00:00
|
|
|
context["cafe"] = cafe
|
|
|
|
|
context["device"] = device
|
2023-04-25 07:14:26 +00:00
|
|
|
context["mail"] = mail
|
2023-04-19 19:28:59 +00:00
|
|
|
|
|
|
|
|
return context
|
|
|
|
|
|
|
|
|
|
|
2023-04-21 16:24:31 +00:00
|
|
|
def register_device_final(request, cafe, device_identifier):
|
2023-04-24 19:03:56 +00:00
|
|
|
"""
|
|
|
|
|
View to confirm device registration.
|
|
|
|
|
"""
|
2023-04-20 18:52:24 +00:00
|
|
|
cafe = get_object_or_404(Cafe, pk=cafe)
|
2023-04-21 16:24:31 +00:00
|
|
|
device = get_object_or_404(Device, identifier=device_identifier)
|
2023-04-20 18:52:24 +00:00
|
|
|
|
2023-04-19 19:28:59 +00:00
|
|
|
return render(
|
|
|
|
|
request,
|
|
|
|
|
"repapp/register_device_final.html",
|
2023-04-21 16:24:31 +00:00
|
|
|
{"device": device, 'cafe': cafe},
|
2023-04-20 18:52:24 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2023-04-23 11:56:52 +00:00
|
|
|
@login_required
|
2023-04-21 16:24:31 +00:00
|
|
|
def device_view(request, device_identifier):
|
2023-04-24 19:03:56 +00:00
|
|
|
"""
|
|
|
|
|
View for showing device details.
|
|
|
|
|
"""
|
2023-04-23 11:56:52 +00:00
|
|
|
user = request.user
|
|
|
|
|
if not user:
|
|
|
|
|
raise PermissionDenied()
|
|
|
|
|
|
2023-04-21 16:24:31 +00:00
|
|
|
device = get_object_or_404(Device, identifier=device_identifier)
|
2023-04-23 11:56:52 +00:00
|
|
|
if not device.guest:
|
|
|
|
|
raise PermissionDenied()
|
|
|
|
|
|
2023-04-24 16:02:43 +00:00
|
|
|
if not (is_member(user) or device.guest.mail == user.email):
|
|
|
|
|
raise PermissionDenied()
|
2023-04-20 18:52:24 +00:00
|
|
|
|
|
|
|
|
return render(
|
|
|
|
|
request,
|
|
|
|
|
"repapp/device_view.html",
|
|
|
|
|
{"device": device},
|
|
|
|
|
)
|
2023-04-23 11:56:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@login_required
|
|
|
|
|
def profile(request):
|
2023-04-24 19:03:56 +00:00
|
|
|
"""
|
|
|
|
|
View for showing guest details.
|
|
|
|
|
"""
|
2023-04-23 11:56:52 +00:00
|
|
|
user = request.user
|
|
|
|
|
if not user:
|
|
|
|
|
raise PermissionDenied()
|
|
|
|
|
|
|
|
|
|
guest = get_object_or_404(Guest, mail=user.email)
|
|
|
|
|
|
|
|
|
|
return render(
|
|
|
|
|
request,
|
|
|
|
|
"repapp/guest_profile.html",
|
|
|
|
|
{
|
|
|
|
|
'guest': guest
|
|
|
|
|
}
|
|
|
|
|
)
|
2023-04-23 15:40:19 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def member_login(request):
|
2023-04-24 19:03:56 +00:00
|
|
|
"""
|
|
|
|
|
Login page for repair cafe members, using OIDC.
|
|
|
|
|
"""
|
2023-04-23 15:40:19 +00:00
|
|
|
return render(
|
|
|
|
|
request,
|
|
|
|
|
"repapp/member_login.html"
|
|
|
|
|
)
|
2023-04-24 16:02:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def cron(request):
|
2023-04-24 19:03:56 +00:00
|
|
|
"""
|
|
|
|
|
View to trigger automated regular tasks.
|
|
|
|
|
"""
|
2023-05-03 06:26:24 +00:00
|
|
|
return HttpResponse('done.')
|
2023-04-24 16:02:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def process_mails(request):
|
2023-04-24 19:03:56 +00:00
|
|
|
"""
|
|
|
|
|
View to trigger processing of email in inbox.
|
|
|
|
|
"""
|
2023-05-03 06:26:24 +00:00
|
|
|
count = mail_interface.process_mails()
|
|
|
|
|
return HttpResponse(f'Done. Processed {count} messages.')
|
2023-04-24 16:02:43 +00:00
|
|
|
|
|
|
|
|
|
2023-04-25 12:04:26 +00:00
|
|
|
def one_time_login(request, secret: str):
|
2023-04-24 19:03:56 +00:00
|
|
|
"""
|
|
|
|
|
View for one time login.
|
|
|
|
|
"""
|
|
|
|
|
# waste a little time as brute force protection
|
2023-04-24 16:02:43 +00:00
|
|
|
time.sleep(1)
|
|
|
|
|
|
2023-04-25 19:04:13 +00:00
|
|
|
secret_hash = sha256(secret.encode('utf-8')).hexdigest()
|
|
|
|
|
otl = get_object_or_404(OneTimeLogin, secret=secret_hash)
|
2023-04-24 16:02:43 +00:00
|
|
|
|
|
|
|
|
if otl.login_used:
|
|
|
|
|
messages.add_message(request, messages.ERROR,
|
|
|
|
|
'Der Einmal-Login wurde schon verwendet und ist nichtmehr gültig.')
|
2023-04-25 19:04:13 +00:00
|
|
|
new_secret = create_one_time_login(otl.user, otl.url)
|
|
|
|
|
send_one_time_login_mail(new_secret, otl.user.email, request)
|
2023-04-24 16:02:43 +00:00
|
|
|
return HttpResponseRedirect(reverse_lazy('index'))
|
|
|
|
|
else:
|
|
|
|
|
otl.login_used = True
|
|
|
|
|
otl.login_date = now()
|
|
|
|
|
otl.save()
|
|
|
|
|
|
2023-04-25 19:04:13 +00:00
|
|
|
user = authenticate(request, username=secret_hash, password=None)
|
2023-04-24 16:02:43 +00:00
|
|
|
|
|
|
|
|
if user is not None:
|
|
|
|
|
login(request, user)
|
|
|
|
|
messages.add_message(request, messages.INFO, 'Login erfolgreich!')
|
|
|
|
|
return HttpResponseRedirect(otl.url)
|
|
|
|
|
else:
|
|
|
|
|
messages.add_message(request, messages.ERROR, 'Login fehlgeschlagen.')
|
|
|
|
|
return HttpResponseRedirect(reverse_lazy('index'))
|
2023-04-28 09:54:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def bootstrap(request):
|
|
|
|
|
"""
|
|
|
|
|
Bootstrap design test page.
|
|
|
|
|
"""
|
|
|
|
|
return render(
|
|
|
|
|
request,
|
|
|
|
|
"repapp/bootstrap.html"
|
|
|
|
|
)
|