From 9802a6345ccd33b8bb363f14a8bbe1a03ac52bea Mon Sep 17 00:00:00 2001 From: Tom Irgang Date: Thu, 18 May 2023 09:18:58 +0200 Subject: [PATCH] start orga area Orga login: - Remove not needed login page for members - Add landing page after member login with redirect to correct area - Add selection page if member is orga and repa - Add orga main menu - Add cafe CRUD pages - Add guest list and edit view --- cspell.json | 4 +- rc_hip/rc_hip/settings.py | 4 +- rc_hip/repapp/fixtures/cafe-data.json | 2 +- rc_hip/repapp/forms.py | 23 +- rc_hip/repapp/live_tests.py | 9 - rc_hip/repapp/templates/repapp/base.html | 6 +- rc_hip/repapp/templates/repapp/bootstrap.html | 2 +- rc_hip/repapp/templates/repapp/index.html | 345 ++---------------- .../repapp/templates/repapp/member_login.html | 25 -- rc_hip/repapp/templates/repapp/orga/cafe.html | 45 +++ .../templates/repapp/orga/delete_cafe.html | 16 + .../templates/repapp/orga/edit_cafe.html | 15 + .../templates/repapp/orga/edit_guest.html | 15 + .../repapp/templates/repapp/orga/guest.html | 44 +++ rc_hip/repapp/templates/repapp/orga/main.html | 27 ++ .../templates/repapp/orga/select_role.html | 16 + rc_hip/repapp/templates/repapp/repa/main.html | 10 + rc_hip/repapp/tests.py | 21 -- rc_hip/repapp/urls.py | 14 +- rc_hip/repapp/views.py | 191 ++++++++-- 20 files changed, 391 insertions(+), 443 deletions(-) delete mode 100644 rc_hip/repapp/templates/repapp/member_login.html create mode 100644 rc_hip/repapp/templates/repapp/orga/cafe.html create mode 100644 rc_hip/repapp/templates/repapp/orga/delete_cafe.html create mode 100644 rc_hip/repapp/templates/repapp/orga/edit_cafe.html create mode 100644 rc_hip/repapp/templates/repapp/orga/edit_guest.html create mode 100644 rc_hip/repapp/templates/repapp/orga/guest.html create mode 100644 rc_hip/repapp/templates/repapp/orga/main.html create mode 100644 rc_hip/repapp/templates/repapp/orga/select_role.html create mode 100644 rc_hip/repapp/templates/repapp/repa/main.html diff --git a/cspell.json b/cspell.json index 27501ea..4b33dee 100644 --- a/cspell.json +++ b/cspell.json @@ -19,7 +19,9 @@ "tabindex", "onetimelogin", "Ammeldelink", - "orga" + "orga", + "repa", + "organisators" ], "ignoreWords": [], "import": [] diff --git a/rc_hip/rc_hip/settings.py b/rc_hip/rc_hip/settings.py index 81459fe..78d64cf 100644 --- a/rc_hip/rc_hip/settings.py +++ b/rc_hip/rc_hip/settings.py @@ -179,10 +179,10 @@ OIDC_OP_TOKEN_ENDPOINT = "https://sso.makes-hacks-hip.de/realms/Makes-Hacks-Hip/ OIDC_OP_USER_ENDPOINT = "https://sso.makes-hacks-hip.de/realms/Makes-Hacks-Hip/protocol/openid-connect/userinfo" if DEBUG: - LOGIN_REDIRECT_URL = "http://127.0.0.1:8000/" + LOGIN_REDIRECT_URL = "http://127.0.0.1:8000/member" LOGOUT_REDIRECT_URL = "http://127.0.0.1:8000/" else: - LOGIN_REDIRECT_URL = "https://anmeldung.repaircafe-hilpoltstein.de/" + LOGIN_REDIRECT_URL = "https://anmeldung.repaircafe-hilpoltstein.de/member" LOGOUT_REDIRECT_URL = "https://anmeldung.repaircafe-hilpoltstein.de/" diff --git a/rc_hip/repapp/fixtures/cafe-data.json b/rc_hip/repapp/fixtures/cafe-data.json index da8e763..59ff18a 100644 --- a/rc_hip/repapp/fixtures/cafe-data.json +++ b/rc_hip/repapp/fixtures/cafe-data.json @@ -5,7 +5,7 @@ "fields": { "location": "Haus Einstein' (beim Gymnasium)", "address": "Patersholzer Weg 19, Hilpoltstein", - "event_date": "2023-05-13" + "event_date": "2024-05-13" } }, { diff --git a/rc_hip/repapp/forms.py b/rc_hip/repapp/forms.py index 5772800..cc8650a 100644 --- a/rc_hip/repapp/forms.py +++ b/rc_hip/repapp/forms.py @@ -19,13 +19,13 @@ class HoneypotWidget(forms.TextInput): def __init__(self, attrs=None, html_comment=False, *args, **kwargs): self.html_comment = html_comment super(HoneypotWidget, self).__init__(attrs, *args, **kwargs) - if not 'class' in self.attrs: + if 'class' not in self.attrs: self.attrs['style'] = 'display:none' def render(self, *args, **kwargs): value = super(HoneypotWidget, self).render(*args, **kwargs) if self.html_comment: - value = '' % value + value = f'' return value @@ -113,22 +113,3 @@ 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/live_tests.py b/rc_hip/repapp/live_tests.py index 4ed713f..f030013 100644 --- a/rc_hip/repapp/live_tests.py +++ b/rc_hip/repapp/live_tests.py @@ -5,7 +5,6 @@ import random from pathlib import Path from hashlib import sha256 from django.contrib.staticfiles.testing import StaticLiveServerTestCase -from django.contrib.auth import get_user_model from selenium.webdriver.common.by import By from selenium.webdriver.chrome.webdriver import WebDriver from selenium.webdriver import ActionChains, Keys @@ -202,11 +201,3 @@ class WorkflowTests(StaticLiveServerTestCase): self.assertTrue("Test Hersteller" in self.selenium.page_source) self.assertTrue("/device/" in self.selenium.current_url) time.sleep(1) - - def test_member_login(self): - self.selenium.get( - f"{self.live_server_url}/member/login/") - time.sleep(1) - self.selenium.find_element(By.CLASS_NAME, 'login_link').click() - time.sleep(1) - self.assertTrue('sso.makes-hacks-hip.de' in self.selenium.current_url) diff --git a/rc_hip/repapp/templates/repapp/base.html b/rc_hip/repapp/templates/repapp/base.html index f23cb89..91436ab 100644 --- a/rc_hip/repapp/templates/repapp/base.html +++ b/rc_hip/repapp/templates/repapp/base.html @@ -43,10 +43,10 @@ - {% endif %} + diff --git a/rc_hip/repapp/templates/repapp/bootstrap.html b/rc_hip/repapp/templates/repapp/bootstrap.html index 1777fbc..192d367 100644 --- a/rc_hip/repapp/templates/repapp/bootstrap.html +++ b/rc_hip/repapp/templates/repapp/bootstrap.html @@ -45,7 +45,7 @@ Gast Anmeldung {% endif %} diff --git a/rc_hip/repapp/templates/repapp/index.html b/rc_hip/repapp/templates/repapp/index.html index 8421850..b1bfb2c 100644 --- a/rc_hip/repapp/templates/repapp/index.html +++ b/rc_hip/repapp/templates/repapp/index.html @@ -2,326 +2,35 @@ {% block title %} - Repair-Cafés {% endblock title %} -{% block head %} - -{% endblock head %} {% block page_title %} Anmeldung {% endblock page_title %} {% block content %} -

Repair-Café auswählen

-
- + + + + + + + + + + + {% for cafe in object_list %} + + + + + + + {% empty %} + + + + {% endfor %} + +
DatumOrtAdresseGerät anmelden
{{ cafe.event_date|date:"l" }}, {{ cafe.event_date|date }}{{ cafe.location }}{{ cafe.address }} + Gerät anmelden +
Es sind keine Repair-Cafés angelegt.
{% endblock content %} diff --git a/rc_hip/repapp/templates/repapp/member_login.html b/rc_hip/repapp/templates/repapp/member_login.html deleted file mode 100644 index a3a4585..0000000 --- a/rc_hip/repapp/templates/repapp/member_login.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends "repapp/base.html" %} -{% block title %} - Mitarbeiter Anmeldung -{% endblock title %} -{% block page_title %} - Mitarbeiter - {% if user.is_authenticated %} - Anmelden - {% else %} - Abmelden - {% endif %} -{% endblock page_title %} -{% block content %} -
- {% if user.is_authenticated %} -

Angemeldeter Benutzer: {{ user.email }}

-
- {% csrf_token %} - -
- {% else %} - - {% endif %} -
-{% endblock content %} diff --git a/rc_hip/repapp/templates/repapp/orga/cafe.html b/rc_hip/repapp/templates/repapp/orga/cafe.html new file mode 100644 index 0000000..0db2d30 --- /dev/null +++ b/rc_hip/repapp/templates/repapp/orga/cafe.html @@ -0,0 +1,45 @@ +{% extends "repapp/base.html" %} +{% block title %} + - Repair-Cafés +{% endblock title %} +{% block page_title %} + Repair-Cafés +{% endblock page_title %} +{% block content %} +

+ Neues Repair-Cafés anlegen + Zurück +

+ + + + + + + + + + + + + {% for cafe in object_list %} + + + + + + + + + {% empty %} + + + + {% endfor %} + +
IDDatumOrtAdresseBearbeitenLöschen
{{ cafe.pk }}{{ cafe.event_date|date:"l" }}, {{ cafe.event_date|date }}{{ cafe.location }}{{ cafe.address }} + Bearbeiten + + Löschen +
Es sind keine Repair-Cafés angelegt.
+{% endblock content %} diff --git a/rc_hip/repapp/templates/repapp/orga/delete_cafe.html b/rc_hip/repapp/templates/repapp/orga/delete_cafe.html new file mode 100644 index 0000000..3617efd --- /dev/null +++ b/rc_hip/repapp/templates/repapp/orga/delete_cafe.html @@ -0,0 +1,16 @@ +{% 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 %} +
+ {% csrf_token %} +

Soll das Repair-Café am {{ cafe.event_date|date:"l" }}, {{ cafe.event_date|date }} wirklich gelöscht werden?

+ {{ form|crispy }} + +
+{% endblock content %} diff --git a/rc_hip/repapp/templates/repapp/orga/edit_cafe.html b/rc_hip/repapp/templates/repapp/orga/edit_cafe.html new file mode 100644 index 0000000..b7da85f --- /dev/null +++ b/rc_hip/repapp/templates/repapp/orga/edit_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 %} +
+ {% csrf_token %} + {{ form|crispy }} + +
+{% endblock content %} diff --git a/rc_hip/repapp/templates/repapp/orga/edit_guest.html b/rc_hip/repapp/templates/repapp/orga/edit_guest.html new file mode 100644 index 0000000..3b3edc1 --- /dev/null +++ b/rc_hip/repapp/templates/repapp/orga/edit_guest.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 %} +
+ {% csrf_token %} + {{ form|crispy }} + +
+{% endblock content %} diff --git a/rc_hip/repapp/templates/repapp/orga/guest.html b/rc_hip/repapp/templates/repapp/orga/guest.html new file mode 100644 index 0000000..a587a6b --- /dev/null +++ b/rc_hip/repapp/templates/repapp/orga/guest.html @@ -0,0 +1,44 @@ +{% extends "repapp/base.html" %} +{% block title %} + - Gäste +{% endblock title %} +{% block page_title %} + Gäste +{% endblock page_title %} +{% block content %} +

+ Neuen Gast anlegen + Zurück +

+ + + + + + + + + + + + + + {% for guest in object_list %} + + + + + + + + + {% empty %} + + + + {% endfor %} + +
IDNameTelefonWohnorteMail AdresseBearbeitenLöschen
{{ guest.pk }}{{ guest.name }}{{ guest.phone }}{{ guest.residence }}{{ guest.mail }} + Bearbeiten +
Es sind keine Gäste verfügbar.
+{% endblock content %} diff --git a/rc_hip/repapp/templates/repapp/orga/main.html b/rc_hip/repapp/templates/repapp/orga/main.html new file mode 100644 index 0000000..788764c --- /dev/null +++ b/rc_hip/repapp/templates/repapp/orga/main.html @@ -0,0 +1,27 @@ +{% extends "repapp/base.html" %} +{% load crispy_forms_tags %} +{% block title %} + - Organisation +{% endblock title %} +{% block page_title %} + Organisation +{% endblock page_title %} +{% block content %} +

+ Repair-Cafés + Gäste +

+
+

Repair-Cafés

+ Neues Repair-Café anlegen + // TODO: Button nächstes Repair-Café +
+

Geräte

+ // TODO: Liste mit neuen Geräten +
+

Rückfragen

+ // TODO: Liste mit Antworten auf Rückfragen +
+

Nachrichten

+ // TODO: Liste mit neuen Nachrichten +{% endblock content %} diff --git a/rc_hip/repapp/templates/repapp/orga/select_role.html b/rc_hip/repapp/templates/repapp/orga/select_role.html new file mode 100644 index 0000000..2933f68 --- /dev/null +++ b/rc_hip/repapp/templates/repapp/orga/select_role.html @@ -0,0 +1,16 @@ +{% extends "repapp/base.html" %} +{% load crispy_forms_tags %} +{% block title %} + - Organisation +{% endblock title %} +{% block page_title %} + Organisation +{% endblock page_title %} +{% block content %} +

+ Weiter als Organisator +

+

+ Weiter als Reparateur +

+{% endblock content %} diff --git a/rc_hip/repapp/templates/repapp/repa/main.html b/rc_hip/repapp/templates/repapp/repa/main.html new file mode 100644 index 0000000..179e8d5 --- /dev/null +++ b/rc_hip/repapp/templates/repapp/repa/main.html @@ -0,0 +1,10 @@ +{% extends "repapp/base.html" %} +{% load crispy_forms_tags %} +{% block title %} + - Reparateur +{% endblock title %} +{% block page_title %} + Reparateur +{% endblock page_title %} +{% block content %} +{% endblock content %} diff --git a/rc_hip/repapp/tests.py b/rc_hip/repapp/tests.py index 3d05dde..7312652 100644 --- a/rc_hip/repapp/tests.py +++ b/rc_hip/repapp/tests.py @@ -271,27 +271,6 @@ class ViewsTest(TestCase): response, 'type="text" name="accept_agb" style="display:none"') self.assertContains(response, 'csrfmiddlewaretoken') - def test_member_login(self): - """ - Test member login view - """ - client = Client(enforce_csrf_checks=True) - response = client.get(reverse('member_login')) - - self.assertEqual(response.status_code, 200) - - # ensure OIDC link is displayed - self.assertContains(response, "Anmelden mit Makes-Hacks-Hip") - - client.login(username="testuser@example.com", password="aTestPassword") - response = client.get(reverse('member_login')) - self.assertEqual(response.status_code, 200) - - # ensure logout button is displayed - self.assertContains(response, "Abmelden") - # ensure user is displayed - self.assertContains(response, "testuser@example.com") - def test_send_one_time_login_mail(self): """ Test that a mail is sent with the right link included. diff --git a/rc_hip/repapp/urls.py b/rc_hip/repapp/urls.py index 9071cb8..ea75c77 100644 --- a/rc_hip/repapp/urls.py +++ b/rc_hip/repapp/urls.py @@ -24,9 +24,17 @@ urlpatterns = [ views.profile, name="guest_profile"), path("onetimelogin//", 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("member/", views.member, name="member"), + path("orga/select/", views.select_role, name="select_role"), + path("orga/", views.orga, name="orga"), + path("repa/", views.repa, name="repa"), + path("cafe/", views.CafeView.as_view(), name="cafe"), + path("cafe/create", views.CafeCreateView.as_view(), name="create_cafe"), + path("cafe//edit", views.CafeUpdateView.as_view(), name="edit_cafe"), + path("cafe//delete", + views.CafeDeleteView.as_view(), name="delete_cafe"), + path("guest/", views.GuestView.as_view(), name="guest"), + path("guest//edit", views.GuestUpdateView.as_view(), name="edit_guest"), 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 47b4b89..692dcf4 100644 --- a/rc_hip/repapp/views.py +++ b/rc_hip/repapp/views.py @@ -18,10 +18,10 @@ 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.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.auth import authenticate, login from django.utils.timezone import now -from .forms import RegisterDevice, RegisterGuest, CreateCafe +from .forms import RegisterDevice, RegisterGuest from .models import (Cafe, Device, Guest, OneTimeLogin, CustomUser, Organisator, Reparateur) from . import mail_interface @@ -45,7 +45,7 @@ def send_one_time_login_mail(secret, mail, request): 'link': url, }) - ok = send_mail( + send_ok = send_mail( subject=subject, message=text, from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""), @@ -54,7 +54,7 @@ def send_one_time_login_mail(secret, mail, request): html_message=html ) - if ok > 0: + if send_ok > 0: messages.add_message(request, messages.INFO, 'Sie haben einen neuen Login per eMail erhalten.') @@ -138,7 +138,7 @@ def send_guest_account_mail(guest, password, request): 'password': password, }) - ok = send_mail( + send_ok = send_mail( subject=subject, message=text, from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""), @@ -147,7 +147,7 @@ def send_guest_account_mail(guest, password, request): html_message=html ) - if ok > 0: + if send_ok > 0: messages.add_message(request, messages.INFO, 'Sie haben ihre Benutzerdaten per eMail erhalten.') @@ -169,6 +169,14 @@ def is_organisator(user): return organisator is not None +def is_reparateur(user): + """ + Test is a user is a Repair-Café reparateur. + """ + reparateur = Reparateur.objects.filter(mail=user.email).first() + return reparateur 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. @@ -410,17 +418,92 @@ def profile(request): ) -def member_login(request): +def member(request): """ Login page for repair cafe members, using OIDC. """ - # TODO: create member login landing page + # TODO: test + logger.debug('Member-View: User: %s', str(request.user)) + if request.user.is_anonymous or not is_member(request.user): + return HttpResponseRedirect(reverse_lazy('oidc_authentication_init')) + + if is_organisator(request.user) and is_reparateur(request.user): + return HttpResponseRedirect(reverse_lazy('select_role')) + + if is_organisator(request.user): + return HttpResponseRedirect(reverse_lazy('orga')) + + if is_reparateur(request.user): + return HttpResponseRedirect(reverse_lazy('repa')) + + logger.warning('User %s is no member!', str(request.user)) + raise PermissionDenied('No member!') + + +@login_required(login_url=reverse_lazy('member')) +def orga(request): + """ + Landing page for organisators. + """ + # TODO: test + if not is_organisator(request.user): + logger.warning('The user %s is no organisator!', str(request.user)) + raise PermissionDenied('Not organisator!') + return render( request, - "repapp/member_login.html" + "repapp/orga/main.html" ) +@login_required(login_url=reverse_lazy('member')) +def select_role(request): + """ + Landing page for organisators. + """ + # TODO: test + if not is_organisator(request.user): + logger.warning('The user %s is no organisator!', str(request.user)) + raise PermissionDenied('Not organisator!') + + if not is_reparateur(request.user): + logger.warning('The user %s is no reparateur!', str(request.user)) + raise PermissionDenied('Not reparateur!') + + return render( + request, + "repapp/orga/select_role.html" + ) + + +@login_required(login_url=reverse_lazy('member')) +def repa(request): + """ + Organisator main menu. + """ + # TODO: test + if not is_reparateur(request.user): + logger.warning('The user %s is no reparateur!', str(request.user)) + raise PermissionDenied('Not reparateur!') + + return render( + request, + "repapp/repa/main.html" + ) + + +class CafeView(LoginRequiredMixin, generic.ListView): + """ + List of all Repair-Cafés. + """ + # TODO: test + login_url = reverse_lazy('member') + template_name = "repapp/orga/cafe.html" + + def get_queryset(self): + return Cafe.objects.all() + + def cron(request): """ View to trigger automated regular tasks. @@ -478,43 +561,75 @@ def bootstrap(request): ) -class CreateCafeView(LoginRequiredMixin, generic.edit.FormView): +class CafeCreateView(LoginRequiredMixin, UserPassesTestMixin, generic.edit.CreateView): """ - Organisator view for registering a new guest. + Organisator view for creating a new Repair-Café. """ # TODO: create test - login_url = reverse_lazy('member_login') + login_url = reverse_lazy('member') template_name = "repapp/orga/create_cafe.html" - form_class = CreateCafe + model = Cafe + fields = ['event_date', 'location', 'address'] + success_url = reverse_lazy('cafe') - def form_valid(self, form): - if not is_organisator(self.request.user): - raise PermissionDenied('Only accessible for organisator.') + def test_func(self): + return is_organisator(self.request.user) - 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() +class CafeUpdateView(LoginRequiredMixin, UserPassesTestMixin, generic.edit.UpdateView): + """ + Organisator view for edit a Repair-Café. + """ + # TODO: create test + login_url = reverse_lazy('member') + template_name = "repapp/orga/edit_cafe.html" + model = Cafe + fields = ['event_date', 'location', 'address'] + success_url = reverse_lazy('cafe') - messages.add_message(self.request, messages.INFO, - 'Es wurde ein neues Repair-Café ' - f'am {cafe.event_date} angelegt') + def test_func(self): + logger.debug('User passes test: user: %s, result: %s.', + self.request.user, is_organisator(self.request.user)) + return is_organisator(self.request.user) - # 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.') +class CafeDeleteView(LoginRequiredMixin, UserPassesTestMixin, generic.edit.DeleteView): + """ + Organisator view for edit a Repair-Café. + """ + # TODO: create test + login_url = reverse_lazy('member') + template_name = "repapp/orga/delete_cafe.html" + model = Cafe + success_url = reverse_lazy('cafe') - return super(CreateCafeView, self).get_context_data(**kwargs) + def test_func(self): + logger.debug('User passes test: user: %s, result: %s.', + self.request.user, is_organisator(self.request.user)) + return is_organisator(self.request.user) + + +class GuestView(LoginRequiredMixin, generic.ListView): + """ + List of all Repair-Cafés. + """ + # TODO: test + login_url = reverse_lazy('member') + template_name = "repapp/orga/guest.html" + + def get_queryset(self): + return Guest.objects.all() + + +class GuestUpdateView(LoginRequiredMixin, UserPassesTestMixin, generic.edit.UpdateView): + """ + Organisator view for edit a guest. + """ + # TODO: create test + login_url = reverse_lazy('member') + template_name = "repapp/orga/edit_guest.html" + model = Guest + success_url = reverse_lazy('guest') + + def test_func(self): + return is_organisator(self.request.user)