Finish email odyssey, Add logging

This commit is contained in:
Götz 2019-04-09 14:33:52 +02:00
parent 005c9f4176
commit 3e1a6aece0
13 changed files with 184 additions and 57 deletions

View File

@ -1,7 +1,5 @@
from django.contrib import admin
from .models import Realm, LdapGroupRDN, LdapUserRDN
from .models import Realm
# Register your models here.
admin.site.register(Realm)
admin.site.register(LdapGroupRDN)
admin.site.register(LdapUserRDN)

View File

@ -1,27 +1,13 @@
from django.contrib.auth.models import Group
from django.db import models
from django.contrib.auth.models import User, Group
# Create your models here.
class Realm(models.Model):
name = models.CharField(max_length=200, unique=True)
email = models.EmailField(blank=True, null=True)
email = models.CharField(max_length=200)
admin_group = models.ForeignKey(Group, models.PROTECT, blank=True, null=True)
ldap_base_dn = models.CharField(max_length=400, unique=True)
def __str__(self):
return f'{self.name} - {self.ldap_base_dn}'
class LdapUserRDN(models.Model):
rdn = models.CharField(max_length=400, unique=True)
def __str__(self):
return self.rdn
class LdapGroupRDN(models.Model):
rdn = models.CharField(max_length=400, unique=True)
def __str__(self):
return self.rdn

View File

@ -1,4 +1,5 @@
from django import forms
from .models import LdapUser, LdapGroup
@ -29,7 +30,10 @@ class RealmUpdateForm(forms.Form):
help_text='TODO',
max_length=200)
name = forms.CharField(label='Bereichsname', max_length=200)
email = forms.EmailField(label='E-Mail', required=False)
admin_group = forms.ModelChoiceField(label='Admin Grouppe',
help_text="Die Mitglieder dieser Gruppe darf den Bereich administieren",
queryset=LdapGroup.objects.all())
class EmailSettingsForm(forms.Form):
email = forms.EmailField(label='Eigene E-Mail Adresse')

View File

@ -1,10 +1,15 @@
from django.shortcuts import render, redirect
from .models import LdapGroup, LdapUser
from .forms import RealmAddForm, RealmUpdateForm
from account_helper.models import Realm
from django.contrib.auth.models import Group, User
from django.contrib.auth.decorators import login_required
import re
from smtplib import SMTPAuthenticationError, SMTPConnectError, SMTPException
from socket import timeout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group, User
from django.shortcuts import render, redirect
from account_helper.models import Realm
from account_manager.utils.mail_utils import realm_send_mail
from .forms import RealmAddForm, RealmUpdateForm, EmailSettingsForm
from .models import LdapGroup, LdapUser
def is_realm_admin(view_func):
@ -62,15 +67,12 @@ def realm_update(request, realm_id):
if request.user.is_superuser:
realm_obj = Realm.objects.get(id=realm_id)
data = {'id': realm_obj.id, 'ldap_base_dn': realm_obj.ldap_base_dn, 'name': realm_obj.name,
'email': realm_obj.email,
'admin_group': realm_obj.admin_group}
if request.method == 'POST':
form = RealmUpdateForm(request.POST)
if form.is_valid():
realm_obj.name = form.cleaned_data['name']
realm_obj.ldap_base_dn = form.cleaned_data['ldap_base_dn']
realm_obj.email = form.cleaned_data['email']
admin_ldap_group = form.cleaned_data['admin_group']
realm_obj.admin_group, _ = Group.objects.get_or_create(name=admin_ldap_group.name)
realm_obj.save()
@ -107,3 +109,45 @@ def realm_delete(request, realm_id):
def permission_denied(request):
return render(request, 'permission_denied.jinja2', {})
@login_required
@is_realm_admin
def realm_email_update(request, realm_id):
realm = Realm.objects.get(id=realm_id)
if request.method == 'POST':
form = EmailSettingsForm(request.POST)
if form.is_valid():
realm.email = form.cleaned_data['email']
realm.save()
return redirect('realm-detail', realm.id)
else:
data = {}
if realm.email:
data = {'email': realm.email, }
form = EmailSettingsForm(initial=data)
return render(request, 'realm/realm_create_update_mail.jinja2', {'realm': realm, 'form': form})
def realm_email_test(request, realm_id):
realm = Realm.objects.get(id=realm_id)
try:
realm_send_mail(realm, realm.email, f'{realm.name} Test Mail',
f'Du hast die Mail Konfiguration für {realm.name} erfolgreich abgeschlossen.')
except SMTPAuthenticationError as err:
return render(request, 'realm/realm_detailed.jinja2',
{'realm': realm, 'error': f'Mail konnte nicht versendet werden, Anmeldedaten inkorrekt.'})
except SMTPConnectError as err:
return render(request, 'realm/realm_detailed.jinja2',
{'realm': realm,
'error': f'Mail konnte nicht versendet werden. Verbindungsaufbau abgelehnt. Bitte überprüfen sie die Server Addresse und den Port'})
except timeout as err:
return render(request, 'realm/realm_detailed.jinja2',
{'realm': realm,
'error': f'Mail konnte nicht versendet werden. Zeitüberschreitung beim Verbindungsaufbau. Bitte überprüfen sie die Server Addresse und den Port'})
except SMTPException:
return render(request, 'realm/realm_detailed.jinja2',
{'realm': realm,
'error': f'Mail konnte nicht versendet werden. Bitte kontaktieren sie den Administrator'})
return render(request, 'realm/realm_detailed.jinja2', {'realm': realm, 'notice': 'Test erfolgreich'})

View File

@ -1,18 +1,17 @@
# Create your models here.
from ldapdb.models import fields as ldap_fields
from ldapdb.models.base import Model
from django.dispatch import receiver
from django.db.models.signals import post_save, pre_save
import re
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from django.template.loader import render_to_string
from core.tokens import account_activation_token
from django.core.mail import EmailMessage
from django.contrib.auth.models import User
from django.contrib.auth.tokens import default_token_generator
from django.template.loader import render_to_string
from django.utils.encoding import force_bytes
from django.utils.http import urlsafe_base64_encode
from ldapdb.models import fields as ldap_fields
from ldapdb.models.base import Model
from core.settings import PASSWORD_RESET_TIMEOUT_DAYS
import re
from account_manager.utils.mail_utils import realm_send_mail
from multiprocessing import Process
class LdapUser(Model):
@ -42,11 +41,9 @@ class LdapUser(Model):
return self.full_name
@staticmethod
def create_with_django_user_creation_and_welcome_mail(protocol, domain, username, email):
# current_site = get_current_site(request)
def create_with_django_user_creation_and_welcome_mail(realm, protocol, domain, username, email):
ldap_user = LdapUser.objects.create(username=username, email=email, first_name=" ", last_name=" ")
user, _ = User.objects.get_or_create(username=username, email=email)
# user.save()
mail_subject = 'Activate your blog account.'
message = render_to_string('registration/welcome_email.jinja2', {
'user': user,
@ -57,10 +54,9 @@ class LdapUser(Model):
'email': email,
'expiration_days': PASSWORD_RESET_TIMEOUT_DAYS
})
email = EmailMessage(
mail_subject, message, to=[user.email]
)
email.send()
# TODO failure handling
p1 = Process(target=realm_send_mail, args=(realm, user.email, mail_subject, message))
p1.start()
return ldap_user
@staticmethod

View File

@ -1,4 +1,4 @@
from django.urls import path, re_path
from django.urls import path
import account_manager.views.group_views
import account_manager.views.user_views
@ -10,6 +10,8 @@ urlpatterns = [
path('realm/<int:realm_id>/', main_views.realm_detail, name='realm-detail'),
path('realm/<int:realm_id>/update/', main_views.realm_update, name='realm-update'),
path('realm/<int:realm_id>/delete/', main_views.realm_delete, name='realm-delete'),
path('realm/<int:realm_id>/mail/', main_views.realm_email_update, name='realm-mail-add-update'),
path('realm/<int:realm_id>/mail/test/', main_views.realm_email_test, name='realm-mail-test'),
# Realm User
path('realm/<int:realm_id>/users/', account_manager.views.user_views.realm_user, name='realm-user-list'),

View File

View File

@ -0,0 +1,22 @@
import logging
from django.core.mail import get_connection, send_mail
from core.settings import EMAIL_HOST, EMAIL_PORT, EMAIL_USE_SSL, EMAIL_USE_TLS
logger = logging.getLogger(__name__)
def realm_send_mail(realm, to, subject, message):
logger.info('send mail')
connection = get_connection(host=EMAIL_HOST,
port=EMAIL_PORT,
username=realm.email,
use_ssl=EMAIL_USE_SSL,
use_tls=EMAIL_USE_TLS)
send_mail(subject=subject,
message=message,
from_email=realm.email,
recipient_list=[to, ],
connection=connection)
logger.info('mail sent')

View File

@ -52,8 +52,11 @@ def user_add(request, realm_id):
if request.is_secure():
protocol = 'https'
LdapUser.base_dn = f'ou=people,{realm_obj.ldap_base_dn}'
LdapUser.create_with_django_user_creation_and_welcome_mail(protocol=protocol, domain=current_site.domain,
username=username, email=email)
LdapUser.create_with_django_user_creation_and_welcome_mail(realm=realm_obj,
protocol=protocol,
domain=current_site.domain,
username=username,
email=email)
return redirect('realm-user-list', realm_id)
# if a GET (or any other method) we'll create a blank form

View File

@ -173,10 +173,54 @@ AUTH_PROFILE_MODULE = 'account_manager.UserProfile'
########################################################################################################################
# EMAIL Config #
########################################################################################################################
EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
EMAIL_FILE_PATH = os.path.join(BASE_DIR, "sent_emails")
# EMAIL_HOST = 'smtp.gmail.com'
# EMAIL_PORT = 587
# EMAIL_HOST_USER = 'info.mgserver3@gmail.com'
# EMAIL_HOST_PASSWORD = 'HaUTQh;tw6Z3"gZNK.UY'
# EMAIL_USE_TLS = True
# EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
# EMAIL_FILE_PATH = os.path.join(BASE_DIR, "sent_emails")
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_TIMEOUT = 15
EMAIL_HOST = 'smtp.uni-bamberg.de'
EMAIL_PORT = 587
EMAIL_USE_TLS = False
EMAIL_USE_SSL = False
########################################################################################################################
# Logging Config #
########################################################################################################################
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'default': {
'format': '%(asctime)s %(module)s [%(levelname)s]: %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
}
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'default',
},
'file': {
'class': 'logging.FileHandler',
'filename': './logs/import_food.log',
'formatter': 'default',
},
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
},
'mail_admins_image_upload': {
'level': 'INFO',
'class': 'django.utils.log.AdminEmailHandler',
},
},
'loggers': {
'account_manager': {
'handlers': ['console', 'file'],
'level': 'INFO',
},
'account_helper': {
'handlers': ['console', 'file'],
'level': 'INFO',
},
},
}

View File

@ -0,0 +1,11 @@
{% extends 'realm/realm_detailed.jinja2' %}
{% block realm_form %}
<h2>Email Account erstellen oder updaten</h2>
{% if form %}
<form method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{ form.as_p()|safe }}
<button type="submit">Speichern</button>
</form>
{% endif %}
{% endblock %}

View File

@ -2,15 +2,31 @@
{% block content %}
<a href="{{ url('realm-home') }}">Zurück zur Realmübersicht</a>
<h1>Bereich {{ realm.name }}</h1>
{% if notice %}
<p style="color: green">{{ notice }}</p>
{% endif %}
{% if error %}
<p style="color: darkred">{{ error }}</p>
{% endif %}
<h2>Bereich Info</h2>
<p>LDAP OU: {{ realm.ldap_base_dn }}</p>
<p>Email: {{ realm.email }}</p>
{% if realm.email %}
<p>Email: {{ realm.email }}</p>
{% else %}
<p>Noch ausstehend</p>
{% endif %}
<p>Admin Gruppe: {{ realm.admin_group }}</p>
{% if request.user.is_superuser %}
{% block realm_form %}
<h2><a href="{{ url('realm-update', args=[realm.id]) }}">Bereichsinformationen anpassen</a></h2>
{% endblock %}
{% endif %}
<h2>
<a href="{{ url('realm-mail-add-update', args=[realm.id]) }}">E-Mail Einstellungen</a> |
{% if realm.email %}
<a href="{{ url('realm-mail-test', args=[realm.id]) }}">Test Mail</a>
{% endif %}
</h2>
<h2><a href="{{ url('realm-user-add', args=[realm.id]) }}">Nutzer hinzufügen</a></h2>
{% block user_content %}

View File

@ -6,4 +6,5 @@
<p>Über den folgenden Link kannst du deinen Account
aktivieren: {{ protocol }}://{{ domain }}{{ url('ldap_password_reset_confirm', kwargs={'uidb64':uid, 'token':token}) }}</p>
<p>Der Link ist nur {{ expiration_days }} Tage gültig!</p>
<p>Und so erreichst du deinen Account: {{ protocol }}://{{ domain }}{{ url('login') }}</p>