Implement password reset, user add mail

This commit is contained in:
Götz 2019-04-05 17:58:01 +02:00
parent 84afd3f2eb
commit c1e3417f5a
11 changed files with 126 additions and 33 deletions

View File

@ -4,9 +4,6 @@ from .models import LdapUser, LdapGroup
class AddLDAPUserForm(forms.Form):
username = forms.CharField(label='Nutzername', max_length=400)
first_name = forms.CharField(label='Vorname', max_length=400)
last_name = forms.CharField(label='Nachname', max_length=400)
password = forms.CharField(label='Passwort', widget=forms.PasswordInput, required=False)
email = forms.EmailField(label='E-Mail', required=False)

View File

@ -27,7 +27,7 @@ def realm_list(request):
realms = Realm.objects.filter(admin_group__user__username__contains=user.username)
if len(realms) == 0:
user = LdapUser.objects.get(username=user.username)
realm_base_dn = re.compile('(uid=[a-zA-Z_]*),(ou=[a-zA-Z_]*),(.*)').match(user.dn).group(3)
realm_base_dn = re.compile('(uid=[a-zA-Z0-9_]*),(ou=[a-zA-Z_]*),(.*)').match(user.dn).group(3)
realm = Realm.objects.get(ldap_base_dn=realm_base_dn)
return redirect('realm-user-detail', realm.id, user.dn)
elif len(realms) == 1:

View File

@ -1,7 +1,17 @@
# Create your models here.
from django.db import models
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
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
import re
class LdapUser(Model):
@ -30,6 +40,35 @@ class LdapUser(Model):
def __unicode__(self):
return self.full_name
@staticmethod
def create_with_django_user_creation_and_welcome_mail(protocol, domain, username, email):
# current_site = get_current_site(request)
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,
'domain': domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token': default_token_generator.make_token(user=user),
'protocol': protocol,
'email': email
})
email = EmailMessage(
mail_subject, message, to=[user.email]
)
email.send()
return ldap_user
@staticmethod
def password_reset(user, raw_password):
LdapUser.base_dn = LdapUser.ROOT_DN
ldap_user = LdapUser.objects.get(username=user.username)
ldap_user.password = raw_password
LdapUser.base_dn = re.compile('(uid=[a-zA-Z0-9_]*),(.*)').match(ldap_user.dn).group(2)
ldap_user.save()
class LdapGroup(Model):
"""

View File

@ -1,4 +1,4 @@
from django.urls import path
from django.urls import path, re_path
import account_manager.views.group_views
import account_manager.views.user_views
@ -36,6 +36,8 @@ urlpatterns = [
name='user-update'),
path('user/<str:user_dn>/delete/realm/<int:realm_id>/', account_manager.views.user_views.user_delete,
name='user-delete'),
path('reset/<uidb64>/<token>/', account_manager.views.user_views.LdapPasswordResetConfirmView.as_view(),
name='ldap_password_reset_confirm'),
# Extra
path('permission-denied/', main_views.permission_denied, name='permission-denied'),

View File

@ -6,7 +6,11 @@ from account_manager.forms import AddLDAPUserForm
from account_manager.models import LdapUser, LdapGroup
from django.contrib.auth.models import User
from account_manager.main_views import is_realm_admin
from django.core.exceptions import ObjectDoesNotExist
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.utils.http import urlsafe_base64_decode
from django.contrib.auth.views import PasswordResetConfirmView
from django.contrib.sites.shortcuts import get_current_site
from django.contrib.auth import login
@login_required
@ -42,14 +46,14 @@ def user_add(request, realm_id):
# check whether it's valid:
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
email = form.cleaned_data['email']
current_site = get_current_site(request)
protocol = 'http'
if request.is_secure():
protocol = 'https'
LdapUser.base_dn = f'ou=people,{realm_obj.ldap_base_dn}'
LdapUser.objects.create(username=username,
password=password, first_name=first_name,
last_name=last_name, email=email)
LdapUser.create_with_django_user_creation_and_welcome_mail(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
@ -140,3 +144,13 @@ def user_delete_controller(request, ldap_user, realm_id, redirect_name):
except ObjectDoesNotExist:
pass
return redirect(redirect_name, realm_id)
class LdapPasswordResetConfirmView(PasswordResetConfirmView):
def form_valid(self, form):
user = form.save()
password = form.cleaned_data['new_password1']
print(password)
LdapUser.password_reset(user, password)
return super().form_valid(form)

View File

@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
# Application definition
LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'realm-home'
PASSWORD_RESET_TIMEOUT_DAYS = 3
INSTALLED_APPS = [
'django.contrib.admin',
@ -41,6 +42,9 @@ INSTALLED_APPS = [
'django.contrib.staticfiles',
'account_manager',
'account_helper',
'rest_framework',
'rest_framework.authtoken',
'djoser',
]
MIDDLEWARE = [
@ -149,16 +153,16 @@ AUTHENTICATION_BACKENDS = [
AUTH_LDAP_1_SERVER_URI = "ldap://localhost:1389"
AUTH_LDAP_1_USER_DN_TEMPLATE = "uid=%(user)s,ou=people,ou=fs_wiai,ou=fachschaften,dc=stuve,dc=de"
AUTH_LDAP_1_GROUP_SEARCH = LDAPSearch("dc=stuve,dc=de",
ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
)
ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
)
AUTH_LDAP_1_GROUP_TYPE = GroupOfNamesType(name_attr='cn')
AUTH_LDAP_1_MIRROR_GROUPS = True
AUTH_LDAP_2_SERVER_URI = "ldap://localhost:1389"
AUTH_LDAP_2_USER_DN_TEMPLATE = "uid=%(user)s,ou=people,ou=fs_sowi,ou=fachschaften,dc=stuve,dc=de"
AUTH_LDAP_2_GROUP_SEARCH = LDAPSearch("dc=stuve,dc=de",
ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
)
ldap.SCOPE_SUBTREE, "(objectClass=groupOfNames)"
)
AUTH_LDAP_2_GROUP_TYPE = GroupOfNamesType(name_attr='cn')
AUTH_LDAP_2_MIRROR_GROUPS = True
@ -168,3 +172,14 @@ AUTH_LDAP_USER_ATTR_MAP = {
'email': 'mail',
}
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

13
core/tokens.py Normal file
View File

@ -0,0 +1,13 @@
from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six
class TokenGenerator(PasswordResetTokenGenerator):
def _make_hash_value(self, user, timestamp):
return (
six.text_type(user.pk) + six.text_type(timestamp) +
six.text_type(user.is_active)
)
account_activation_token = TokenGenerator()

View File

@ -15,10 +15,9 @@ Including another URLconf
"""
from django.contrib import admin
from django.urls import path, include
from django.contrib.auth import views as auth_views
urlpatterns = [
path('', include('account_manager.urls')),
path('admin/', admin.site.urls),
path('account/', include('django.contrib.auth.urls')),
path('accounts/', include('django.contrib.auth.urls')),
]

View File

@ -14,15 +14,15 @@
<meta name="author" content="Michael Götz"/>
{% block js_extra %}{% endblock %}
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="{{ static('libs/font-awesome-4.7.0/css/font-awesome.css') }}">
<link rel="stylesheet" href="{{ static('libs/bootstrap-4.0.0-beta-dist/css/bootstrap.css') }}">
<link rel="stylesheet" href="{{ static('home/form.css') }}">
<link rel="stylesheet" href="{{ static('home/main.css') }}">
<script src="{{ static('libs/jquery-3.3.1.min.js') }}"></script>
<script src="{{ static('libs/handlebars-379172e.js') }}"></script>
<script src="{{ static('js/main.js') }}"></script>
<script src="{{ static('libs/popper.js-1.14.4/dist/umd/popper.js') }}"></script>
<script src="{{ static('libs/bootstrap-4.0.0-beta-dist/js/bootstrap.js') }}"></script>
{# <link rel="stylesheet" href="{{ static('libs/font-awesome-4.7.0/css/font-awesome.css') }}">#}
{# <link rel="stylesheet" href="{{ static('libs/bootstrap-4.0.0-beta-dist/css/bootstrap.css') }}">#}
{# <link rel="stylesheet" href="{{ static('home/form.css') }}">#}
{# <link rel="stylesheet" href="{{ static('home/main.css') }}">#}
{# <script src="{{ static('libs/jquery-3.3.1.min.js') }}"></script>#}
{# <script src="{{ static('libs/handlebars-379172e.js') }}"></script>#}
{# <script src="{{ static('js/main.js') }}"></script>#}
{# <script src="{{ static('libs/popper.js-1.14.4/dist/umd/popper.js') }}"></script>#}
{# <script src="{{ static('libs/bootstrap-4.0.0-beta-dist/js/bootstrap.js') }}"></script>#}
{# <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.12/handlebars.js"></script>#}
@ -32,16 +32,19 @@
{# ===== Body ===== #}
<body class="bg-dark">
{% if request.user.is_authenticated %}
Login as {{ request.user.username }}
<a href="{{ url('logout') }}">Logout</a>
Hi {{ request.user.username }}!
<p><a href="{{ url('logout') }}">Logout</a></p>
<p><a href="{{ url('password_reset') }}">Passwort zurücksetzen</a></p>
{% else %}
<p>Du bist nicht eingelogt</p>
<a href="{{ url('login') }}">Login</a>
{% endif %}
{% block body %}
<div class="container-fluid">
<div class="row">{% block bottom_nav %}{% endblock %}</div>
<div class="row bg-dark text-white">
{% block content %}{% endblock %}
<div class="row">{% block bottom_nav %}{% endblock %}</div>
<div class="row bg-dark text-white">
{% block content %}{% endblock %}
</div>
</div>
{% endblock %}
<script src="{{ static('js/form.js') }}"></script>

View File

@ -0,0 +1,3 @@
Someone asked for password reset for email {{ email }}. Follow the link below:
{{ protocol }}://{{ domain }}{{ url('password_reset_confirm', kwargs={'uidb64':uid, 'token':token}) }}

View File

@ -0,0 +1,8 @@
<h1>Willkommen bei den StuVe Services, {{ user.username }}!</h1>
<p>Es wurde ein Account für dich angelegt.</p>
<p>Dein Nutzername lautet: {{ user.username }}</p>
<p>Uns ist folgende E-Mail bekannt: {{ email }}</p>
<p>Um deinen Account zu aktivieren</p>
<p>Über den folgenden Link kannst du deinen Account
aktivieren: {{ protocol }}://{{ domain }}{{ url('ldap_password_reset_confirm', kwargs={'uidb64':uid, 'token':token}) }}</p>