Implement password reset, user add mail
This commit is contained in:
parent
84afd3f2eb
commit
c1e3417f5a
@ -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)
|
||||
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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):
|
||||
"""
|
||||
|
||||
@ -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'),
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
13
core/tokens.py
Normal 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()
|
||||
@ -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')),
|
||||
]
|
||||
|
||||
@ -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>
|
||||
|
||||
3
templates/registration/password_reset_email.html
Normal file
3
templates/registration/password_reset_email.html
Normal 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}) }}
|
||||
|
||||
8
templates/registration/welcome_email.jinja2
Normal file
8
templates/registration/welcome_email.jinja2
Normal 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>
|
||||
|
||||
Reference in New Issue
Block a user