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
This commit is contained in:
parent
db4fd70c92
commit
9802a6345c
20 changed files with 391 additions and 443 deletions
|
|
@ -19,7 +19,9 @@
|
||||||
"tabindex",
|
"tabindex",
|
||||||
"onetimelogin",
|
"onetimelogin",
|
||||||
"Ammeldelink",
|
"Ammeldelink",
|
||||||
"orga"
|
"orga",
|
||||||
|
"repa",
|
||||||
|
"organisators"
|
||||||
],
|
],
|
||||||
"ignoreWords": [],
|
"ignoreWords": [],
|
||||||
"import": []
|
"import": []
|
||||||
|
|
|
||||||
|
|
@ -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"
|
OIDC_OP_USER_ENDPOINT = "https://sso.makes-hacks-hip.de/realms/Makes-Hacks-Hip/protocol/openid-connect/userinfo"
|
||||||
|
|
||||||
if DEBUG:
|
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/"
|
LOGOUT_REDIRECT_URL = "http://127.0.0.1:8000/"
|
||||||
else:
|
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/"
|
LOGOUT_REDIRECT_URL = "https://anmeldung.repaircafe-hilpoltstein.de/"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
"fields": {
|
"fields": {
|
||||||
"location": "Haus Einstein' (beim Gymnasium)",
|
"location": "Haus Einstein' (beim Gymnasium)",
|
||||||
"address": "Patersholzer Weg 19, Hilpoltstein",
|
"address": "Patersholzer Weg 19, Hilpoltstein",
|
||||||
"event_date": "2023-05-13"
|
"event_date": "2024-05-13"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -19,13 +19,13 @@ class HoneypotWidget(forms.TextInput):
|
||||||
def __init__(self, attrs=None, html_comment=False, *args, **kwargs):
|
def __init__(self, attrs=None, html_comment=False, *args, **kwargs):
|
||||||
self.html_comment = html_comment
|
self.html_comment = html_comment
|
||||||
super(HoneypotWidget, self).__init__(attrs, *args, **kwargs)
|
super(HoneypotWidget, self).__init__(attrs, *args, **kwargs)
|
||||||
if not 'class' in self.attrs:
|
if 'class' not in self.attrs:
|
||||||
self.attrs['style'] = 'display:none'
|
self.attrs['style'] = 'display:none'
|
||||||
|
|
||||||
def render(self, *args, **kwargs):
|
def render(self, *args, **kwargs):
|
||||||
value = super(HoneypotWidget, self).render(*args, **kwargs)
|
value = super(HoneypotWidget, self).render(*args, **kwargs)
|
||||||
if self.html_comment:
|
if self.html_comment:
|
||||||
value = '<!-- %s -->' % value
|
value = f'<!-- {value} -->'
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -113,22 +113,3 @@ class RegisterGuest(forms.Form):
|
||||||
max_length=200
|
max_length=200
|
||||||
)
|
)
|
||||||
accept_agb = HoneypotField(label="")
|
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"
|
|
||||||
)
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import random
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
|
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.common.by import By
|
||||||
from selenium.webdriver.chrome.webdriver import WebDriver
|
from selenium.webdriver.chrome.webdriver import WebDriver
|
||||||
from selenium.webdriver import ActionChains, Keys
|
from selenium.webdriver import ActionChains, Keys
|
||||||
|
|
@ -202,11 +201,3 @@ class WorkflowTests(StaticLiveServerTestCase):
|
||||||
self.assertTrue("Test Hersteller" in self.selenium.page_source)
|
self.assertTrue("Test Hersteller" in self.selenium.page_source)
|
||||||
self.assertTrue("/device/" in self.selenium.current_url)
|
self.assertTrue("/device/" in self.selenium.current_url)
|
||||||
time.sleep(1)
|
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)
|
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,10 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="{% url 'login' %}" class="nav-link">Gast Login</a>
|
<a href="{% url 'login' %}" class="nav-link">Gast Login</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
|
||||||
<a href="{% url 'member_login' %}" class="nav-link">Mitglieder Login</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<li class="nav-item">
|
||||||
|
<a href="{% url 'member' %}" class="nav-link">Mitglieder</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@
|
||||||
<a href="{% url 'login' %}" class="nav-link">Gast Anmeldung</a>
|
<a href="{% url 'login' %}" class="nav-link">Gast Anmeldung</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a href="{% url 'member_login' %}" class="nav-link">Mitglieder Anmeldung</a>
|
<a href="{% url 'member' %}" class="nav-link">Mitglieder</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -2,326 +2,35 @@
|
||||||
{% block title %}
|
{% block title %}
|
||||||
- Repair-Cafés
|
- Repair-Cafés
|
||||||
{% endblock title %}
|
{% endblock title %}
|
||||||
{% block head %}
|
|
||||||
<style>
|
|
||||||
@font-face {
|
|
||||||
font-family:'Source Sans Pro';
|
|
||||||
font-style:normal;
|
|
||||||
font-weight:300;
|
|
||||||
src:url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-300.eot');
|
|
||||||
/* IE9 Compat Modes */
|
|
||||||
src:local('Source Sans Pro Light'), local('SourceSansPro-Light'),
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-300.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-300.woff2') format('woff2'), /* Super Modern Browsers */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-300.woff') format('woff'), /* Modern Browsers */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-300.ttf') format('truetype'), /* Safari, Android, iOS */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-300.svg#SourceSansPro') format('svg');/* Legacy iOS */;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family:'Source Sans Pro';
|
|
||||||
font-style:normal;
|
|
||||||
font-weight:400;
|
|
||||||
src:url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-regular.eot');
|
|
||||||
/* IE9 Compat Modes */
|
|
||||||
src:local('Source Sans Pro Regular'), local('SourceSansPro-Regular'),
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-regular.woff') format('woff'), /* Modern Browsers */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-regular.svg#SourceSansPro') format('svg');/* Legacy iOS */;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family:'Source Sans Pro';
|
|
||||||
font-style:normal;
|
|
||||||
font-weight:700;
|
|
||||||
src:url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-700.eot');
|
|
||||||
/* IE9 Compat Modes */
|
|
||||||
src:local('Source Sans Pro Bold'), local('SourceSansPro-Bold'),
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-700.woff2') format('woff2'), /* Super Modern Browsers */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-700.woff') format('woff'), /* Modern Browsers */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */
|
|
||||||
url('https://www.repaircafe-hilpoltstein.de/fileadmin/repaircafe-hilpoltstein/default/templates/fonts/source-sans-pro-v11-latin-700.svg#SourceSansPro') format('svg');/* Legacy iOS */;
|
|
||||||
}
|
|
||||||
@media all{
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.frame > :last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.frame {
|
|
||||||
position: relative;
|
|
||||||
padding-top: 2rem;
|
|
||||||
padding-bottom: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 576px){
|
|
||||||
.frame {
|
|
||||||
padding-top: 2.5rem;
|
|
||||||
padding-bottom: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px){
|
|
||||||
.frame {
|
|
||||||
padding-top: 3rem;
|
|
||||||
padding-bottom: 3rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 992px){
|
|
||||||
.frame {
|
|
||||||
padding-top: 3.5rem;
|
|
||||||
padding-bottom: 3.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1200px){
|
|
||||||
.frame {
|
|
||||||
padding-top: 3.5rem;
|
|
||||||
padding-bottom: 3.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all{
|
|
||||||
.frame-space-before-none {
|
|
||||||
margin-top: 0rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.frame-space-after-none {
|
|
||||||
margin-bottom: 0rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 1200px){
|
|
||||||
.frame {
|
|
||||||
padding-top: 2.5rem;
|
|
||||||
padding-bottom: 2.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all{
|
|
||||||
.col-md-8 {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 20px;
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px){
|
|
||||||
.col-md-8 {
|
|
||||||
flex: 0 0 66.6666666667%;
|
|
||||||
max-width: 66.6666666667%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 992px){
|
|
||||||
.col-md-8 {
|
|
||||||
padding-right: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all{
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
margin-right: -20px;
|
|
||||||
margin-left: -20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
width: 100%;
|
|
||||||
padding-right: 20px;
|
|
||||||
padding-left: 20px;
|
|
||||||
margin-right: auto;
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 576px){
|
|
||||||
.container {
|
|
||||||
max-width: 540px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 768px){
|
|
||||||
.container {
|
|
||||||
max-width: 720px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 992px){
|
|
||||||
.container {
|
|
||||||
max-width: 960px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 1200px){
|
|
||||||
.container {
|
|
||||||
max-width: 1140px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all{
|
|
||||||
.section {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 1200px){
|
|
||||||
.section {
|
|
||||||
padding-top: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media all{
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: "Source Sans Pro", sans-serif;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 400;
|
|
||||||
line-height: 1.5;
|
|
||||||
color: #2b2b2b;
|
|
||||||
text-align: left;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
font-family: sans-serif;
|
|
||||||
line-height: 1.15;
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.news-list-view {
|
|
||||||
padding-right: 20px;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
*,:before,:after {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
:selection {
|
|
||||||
background-color: darkred;
|
|
||||||
}
|
|
||||||
|
|
||||||
.article {
|
|
||||||
padding: 30px 0;
|
|
||||||
border-bottom: 2px solid #cccccc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.article:last-child {
|
|
||||||
border-bottom: 2px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.article.event {
|
|
||||||
padding: 0 0 30px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dtdate {
|
|
||||||
font-size: 21px;
|
|
||||||
color: #FFFFFF;
|
|
||||||
background: darkred;
|
|
||||||
padding: 0 5px;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.article.event .ort {
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 19px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.teaser-text {
|
|
||||||
position: relative;
|
|
||||||
padding-bottom: 30px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.article.event .teaser-text {
|
|
||||||
padding-top: 20px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
strong {
|
|
||||||
font-weight: bolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: darkred;
|
|
||||||
text-decoration: none;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: darkblue;
|
|
||||||
border-bottom: 1px solid;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
color: #FFFFFF;
|
|
||||||
text-decoration: underline;
|
|
||||||
background: darkred;
|
|
||||||
}
|
|
||||||
|
|
||||||
a:hover {
|
|
||||||
background: darkblue;
|
|
||||||
color: #ffffff!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
{% endblock head %}
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
Anmeldung
|
Anmeldung
|
||||||
{% endblock page_title %}
|
{% endblock page_title %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1 class="mt-2">Repair-Café auswählen</h1>
|
<table class="table">
|
||||||
<hr class="mt-0 mb-4">
|
<thead>
|
||||||
<ul class="list-group">
|
<tr>
|
||||||
|
<th scope="col">Datum</th>
|
||||||
|
<th scope="col">Ort</th>
|
||||||
|
<th scope="col">Adresse</th>
|
||||||
|
<th scope="col">Gerät anmelden</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
{% for cafe in object_list %}
|
{% for cafe in object_list %}
|
||||||
<li class="list-group-item">
|
<tr>
|
||||||
<div class="news-list-view eventhome snipcss-aSNzE" id="news-container-82">
|
<td>{{ cafe.event_date|date:"l" }}, {{ cafe.event_date|date }}</td>
|
||||||
<div class="rc-date">
|
<td>{{ cafe.location }}</td>
|
||||||
<div class="article event rc-date "
|
<td>{{ cafe.address }}</td>
|
||||||
itemscope="itemscope"
|
<td>
|
||||||
itemtype="http://schema.org/Article">
|
<a href="{% url 'register_device' cafe.pk %}"
|
||||||
<div class="dtdate">
|
class="btn btn-primary register_link">Gerät anmelden</a>
|
||||||
<time itemprop="datePublished" datetime="13.05.2023">
|
</td>
|
||||||
{{ cafe.event_date|date:"l" }}, {{ cafe.event_date|date }}, 14.00 - 17.00 Uhr
|
</tr>
|
||||||
</time>
|
|
||||||
</div>
|
|
||||||
<div class="ort">
|
|
||||||
{{ cafe.location }}
|
|
||||||
<br>
|
|
||||||
{{ cafe.address }}
|
|
||||||
</div>
|
|
||||||
<div class="teaser-text">
|
|
||||||
<div itemprop="description">
|
|
||||||
<p>
|
|
||||||
<strong>
|
|
||||||
Nur per Voranmeldung.
|
|
||||||
<a class="register_link" href="{% url 'register_device' cafe.id %}">Zum Anmeldeformular</a>
|
|
||||||
</strong>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<li class="list-group-item">Es gibt keine geplanten Repair-Cafés.</li>
|
<tr>
|
||||||
|
<td colspan="4">Es sind keine Repair-Cafés angelegt.</td>
|
||||||
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</tbody>
|
||||||
|
</table>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
||||||
|
|
@ -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 %}
|
|
||||||
<div>
|
|
||||||
{% if user.is_authenticated %}
|
|
||||||
<p>Angemeldeter Benutzer: {{ user.email }}</p>
|
|
||||||
<form action="{% url 'oidc_logout' %}" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<button type="submit" class="btn btn-primary">Abmelden</button>
|
|
||||||
</form>
|
|
||||||
{% else %}
|
|
||||||
<a class="login_link" href="{% url 'oidc_authentication_init' %}">Anmelden mit Makes-Hacks-Hip</a>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% endblock content %}
|
|
||||||
45
rc_hip/repapp/templates/repapp/orga/cafe.html
Normal file
45
rc_hip/repapp/templates/repapp/orga/cafe.html
Normal file
|
|
@ -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 %}
|
||||||
|
<p>
|
||||||
|
<a href="{% url 'create_cafe' %}" class="btn btn-primary">Neues Repair-Cafés anlegen</a>
|
||||||
|
<a href="javascript:history.back()" class="btn btn-primary">Zurück</a>
|
||||||
|
</p>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">ID</th>
|
||||||
|
<th scope="col">Datum</th>
|
||||||
|
<th scope="col">Ort</th>
|
||||||
|
<th scope="col">Adresse</th>
|
||||||
|
<th scope="col">Bearbeiten</th>
|
||||||
|
<th scope="col">Löschen</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for cafe in object_list %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{{ cafe.pk }}</th>
|
||||||
|
<td>{{ cafe.event_date|date:"l" }}, {{ cafe.event_date|date }}</td>
|
||||||
|
<td>{{ cafe.location }}</td>
|
||||||
|
<td>{{ cafe.address }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'edit_cafe' cafe.pk %}" class="btn btn-primary">Bearbeiten</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'delete_cafe' cafe.pk %}" class="btn btn-danger">Löschen</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">Es sind keine Repair-Cafés angelegt.</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock content %}
|
||||||
16
rc_hip/repapp/templates/repapp/orga/delete_cafe.html
Normal file
16
rc_hip/repapp/templates/repapp/orga/delete_cafe.html
Normal file
|
|
@ -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 %}
|
||||||
|
<form action="{% url 'delete_cafe' cafe.id %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<p>Soll das Repair-Café am {{ cafe.event_date|date:"l" }}, {{ cafe.event_date|date }} wirklich gelöscht werden?</p>
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button type="submit" class="btn btn-primary submit_button">Löschen</button>
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
||||||
15
rc_hip/repapp/templates/repapp/orga/edit_cafe.html
Normal file
15
rc_hip/repapp/templates/repapp/orga/edit_cafe.html
Normal file
|
|
@ -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 %}
|
||||||
|
<form action="{% url 'edit_cafe' cafe.id %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button type="submit" class="btn btn-primary submit_button">Aktualisieren</button>
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
||||||
15
rc_hip/repapp/templates/repapp/orga/edit_guest.html
Normal file
15
rc_hip/repapp/templates/repapp/orga/edit_guest.html
Normal file
|
|
@ -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 %}
|
||||||
|
<form action="{% url 'edit_guest' guest.id %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button type="submit" class="btn btn-primary submit_button">Aktualisieren</button>
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
||||||
44
rc_hip/repapp/templates/repapp/orga/guest.html
Normal file
44
rc_hip/repapp/templates/repapp/orga/guest.html
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
{% extends "repapp/base.html" %}
|
||||||
|
{% block title %}
|
||||||
|
- Gäste
|
||||||
|
{% endblock title %}
|
||||||
|
{% block page_title %}
|
||||||
|
Gäste
|
||||||
|
{% endblock page_title %}
|
||||||
|
{% block content %}
|
||||||
|
<p>
|
||||||
|
<a href="{% url 'create_guest' %}" class="btn btn-primary">Neuen Gast anlegen</a>
|
||||||
|
<a href="javascript:history.back()" class="btn btn-primary">Zurück</a>
|
||||||
|
</p>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">ID</th>
|
||||||
|
<th scope="col">Name</th>
|
||||||
|
<th scope="col">Telefon</th>
|
||||||
|
<th scope="col">Wohnort</th>
|
||||||
|
<th scope="col">eMail Adresse</th>
|
||||||
|
<th scope="col">Bearbeiten</th>
|
||||||
|
<th scope="col">Löschen</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for guest in object_list %}
|
||||||
|
<tr>
|
||||||
|
<th scope="row">{{ guest.pk }}</th>
|
||||||
|
<td>{{ guest.name }}</td>
|
||||||
|
<td>{{ guest.phone }}</td>
|
||||||
|
<td>{{ guest.residence }}</td>
|
||||||
|
<td>{{ guest.mail }}</td>
|
||||||
|
<td>
|
||||||
|
<a href="{% url 'edit_guest' guest.pk %}" class="btn btn-primary">Bearbeiten</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% empty %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="4">Es sind keine Gäste verfügbar.</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock content %}
|
||||||
27
rc_hip/repapp/templates/repapp/orga/main.html
Normal file
27
rc_hip/repapp/templates/repapp/orga/main.html
Normal file
|
|
@ -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 %}
|
||||||
|
<p>
|
||||||
|
<a href="{% url 'cafe' %}" class="btn btn-primary">Repair-Cafés</a>
|
||||||
|
<a href="{% url 'guest' %}" class="btn btn-primary">Gäste</a>
|
||||||
|
</p>
|
||||||
|
<hr class="mt-0 mb-4">
|
||||||
|
<h1 class="mt-2">Repair-Cafés</h1>
|
||||||
|
<a href="{% url 'create_cafe' %}" class="btn btn-primary">Neues Repair-Café anlegen</a>
|
||||||
|
// TODO: Button nächstes Repair-Café
|
||||||
|
<hr class="mt-0 mb-4">
|
||||||
|
<h1 class="mt-2">Geräte</h1>
|
||||||
|
// TODO: Liste mit neuen Geräten
|
||||||
|
<hr class="mt-0 mb-4">
|
||||||
|
<h1 class="mt-2">Rückfragen</h1>
|
||||||
|
// TODO: Liste mit Antworten auf Rückfragen
|
||||||
|
<hr class="mt-0 mb-4">
|
||||||
|
<h1 class="mt-2">Nachrichten</h1>
|
||||||
|
// TODO: Liste mit neuen Nachrichten
|
||||||
|
{% endblock content %}
|
||||||
16
rc_hip/repapp/templates/repapp/orga/select_role.html
Normal file
16
rc_hip/repapp/templates/repapp/orga/select_role.html
Normal file
|
|
@ -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 %}
|
||||||
|
<p>
|
||||||
|
<a href="{% url 'orga' %}" class="btn btn-primary">Weiter als Organisator</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a href="{% url 'repa' %}" class="btn btn-primary">Weiter als Reparateur</a>
|
||||||
|
</p>
|
||||||
|
{% endblock content %}
|
||||||
10
rc_hip/repapp/templates/repapp/repa/main.html
Normal file
10
rc_hip/repapp/templates/repapp/repa/main.html
Normal file
|
|
@ -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 %}
|
||||||
|
|
@ -271,27 +271,6 @@ class ViewsTest(TestCase):
|
||||||
response, 'type="text" name="accept_agb" style="display:none"')
|
response, 'type="text" name="accept_agb" style="display:none"')
|
||||||
self.assertContains(response, 'csrfmiddlewaretoken')
|
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):
|
def test_send_one_time_login_mail(self):
|
||||||
"""
|
"""
|
||||||
Test that a mail is sent with the right link included.
|
Test that a mail is sent with the right link included.
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,17 @@ urlpatterns = [
|
||||||
views.profile, name="guest_profile"),
|
views.profile, name="guest_profile"),
|
||||||
path("onetimelogin/<str:secret>/",
|
path("onetimelogin/<str:secret>/",
|
||||||
views.one_time_login, name="one_time_login"),
|
views.one_time_login, name="one_time_login"),
|
||||||
path("member/login/",
|
path("member/", views.member, name="member"),
|
||||||
views.member_login, name="member_login"),
|
path("orga/select/", views.select_role, name="select_role"),
|
||||||
path("orga/cafe/create", views.CreateCafeView.as_view(), name="create_cafe"),
|
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/<int:pk>/edit", views.CafeUpdateView.as_view(), name="edit_cafe"),
|
||||||
|
path("cafe/<int:pk>/delete",
|
||||||
|
views.CafeDeleteView.as_view(), name="delete_cafe"),
|
||||||
|
path("guest/", views.GuestView.as_view(), name="guest"),
|
||||||
|
path("guest/<int:pk>/edit", views.GuestUpdateView.as_view(), name="edit_guest"),
|
||||||
path("cron", views.cron, name="cron"),
|
path("cron", views.cron, name="cron"),
|
||||||
path("bootstrap", views.bootstrap, name="bootstrap"),
|
path("bootstrap", views.bootstrap, name="bootstrap"),
|
||||||
path("process_mails", views.process_mails, name="process_mails"),
|
path("process_mails", views.process_mails, name="process_mails"),
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,10 @@ from django.shortcuts import get_object_or_404, render
|
||||||
from django.http import HttpResponseRedirect, HttpResponse
|
from django.http import HttpResponseRedirect, HttpResponse
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
from django.contrib.auth.decorators import login_required
|
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.contrib.auth import authenticate, login
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
from .forms import RegisterDevice, RegisterGuest, CreateCafe
|
from .forms import RegisterDevice, RegisterGuest
|
||||||
from .models import (Cafe, Device, Guest, OneTimeLogin,
|
from .models import (Cafe, Device, Guest, OneTimeLogin,
|
||||||
CustomUser, Organisator, Reparateur)
|
CustomUser, Organisator, Reparateur)
|
||||||
from . import mail_interface
|
from . import mail_interface
|
||||||
|
|
@ -45,7 +45,7 @@ def send_one_time_login_mail(secret, mail, request):
|
||||||
'link': url,
|
'link': url,
|
||||||
})
|
})
|
||||||
|
|
||||||
ok = send_mail(
|
send_ok = send_mail(
|
||||||
subject=subject,
|
subject=subject,
|
||||||
message=text,
|
message=text,
|
||||||
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
||||||
|
|
@ -54,7 +54,7 @@ def send_one_time_login_mail(secret, mail, request):
|
||||||
html_message=html
|
html_message=html
|
||||||
)
|
)
|
||||||
|
|
||||||
if ok > 0:
|
if send_ok > 0:
|
||||||
messages.add_message(request, messages.INFO,
|
messages.add_message(request, messages.INFO,
|
||||||
'Sie haben einen neuen Login per eMail erhalten.')
|
'Sie haben einen neuen Login per eMail erhalten.')
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ def send_guest_account_mail(guest, password, request):
|
||||||
'password': password,
|
'password': password,
|
||||||
})
|
})
|
||||||
|
|
||||||
ok = send_mail(
|
send_ok = send_mail(
|
||||||
subject=subject,
|
subject=subject,
|
||||||
message=text,
|
message=text,
|
||||||
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
from_email=os.getenv("DJANGO_SENDER_ADDRESS", ""),
|
||||||
|
|
@ -147,7 +147,7 @@ def send_guest_account_mail(guest, password, request):
|
||||||
html_message=html
|
html_message=html
|
||||||
)
|
)
|
||||||
|
|
||||||
if ok > 0:
|
if send_ok > 0:
|
||||||
messages.add_message(request, messages.INFO,
|
messages.add_message(request, messages.INFO,
|
||||||
'Sie haben ihre Benutzerdaten per eMail erhalten.')
|
'Sie haben ihre Benutzerdaten per eMail erhalten.')
|
||||||
|
|
||||||
|
|
@ -169,6 +169,14 @@ def is_organisator(user):
|
||||||
return organisator is not None
|
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:
|
def create_one_time_login(user, url) -> str:
|
||||||
"""
|
"""
|
||||||
create_one_time_login creates a one time login object for guest user logins.
|
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.
|
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(
|
return render(
|
||||||
request,
|
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):
|
def cron(request):
|
||||||
"""
|
"""
|
||||||
View to trigger automated regular tasks.
|
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
|
# TODO: create test
|
||||||
login_url = reverse_lazy('member_login')
|
login_url = reverse_lazy('member')
|
||||||
template_name = "repapp/orga/create_cafe.html"
|
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):
|
def test_func(self):
|
||||||
if not is_organisator(self.request.user):
|
return 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(
|
class CafeUpdateView(LoginRequiredMixin, UserPassesTestMixin, generic.edit.UpdateView):
|
||||||
location=location,
|
"""
|
||||||
address=address,
|
Organisator view for edit a Repair-Café.
|
||||||
event_date=event_date,
|
"""
|
||||||
)
|
# TODO: create test
|
||||||
cafe.save()
|
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,
|
def test_func(self):
|
||||||
'Es wurde ein neues Repair-Café '
|
logger.debug('User passes test: user: %s, result: %s.',
|
||||||
f'am {cafe.event_date} angelegt')
|
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):
|
class CafeDeleteView(LoginRequiredMixin, UserPassesTestMixin, generic.edit.DeleteView):
|
||||||
if not is_organisator(self.request.user):
|
"""
|
||||||
logger.warning('Access violation: %s is no organisator!' %
|
Organisator view for edit a Repair-Café.
|
||||||
self.request.user)
|
"""
|
||||||
raise PermissionDenied('Only accessible for organisator.')
|
# 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)
|
||||||
|
|
|
||||||
Reference in a new issue