Skip to content

Commit

Permalink
Merge pull request #323 from d120/server_error_fix
Browse files Browse the repository at this point in the history
Server error fix
  • Loading branch information
joachimschmidt557 authored Jan 3, 2025
2 parents cd0c9bf + b8f38b3 commit 00acb50
Show file tree
Hide file tree
Showing 32 changed files with 272 additions and 146 deletions.
2 changes: 1 addition & 1 deletion src/feedback/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ def save(self, *args, **kwargs):

def link_veranstalter(self): # @see http://stackoverflow.com/a/17948593
"""Gibt die URL für die Bestellunng durch den Veranstalter zurück"""
link_veranstalter = 'https://www.fachschaft.informatik.tu-darmstadt.de%s' % reverse('veranstalter-login')
link_veranstalter = 'https://www.fachschaft.informatik.tu-darmstadt.de%s' % reverse('feedback:veranstalter-login')
link_suffix_format = '?vid=%d&token=%s'
if self.pk is not None and self.access_token is not None:
return link_veranstalter + (link_suffix_format % (self.pk, self.access_token))
Expand Down
7 changes: 6 additions & 1 deletion src/feedback/templatetags/translate_url.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ def translate_url(context, language):
view = resolve(context['request'].path)
request_language = translation.get_language()
translation.activate(language)
url = reverse(view.url_name, args=view.args, kwargs=view.kwargs)

namespace = view.namespace
view_name = f"{namespace}:{view.url_name}" if namespace else view.url_name

url = reverse(view_name, args=view.args, kwargs=view.kwargs)

translation.activate(request_language)
return url
return ""
2 changes: 2 additions & 0 deletions src/feedback/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def suite():

LOGIN_END = f'/{get_language()}/intern/'
INDEX_END = f'/{get_language()}/intern/uebersicht/'
AUTH_END = f'/{get_language()}/intern/auth_user/'
TESTSERVER_BEGIN = ''
LOGIN_URL = TESTSERVER_BEGIN+LOGIN_END
INDEX_URL = TESTSERVER_BEGIN+INDEX_END
AUTH_URL = TESTSERVER_BEGIN+AUTH_END
2 changes: 1 addition & 1 deletion src/feedback/tests/test_views_intern.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ def test_post(self):
# ----- Vorschau: Check if the replacements are highlighted ----- #
color_span = '<span style="color:blue">{}</span>'
self.assertEqual(color_span.format('Grundlagen der Agrarphilosophie I'), response.context['veranstaltung'])
link_veranstalter = 'https://www.fachschaft.informatik.tu-darmstadt.de%s' % reverse('veranstalter-login')
link_veranstalter = 'https://www.fachschaft.informatik.tu-darmstadt.de%s' % reverse('feedback:veranstalter-login')
link_suffix_format = '?vid=%d&token=%s'
self.assertEqual(color_span.format(link_veranstalter + (link_suffix_format % (1337, '0123456789abcdef'))),
response.context['link_veranstalter'])
Expand Down
35 changes: 34 additions & 1 deletion src/feedback/tests/test_views_intern_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@
from feedback import tests
from feedback.models import Veranstaltung
from django.utils.translation import get_language

from django.contrib.auth.models import User
from django.urls import reverse

class InternAuthTest(NonSuTestMixin, TestCase):
def setUp(self):
super(InternAuthTest, self).setUp()
_, self.v = get_veranstaltung('vu')
self.username = 'supers1'
self.password = 'pw1'
self.user = User.objects.create_user(username=self.username, password=self.password)

def test_login_logged_in(self):
self.client.login(username='supers', password='pw')
Expand All @@ -33,6 +37,35 @@ def test_login_debug_auth(self):
self.assertEqual(response.status_code, 302)
self.assertEqual(response['Location'], tests.INDEX_URL)

def test_auth_user(self) :
response = self.client.get(tests.AUTH_URL)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'registration/login.html')

def test_auth_user_post_valid(self) :
response = self.client.post(tests.AUTH_URL, {'username':self.username, 'password':self.password})
self.assertRedirects(response, tests.LOGIN_URL, target_status_code=302)

login_required_url = reverse('feedback:intern-index')

response = self.client.get(login_required_url)
self.assertEqual(response.status_code, 302)

self.assertTrue(response['Location'].split('?')[0].endswith(tests.LOGIN_URL))
self.assertTrue(response['Location'].split('?')[1].endswith(login_required_url))

def test_auth_post_invalid_credentials(self) :
response = self.client.post(tests.AUTH_URL,{'username': self.username,'password': 'wrongpassword'})
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'registration/login.html')
self.assertContains(response, "Invalid Password or Username")

def test_auth_user_post_missing_data(self):
response = self.client.post(tests.AUTH_URL, {})
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'registration/login.html')
self.assertContains(response, "Invalid Password or Username")

def test_rechte_uebernehmen(self):
path = f'/{get_language()}/intern/rechte_uebernehmen/'
self.do_non_su_test(path)
Expand Down
14 changes: 5 additions & 9 deletions src/feedback/urls.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# coding=utf-8

from django.conf.urls import include
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

import feedback.views.public
import feedback.views.veranstalter
Expand All @@ -14,16 +13,13 @@
from django.urls import reverse_lazy, re_path
from django.conf import settings
from feedback.views.veranstalter import VeranstalterWizard
from django.utils.translation import get_language


if not settings.DEBUG:
default_redirect = '/feedback-new/'
else:
default_redirect = '/veranstalter/'
default_redirect = f'/{get_language()}/veranstalter/'

# allgemeine Views
urlpatterns = [
re_path(r'^$', feedback.views.redirect, {'redirect_to': default_redirect}),
re_path(r'^$', feedback.views.redirect, {'redirect_to': default_redirect}, name="default"),
]

# öffentliche Views
Expand Down Expand Up @@ -80,15 +76,15 @@
urlpatterns += [
re_path(r'^intern/rechte_uebernehmen/$', feedback.views.intern.auth.rechte_uebernehmen, name='rechte-uebernehmen'),
re_path(r'^intern/rechte_zuruecknehmen/$', feedback.views.intern.auth.rechte_zuruecknehmen, name='rechte_zuruecknehmen'),
re_path(r'^intern/auth_user/$', feedback.views.intern.auth.auth_user, name='auth-user'),
re_path(r'^intern/$', feedback.views.intern.auth.login, name='auth-login'),
]

# Logout
urlpatterns += [
re_path(r'^logout/$', django.contrib.auth.views.LogoutView.as_view(), {'next_page': reverse_lazy('public-results')}, name='logout'),
re_path(r'^logout/$', django.contrib.auth.views.LogoutView.as_view(), {'next_page': reverse_lazy('feedback:public-results')}, name='logout'),
]

urlpatterns += staticfiles_urlpatterns()

if settings.DEBUG:
# Ausschließlich in der Entwicklung nötig, damit statische Dateien (JS, CSS, Bilder...)
Expand Down
42 changes: 21 additions & 21 deletions src/feedback/views/intern/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def export_veranstaltungen(request):
try:
semester = Semester.objects.get(semester=request.POST['semester'])
except (Semester.DoesNotExist, KeyError):
return HttpResponseRedirect(reverse('export_veranstaltungen'))
return HttpResponseRedirect(reverse('feedback:export_veranstaltungen'))

ubung_export = False
if request.POST.get("xml_ubung", None) is not None:
Expand All @@ -112,19 +112,19 @@ def export_veranstaltungen(request):
'für Vorlesungen mit Übung vor!' % semester)
else:
messages.error(request, 'Für das ausgewählte Semester (%s) liegen keine Bestellungen vor!' % semester)
return HttpResponseRedirect(reverse('export_veranstaltungen'))
return HttpResponseRedirect(reverse('feedback:export_veranstaltungen'))

missing_verantwortlich = veranst.filter(verantwortlich=None)
if missing_verantwortlich.count() > 0:
txt = ', '.join([v.name for v in missing_verantwortlich])
messages.error(request, 'Für die folgenden Veranstaltungen ist kein Verantwortlicher eingetragen: %s' % txt)
return HttpResponseRedirect(reverse('export_veranstaltungen'))
return HttpResponseRedirect(reverse('feedback:export_veranstaltungen'))

missing_sprache = veranst.filter(sprache=None)
if missing_sprache.count() > 0:
txt = ', '.join([v.name for v in missing_sprache])
messages.error(request, 'Für die folgenden Veranstaltungen ist keine Sprache eingetragen: %s' % txt)
return HttpResponseRedirect(reverse('export_veranstaltungen'))
return HttpResponseRedirect(reverse('feedback:export_veranstaltungen'))

person_set = set()

Expand Down Expand Up @@ -190,12 +190,12 @@ def generate_letters(request):
try:
semester = Semester.objects.get(semester=request.POST['semester'])
except (Semester.DoesNotExist, KeyError):
return HttpResponseRedirect(reverse('generate_letters'))
return HttpResponseRedirect(reverse('feedback:generate_letters'))

try:
vorlage = request.POST['vorlage']
except (Semester.DoesNotExist, KeyError):
return HttpResponseRedirect(reverse('generate_letters'))
return HttpResponseRedirect(reverse('feedback:generate_letters'))

if vorlage == 'Anschreiben':
latexpath = settings.LATEX_PATH
Expand All @@ -209,7 +209,7 @@ def generate_letters(request):
try:
abgabedatum = request.POST['erhebungswoche'].replace('\\', '')
except KeyError:
return HttpResponseRedirect(reverse('generate_letters'))
return HttpResponseRedirect(reverse('feedback:generate_letters'))
with open(datefilename, 'w') as f:
f.write(abgabedatum)

Expand All @@ -228,14 +228,14 @@ def generate_letters(request):
if not veranst.count():
messages.error(request, 'Für das ausgewählte Semester (%s) liegen '
'keine Bestellungen vor oder die Mindesteilnehmeranzahl ist zu hoch!' % semester)
return HttpResponseRedirect(reverse('generate_letters'))
return HttpResponseRedirect(reverse('feedback:generate_letters'))

lines = []
for v in veranst:
if not v.verantwortlich.printable():
messages.error(request,
mark_safe(f"Der Veranstalter {v.verantwortlich.full_name} ist nicht druckbar, da das Personenprofil nicht vollständig ist. Du kannst das unter <a href={reverse('admin:feedback_person_change', args=(v.verantwortlich.id,))}>hier</a> beheben."))
return HttpResponseRedirect(reverse('generate_letters'))
return HttpResponseRedirect(reverse('feedback:generate_letters'))
eva_id = v.get_barcode_number()
empfaenger = str(v.verantwortlich.full_name())
line = '\\adrentry{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}{%s}\n' % (
Expand Down Expand Up @@ -300,7 +300,7 @@ def get_demo_context(request):
:return: RequestContext, String, String
"""
color_span = '<span style="color:blue">{}</span>'
link_veranstalter = 'https://www.fachschaft.informatik.tu-darmstadt.de%s' % reverse('veranstalter-login')
link_veranstalter = 'https://www.fachschaft.informatik.tu-darmstadt.de%s' % reverse('feedback:veranstalter-login')
link_suffix_format = '?vid=%d&token=%s'
demo_context = RequestContext(request, {
'veranstaltung': color_span.format('Grundlagen der Agrarphilosophie I'),
Expand Down Expand Up @@ -367,7 +367,7 @@ def sendmail(request):
return render(request, 'intern/sendmail.html', data)

except (Semester.DoesNotExist, KeyError):
return HttpResponseRedirect(reverse('sendmail'))
return HttpResponseRedirect(reverse('feedback:sendmail'))

data['semester_selected'] = semester
data['subject_rendered'] = "Evaluation: %s" % data['subject']
Expand All @@ -379,7 +379,7 @@ def sendmail(request):
data['body'] = vorlage.body

except (Mailvorlage.DoesNotExist, KeyError, ValueError):
return HttpResponseRedirect(reverse('sendmail'))
return HttpResponseRedirect(reverse('feedback:sendmail'))
return render(request, 'intern/sendmail.html', data)

veranstaltungen = get_relevant_veranstaltungen(data['recipient'], semester)
Expand Down Expand Up @@ -445,7 +445,7 @@ def sendmail(request):
'%d Veranstaltungen wurden erfolgreich, samt Tutoren, benachrichtigt.' % (len(mails) - 1))
else:
messages.success(request, '%d Veranstaltungen wurden erfolgreich benachrichtigt.' % (len(mails) - 1))
return HttpResponseRedirect(reverse('intern-index'))
return HttpResponseRedirect(reverse('feedback:intern-index'))

return render(request, 'intern/sendmail.html', data)

Expand All @@ -459,7 +459,7 @@ def import_ergebnisse(request):
try:
semester = Semester.objects.get(semester=request.POST['semester'])
except (Semester.DoesNotExist, KeyError):
return HttpResponseRedirect(reverse('import_ergebnisse'))
return HttpResponseRedirect(reverse('feedback:import_ergebnisse'))

form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
Expand All @@ -480,7 +480,7 @@ def import_ergebnisse(request):
messages.warning(request, w)
for e in errors:
messages.error(request, e)
return HttpResponseRedirect(reverse('sync_ergebnisse'))
return HttpResponseRedirect(reverse('feedback:sync_ergebnisse'))
else:
messages.error(request, 'Fehler beim Upload')
else:
Expand All @@ -500,7 +500,7 @@ def sync_ergebnisse(request):
try:
semester = Semester.objects.get(semester=request.POST['semester'])
except (Semester.DoesNotExist, KeyError):
return HttpResponseRedirect(reverse('sync_ergebnisse'))
return HttpResponseRedirect(reverse('feedback:sync_ergebnisse'))

fragebogen = get_model('Fragebogen', semester)
ergebnis = get_model('Ergebnis', semester)
Expand Down Expand Up @@ -542,7 +542,7 @@ def sync_ergebnisse(request):
messages.warning(request, 'Für das %s liegen keine Ergebnisse vor.' % semester)
else:
messages.success(request, 'Das Ranking für das %s wurde erfolgreich berechnet.' % semester)
return HttpResponseRedirect(reverse('sync_ergebnisse'))
return HttpResponseRedirect(reverse('feedback:sync_ergebnisse'))


@user_passes_test(lambda u: u.is_superuser)
Expand Down Expand Up @@ -586,18 +586,18 @@ def form_valid(self, form):
return super(CloseOrderFormView, self).form_valid(form)

def form_invalid(self, form):
return HttpResponseRedirect(reverse('intern-index'))
return HttpResponseRedirect(reverse('feedback:intern-index'))

def get_queryset(self):
try:
veranstaltungen = Veranstaltung.objects.filter(semester=Semester.current())
return veranstaltungen
except (Veranstaltung.DoesNotExist, KeyError):
messages.warning(self.request, 'Keine passenden Veranstaltungen für das aktuelle Semester gefunden.')
return HttpResponseRedirect(reverse('intern-index'))
return HttpResponseRedirect(reverse('feedback:intern-index'))

def get_success_url(self):
return reverse('intern-index')
return reverse('feedback:intern-index')

def test_func(self):
return self.request.user.is_superuser
Expand Down Expand Up @@ -662,7 +662,7 @@ def done(self, form_list, **kwargs):
self.request,
'{} Veranstaltungen wurden erfolgreich benachrichtigt.'.format(
len(mails)))
return HttpResponseRedirect(reverse('intern-index'))
return HttpResponseRedirect(reverse('feedback:intern-index'))

def get_template_names(self):
return [self.template_name] if self.steps.step0 != 3 else [
Expand Down
30 changes: 26 additions & 4 deletions src/feedback/views/intern/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def rechte_uebernehmen(request):
request.session['vid'] = v
request.session['veranstaltung'] = str(veranst)

return HttpResponseRedirect(reverse('veranstalter-index'))
return HttpResponseRedirect(reverse('feedback:veranstalter-index'))

except KeyError:
pass
Expand All @@ -48,12 +48,31 @@ def rechte_zuruecknehmen(request):
u = User.objects.get(id=uid)
user = auth.authenticate(reset=True, user=u)
auth.login(request, user, backend='feedback.auth.TakeoverBackend')
return HttpResponseRedirect(reverse('intern-index'))
return HttpResponseRedirect(reverse('feedback:intern-index'))
# Redirect to intern.index view to get a clear session
except KeyError:
return HttpResponseRedirect(reverse('intern-index'))
return HttpResponseRedirect(reverse('feedback:intern-index'))


def auth_user(request) :
if request.method == "POST" :
username = request.POST.get("username")
password = request.POST.get("password")

user = auth.authenticate(username=username, password=password)

if user is None :
messages.error(request, "Invalid Password or Username")
return render(request, 'registration/login.html')
else :
auth.login(request, user)
return HttpResponseRedirect(reverse('feedback:auth-login'))

elif request.method == "GET" and not request.user.is_authenticated :
return render(request, 'registration/login.html')

return HttpResponseRedirect(reverse('feedback:auth-login'))

@require_safe
def login(request):
if settings.DEBUG and not request.user.is_superuser:
Expand All @@ -63,6 +82,9 @@ def login(request):
response['WWW-Authenticate'] = 'Basic realm="Feedback"'
return response

if not settings.DEBUG and not request.user.is_authenticated :
return HttpResponseRedirect(reverse('feedback:auth-user'))

# Apache fordert User zum Login mit FS-Account auf, von daher muss hier nur noch weitergeleitet
# werden.
return HttpResponseRedirect(reverse('intern-index'))
return HttpResponseRedirect(reverse('feedback:intern-index'))
Loading

0 comments on commit 00acb50

Please sign in to comment.