diff --git a/cspell.json b/cspell.json index 3987eac..27501ea 100644 --- a/cspell.json +++ b/cspell.json @@ -18,7 +18,8 @@ "Keycloak", "tabindex", "onetimelogin", - "Ammeldelink" + "Ammeldelink", + "orga" ], "ignoreWords": [], "import": [] diff --git a/rc_hip/repapp/forms.py b/rc_hip/repapp/forms.py index 6c01cfa..5772800 100644 --- a/rc_hip/repapp/forms.py +++ b/rc_hip/repapp/forms.py @@ -113,3 +113,22 @@ class RegisterGuest(forms.Form): max_length=200 ) accept_agb = HoneypotField(label="") + + +class CreateCafe(forms.Form): + """ + Form for creating new Repair-Cafés. + """ + location = forms.CharField( + label="Ort", + max_length=200, + help_text="Name des Orts, z.B. AWO." + ) + address = forms.CharField( + label="Adresse", + max_length=200, + help_text="Straße, Hausnummer und Ortsname." + ) + event_date = forms.DateField( + label="Veranstaltungsdatum" + ) diff --git a/rc_hip/repapp/templates/repapp/orga/create_cafe.html b/rc_hip/repapp/templates/repapp/orga/create_cafe.html new file mode 100644 index 0000000..738637c --- /dev/null +++ b/rc_hip/repapp/templates/repapp/orga/create_cafe.html @@ -0,0 +1,15 @@ +{% extends "repapp/base.html" %} +{% load crispy_forms_tags %} +{% block title %} + - Repair-Café anlegen +{% endblock title %} +{% block page_title %} + Repair-Café anlegen +{% endblock page_title %} +{% block content %} +
+{% endblock content %} diff --git a/rc_hip/repapp/urls.py b/rc_hip/repapp/urls.py index b2ee999..9071cb8 100644 --- a/rc_hip/repapp/urls.py +++ b/rc_hip/repapp/urls.py @@ -26,6 +26,7 @@ urlpatterns = [ views.one_time_login, name="one_time_login"), path("member/login/", views.member_login, name="member_login"), + path("orga/cafe/create", views.CreateCafeView.as_view(), name="create_cafe"), path("cron", views.cron, name="cron"), path("bootstrap", views.bootstrap, name="bootstrap"), path("process_mails", views.process_mails, name="process_mails"), diff --git a/rc_hip/repapp/views.py b/rc_hip/repapp/views.py index e3cfcd1..47b4b89 100644 --- a/rc_hip/repapp/views.py +++ b/rc_hip/repapp/views.py @@ -6,6 +6,7 @@ import random import string import time import os +import logging from hashlib import sha256 from django.template.loader import render_to_string from django.urls import reverse @@ -17,14 +18,18 @@ from django.shortcuts import get_object_or_404, render from django.http import HttpResponseRedirect, HttpResponse from django.core.exceptions import PermissionDenied from django.contrib.auth.decorators import login_required +from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth import authenticate, login from django.utils.timezone import now -from .forms import RegisterDevice, RegisterGuest +from .forms import RegisterDevice, RegisterGuest, CreateCafe from .models import (Cafe, Device, Guest, OneTimeLogin, CustomUser, Organisator, Reparateur) from . import mail_interface +logger = logging.getLogger(__name__) + + def send_one_time_login_mail(secret, mail, request): """ Send a mail with a one time login link. @@ -156,6 +161,14 @@ def is_member(user): return organisator or reparateur +def is_organisator(user): + """ + Test is a user is a Repair-Café organisator. + """ + organisator = Organisator.objects.filter(mail=user.email).first() + return organisator is not None + + def create_one_time_login(user, url) -> str: """ create_one_time_login creates a one time login object for guest user logins. @@ -401,6 +414,7 @@ def member_login(request): """ Login page for repair cafe members, using OIDC. """ + # TODO: create member login landing page return render( request, "repapp/member_login.html" @@ -462,3 +476,45 @@ def bootstrap(request): request, "repapp/bootstrap.html" ) + + +class CreateCafeView(LoginRequiredMixin, generic.edit.FormView): + """ + Organisator view for registering a new guest. + """ + # TODO: create test + login_url = reverse_lazy('member_login') + template_name = "repapp/orga/create_cafe.html" + form_class = CreateCafe + + def form_valid(self, form): + if not is_organisator(self.request.user): + raise PermissionDenied('Only accessible for organisator.') + + location = form.cleaned_data['location'] + address = form.cleaned_data['address'] + event_date = form.cleaned_data['event_date'] + + cafe = Cafe( + location=location, + address=address, + event_date=event_date, + ) + cafe.save() + + messages.add_message(self.request, messages.INFO, + 'Es wurde ein neues Repair-Café ' + f'am {cafe.event_date} angelegt') + + # TODO: redirect to orga main view + return HttpResponseRedirect( + reverse_lazy('index') + ) + + def get_context_data(self, **kwargs): + if not is_organisator(self.request.user): + logger.warning('Access violation: %s is no organisator!' % + self.request.user) + raise PermissionDenied('Only accessible for organisator.') + + return super(CreateCafeView, self).get_context_data(**kwargs)