From 5e09c50fa2c0efe0895cce1db81f13c37daadf5c Mon Sep 17 00:00:00 2001
From: Tom Teichler <tom.teichler@teckids.org>
Date: Mon, 13 Sep 2021 21:32:32 +0200
Subject: [PATCH] server sync

---
 ticdesk/settings.py                           |  6 +-
 ticdesk/templates/ticdesk/base.html           |  2 +-
 ticdesk_account/forms.py                      |  4 +-
 .../locale/en/LC_MESSAGES/django.po           |  2 +-
 ticdesk_account/models.py                     | 86 ++++++++++++-------
 ticdesk_account/util.py                       |  8 +-
 ticdesk_account/views.py                      | 14 +--
 ticdesk_org/templates/ticdesk_org/corona.tex  | 32 +++++++
 .../templates/ticdesk_org/persons.html        |  4 +-
 ticdesk_org/views.py                          |  2 +-
 10 files changed, 105 insertions(+), 55 deletions(-)
 create mode 100644 ticdesk_org/templates/ticdesk_org/corona.tex

diff --git a/ticdesk/settings.py b/ticdesk/settings.py
index 1e1876a..eafd942 100644
--- a/ticdesk/settings.py
+++ b/ticdesk/settings.py
@@ -103,8 +103,8 @@ MIDDLEWARE = [
 ]
 
 CRON_CLASSES = [
-    'ticdesk_account.cron.CleanGroups',
-    'ticdesk_account.cron.CleanPersons',
+#    'ticdesk_account.cron.CleanGroups',
+#    'ticdesk_account.cron.CleanPersons',
     'ticdesk_account.cron.BirthdayMails',
     'django_cron.cron.FailedRunsNotificationCronJob'
 ]
@@ -140,7 +140,7 @@ DATABASES = {
     'default': {
         'CONN_MAX_AGE': 0,
         'ENGINE': 'django.db.backends.postgresql_psycopg2',
-        'HOST': 'db.teckids.org',
+        'HOST': 'db-vip.teckids.org',
         'NAME': 'ticdesk',
         'PASSWORD': POSTGRES_PASSWORD,
         'PORT': '5432',
diff --git a/ticdesk/templates/ticdesk/base.html b/ticdesk/templates/ticdesk/base.html
index e055871..ee20e71 100644
--- a/ticdesk/templates/ticdesk/base.html
+++ b/ticdesk/templates/ticdesk/base.html
@@ -14,7 +14,7 @@
  <nav class="navbar navbar-light bg-light navbar-expand-md">
   {% get_current_language as LANGUAGE_CODE %}
   <a class="navbar-brand" href="{% url "index" %}"><img
-  src="https://www.teckids.org/static/logo_{{ LANGUAGE_CODE }}.png" alt="Teckids-Logo" id="logo" /></a>
+  src="https://www.teckids.org/images/logo.png" alt="Teckids-Logo" id="logo" /></a>
 
   <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-main">
    {% fa 'fa-align-justify' %}
diff --git a/ticdesk_account/forms.py b/ticdesk_account/forms.py
index 86b737f..47f8857 100644
--- a/ticdesk_account/forms.py
+++ b/ticdesk_account/forms.py
@@ -119,9 +119,9 @@ class RegisterFormBase(forms.Form):
 
     # Additional fields
     accept_tos = forms.BooleanField(label=_('Ich habe die Nutzungsbedingungen gelesen und stimme ihnen zu.'), help_text=_(
-        'Bitte lies die <a href="https://www.teckids.org/kleingedrucktes/nutzungsbedingungen/">Nutzungsbedingungen</a> aufmerksam durch!'))
+        'Bitte lies die <a href="https://www.teckids.org/pages/nutzungsbedingungen_datenschutz.html">Nutzungsbedingungen</a> aufmerksam durch!'))
     accept_data = forms.BooleanField(label=_('Ich habe die Hinweise zur Verarbeitung meiner Daten gelesen und stimme diesen zu.'), help_text=_(
-        'Ich bin mit der in den <a href="https://www.teckids.org/kleingedrucktes/nutzungsbedingungen/">Nutzungsbedingungen</a> erklärten Verarbeitung meiner Daten einverstanden und alle angegebenen Daten sind richtig. Falls ich jünger als 16 Jahre bin, sind meine Eltern hiermit ebenfalls einverstanden und ich kann dies, auf Anfrage, nachweisen (z.B. durch Herstellung eines Kontakts zu meinen Eltern).'))
+        'Ich bin mit der in den <a href="https://www.teckids.org/pages/nutzungsbedingungen_datenschutz.html">Nutzungsbedingungen</a> erklärten Verarbeitung meiner Daten einverstanden und alle angegebenen Daten sind richtig. Falls ich jünger als 16 Jahre bin, sind meine Eltern hiermit ebenfalls einverstanden und ich kann dies, auf Anfrage, nachweisen (z.B. durch Herstellung eines Kontakts zu meinen Eltern).'))
 
     def clean(self):
         # Ensure both passwords are identical
diff --git a/ticdesk_account/locale/en/LC_MESSAGES/django.po b/ticdesk_account/locale/en/LC_MESSAGES/django.po
index 1b39de0..7e0b41f 100644
--- a/ticdesk_account/locale/en/LC_MESSAGES/django.po
+++ b/ticdesk_account/locale/en/LC_MESSAGES/django.po
@@ -209,7 +209,7 @@ msgid "Diese E-Mail-Adresse ist bereits belegt!"
 msgstr "This mail address is already taken!"
 
 #: models.py:147
-msgid "Allgemeine Teams"
+msgid "Allegemeine Teams"
 msgstr ""
 
 #: models.py:149
diff --git a/ticdesk_account/models.py b/ticdesk_account/models.py
index 19e8c03..6a807bd 100644
--- a/ticdesk_account/models.py
+++ b/ticdesk_account/models.py
@@ -5,7 +5,9 @@ import os
 import pytz
 from random import shuffle
 import string
+from time import sleep
 
+import django.db
 from django.conf import settings
 from django.contrib.staticfiles import finders
 from django.core.exceptions import ObjectDoesNotExist
@@ -204,7 +206,7 @@ class TeckidsGroup(ldapdb.models.Model, TeckidsLdapMixin):
     @property
     def group_type(self):
         if self.cn.startswith('team-'):
-            return ('team', _('Allgemeine Teams'))
+            return ('team', _('Allegemeine Teams'))
         elif self.cn.startswith('thema-'):
             return ('topic', _('Thementeams'))
         elif self.cn.startswith('news-'):
@@ -226,7 +228,7 @@ class TeckidsPerson(ldapdb.models.Model, TeckidsLdapMixin):
 
     base_dn = 'ou=People,dc=teckids,dc=org'
     object_classes = ['inetOrgPerson', 'organizationalPerson', 'teckidsPerson',
-                      'posixAccount', 'shadowAccount', 'inetLocalMailRecipient']
+                      'posixAccount', 'shadowAccount', 'inetLocalMailRecipient', 'krb5KDCEntry', 'krb5Principal']
 
     # Name
     cn = CharField(db_column='cn', max_length=200,
@@ -313,11 +315,20 @@ class TeckidsPerson(ldapdb.models.Model, TeckidsLdapMixin):
     members_share_info = BooleanField(
         db_column='teckidsMembersShareInfo', default=False)
 
+    krb_princ_name = CharField(db_column="krb5PrincipalName")
+
+    krb_princ_version = IntegerField(db_column="krb5KeyVersionNumber", default=1)
+
+    krb_kdc_flags = IntegerField(db_column="krb5KDCFlags", default=126)
+
     def clean(self):
         # Set default cn if not given
         if not self.cn:
             self.cn = "%s %s" % (self.given_name, self.sn)
 
+        if not self.krb_princ_name:
+            self.krb_princ_name = f"{self.uid}@TECKIDS.ORG"
+
         # Set default home directory if not given
         if not self.home_directory:
             self.home_directory = "/home/%s" % self.uid
@@ -328,8 +339,8 @@ class TeckidsPerson(ldapdb.models.Model, TeckidsLdapMixin):
                 '-uid_number')[0].uid_number + 1
 
         # Activate SASL passthrough if principal exists
-        if TeckidsKrbPrinc.objects.filter(princ_name='%s@TECKIDS.ORG' % self.uid):
-            self.set_sasl_passthrough()
+#        if TeckidsKrbPrinc.objects.filter(princ_name='%s@TECKIDS.ORG' % self.uid):
+#            self.set_sasl_passthrough()
 
         # Update coordinates if postal address is given and changed since last save
         if self.home_postal_address and (self.uid not in address_cache or
@@ -411,32 +422,40 @@ class TeckidsPerson(ldapdb.models.Model, TeckidsLdapMixin):
         # Generate temporary password
         # We set the real password later by changing the temporary password to the correct one
         #  through Kerberos, as to leverage passwd's password complexity checking.
-        temp_password = list(string.ascii_letters)
-        shuffle(temp_password)
-        temp_password = ''.join(temp_password)
+#        temp_password = list(string.ascii_letters)
+#        shuffle(temp_password)
+#        temp_password = ''.join(temp_password)
 
         # Set the password in LDAP
-        person.user_password = ssha(temp_password)
-        person.save()
+#        person.user_password = ssha(temp_password)
+#        person.save()
 
         # Do PAM authentication for the new user
         # On ticdesk.teckids.org, this will trigger pam_migrate to create the Kerberos principal
-        p_conv = pam()
-        res = p_conv.authenticate(
-            '%s%s' % (uid, settings.TICDESK_USER_INITIAL_SUFFIX), temp_password, service='ticdesk')
-        if res:
+#        res = False
+#        for tries in range(6):
+#            p_conv = pam()
+#            res = p_conv.authenticate(
+#                '%s%s' % (uid, settings.TICDESK_USER_INITIAL_SUFFIX), temp_password, service='ticdesk')
+#            if res:
+#                break
+#            else:
+#                sleep(5)
+        res = django.db.connections.all()[1].client.connection.connection.passwd_s(person.dn, oldpw=None, newpw=password)
+        person.user_password = "{SASL}%s@TECKIDS.ORG" % person.uid
+        if not res:
             # Now set the real password
-            res = change_kerberos_password(uid, temp_password, password)
+#            res = change_kerberos_password(uid, temp_password, password)
 
-            if not res[0]:
+#            if not res[0]:
                 # passwd failed - remove the new user to not confuse systems!
-                person.delete()
-                return res
-        else:
+#                person.delete()
+#                return res
+#        else:
             # PAM failed - remove the new user to not confuse systems!
             person.delete()
             return (False, _('Anlegen des Benutzers fehlgeschlagen. Bitte versuche es später erneut!'))
-
+#
         # Save again, which will activate SASL passthrough in clean()
         person.save()
 
@@ -444,10 +463,10 @@ class TeckidsPerson(ldapdb.models.Model, TeckidsLdapMixin):
 
     def delete(self):
         # Look for Kerberos principal with asme name and delete if existing
-        principals = TeckidsKrbPrinc.objects.filter(
-            princ_name='%s@TECKIDS.ORG' % self.uid)
-        if principals.count() > 0:
-            principals.delete()
+#        principals = TeckidsKrbPrinc.objects.filter(
+#            princ_name='%s@TECKIDS.ORG' % self.uid)
+#        if principals.count() > 0:
+#            principals.delete()
 
         return super(TeckidsPerson, self).delete()
 
@@ -499,13 +518,14 @@ class TeckidsPerson(ldapdb.models.Model, TeckidsLdapMixin):
         return self._get_objects('guardians', TeckidsParent)
 
 
-class TeckidsKrbPrinc(ldapdb.models.Model):
-    class Meta:
-        managed = False
-        app_label = 'ticdesk_account'
-
-    base_dn = 'ou=KerberosPrincipals,dc=teckids,dc=org'
-    object_classes = ['account', 'krb5Principal', 'krb5KDCEntry']
-
-    # Only need the principal name as all we do is validating existence
-    princ_name = CharField(db_column='krb5PrincipalName', max_length=100)
+#class TeckidsKrbPrinc(ldapdb.models.Model):
+#    class Meta:
+#        managed = False
+#        app_label = 'ticdesk_account'
+#
+#    base_dn = 'ou=KerberosPrincipals,dc=teckids,dc=org'
+#    object_classes = ['account', 'krb5Principal', 'krb5KDCEntry']
+#
+#    # Only need the principal name as all we do is validating existence
+#    princ_name = CharField(db_column='krb5PrincipalName', max_length=100)
+#
diff --git a/ticdesk_account/util.py b/ticdesk_account/util.py
index ba14be1..8113ba7 100644
--- a/ticdesk_account/util.py
+++ b/ticdesk_account/util.py
@@ -12,7 +12,6 @@ import requests
 def change_kerberos_password(uid, old_password, new_password):
     # Trigger PAM once to ensure password is correct
     ret = pam().authenticate(uid, old_password, service='ticdesk')
-
     if ret:
         # Do expect conversation with passwd as logged-in user
         child = pexpect.spawn('su -c passwd %s' % uid)
@@ -44,13 +43,8 @@ def change_kerberos_password(uid, old_password, new_password):
         elif ret == 3:
             return (False,
                     _('Das Passwort enthält nicht genug verschiedene Zeichen.'))
-        # Try new password
-        ret = pam().authenticate(uid, new_password, service='ticdesk')
 
-        if ret:
-            return (True, None)
-        return (False,
-                _('Unerwarteter Fehler beim Ändern des Passworts. Bitte versuche es in ein paar Minuten noch einmal.'))
+        return (True, None)
     return (False, _('Das angegebene alte Passwort ist falsch!'))
 
 
diff --git a/ticdesk_account/views.py b/ticdesk_account/views.py
index a8c9617..89fd28b 100644
--- a/ticdesk_account/views.py
+++ b/ticdesk_account/views.py
@@ -1,3 +1,4 @@
+import django.db
 from datetime import datetime
 from django.conf import settings
 from django.contrib import auth
@@ -64,15 +65,16 @@ def change_password(request):
     if request.method == 'POST':
         chpw_form = ChPwForm(request.POST)
         if chpw_form.is_valid():
-            ret = change_kerberos_password(
-                request.user.username,
-                chpw_form.cleaned_data['password_old'],
-                chpw_form.cleaned_data['password_new'])
+            dn = TeckidsPerson.objects.get(uid=request.user.username).dn
+            ret = django.db.connections.all()[1].client.connection.connection.passwd_s(
+                dn,
+                oldpw=chpw_form.cleaned_data['password_old'],
+                newpw=chpw_form.cleaned_data['password_new'])
 
-            if ret[0]:
+            if ret:
                 context['success'] = True
             else:
-                context['error'] = ret[1]
+                context['error'] = ret
 
     context['chpw_form'] = chpw_form
     return render(request, 'ticdesk_account/change_password.html', context)
diff --git a/ticdesk_org/templates/ticdesk_org/corona.tex b/ticdesk_org/templates/ticdesk_org/corona.tex
new file mode 100644
index 0000000..d1d5857
--- /dev/null
+++ b/ticdesk_org/templates/ticdesk_org/corona.tex
@@ -0,0 +1,32 @@
+{% load i18n latex_helpers %}
+{% autoescape off %}
+\documentclass{teckidsproto}
+
+\usepackage{tabu}
+\usepackage{longtable}
+\geometry{landscape,left=.5cm,right=.5cm}
+
+\usepackage[export]{adjustbox}
+
+\keineseitenzahlenbeginn
+\begin{document}
+ \teckidshead{ {{ group.display_name }} \dash {% blocktrans %}Corona{% endblocktrans %}}
+
+ \begin{longtabu} to \linewidth {|l|l|l|l|X[l]|X[l]|}
+\hline\rowfont\bfseries Nachname & Vorname & Adresse & Telefon & Ankunft & Abfahrt \\\hline
+\endhead
+{% for person in persons|dictsort:"sn" %}
+ \nohyphens{{ person.sn|embrace }} &
+ \nohyphens{{ person.given_name|embrace }} &
+ \nohyphens{{ person.home_postal_address|embrace }} &
+ {% if person.is_member %}
+   \nohyphens{{ person.mobile|embrace }} &
+ {% else %} 
+   \nohyphens{{ person.guardians_parents.0.mobile|embrace }} &
+ {% endif %} 
+ &
+ \\\hline
+{% endfor %}
+ \end{longtabu}
+\end{document}
+{% endautoescape %}
diff --git a/ticdesk_org/templates/ticdesk_org/persons.html b/ticdesk_org/templates/ticdesk_org/persons.html
index 98c6ae7..28022ba 100644
--- a/ticdesk_org/templates/ticdesk_org/persons.html
+++ b/ticdesk_org/templates/ticdesk_org/persons.html
@@ -25,11 +25,13 @@
    <a href="{% url 'org:persons_by_group' group.cn %}?format=pdf&amp;template=list_attendance">{% blocktrans %}Anwesenheitsliste{% endblocktrans %}</a>
    &middot;
    <a href="{% url 'org:persons_by_group' group.cn %}?format=pdf&amp;template=list_attendance_sig">{% blocktrans %}Unterschriftenliste{% endblocktrans %}</a>
+   &middot;
+   <a href="{% url 'org:persons_by_group' group.cn %}?format=pdf&amp;template=corona">{% blocktrans %}Corona{% endblocktrans %}</a>
    )
   </p>
 
   <p>
-   {% blocktrans %}Kontankt{% endblocktrans %}
+   {% blocktrans %}Kontakt{% endblocktrans %}
     <a href="{% url 'org:group_contact_by_group' group.cn %}">Gruppenkommunikation</a>
   </p>
 
diff --git a/ticdesk_org/views.py b/ticdesk_org/views.py
index 819a08d..926b189 100644
--- a/ticdesk_org/views.py
+++ b/ticdesk_org/views.py
@@ -488,7 +488,7 @@ def edit_user(request, uid):
                 'setting_birthday_mail_days']
             # Editable only for board
             if request.FILES and 'jpeg_photo' in request.FILES:
-                with Image.open(request.FILE['jpeg_photo']) as image:
+                with Image.open(request.FILES['jpeg_photo']) as image:
                     resized_image = resizeimage.resize_width(
                         image, 300, validate=False)
                     img_bytes = BytesIO()
-- 
GitLab