From b00ecd576bd7b148601355c584b25ae658354018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20G=C3=B6tz?= Date: Tue, 28 May 2019 20:33:15 +0200 Subject: [PATCH 1/6] Standardize realm detail page --- docker/lama/dev.env | 10 ++++++++++ src/account_manager/main_views.py | 18 +++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/docker/lama/dev.env b/docker/lama/dev.env index 1f640cd..d91d21c 100644 --- a/docker/lama/dev.env +++ b/docker/lama/dev.env @@ -30,3 +30,13 @@ DEFAULT_FROM_EMAIL= SERVER_EMAIL= DELETION_WAIT_DAYS=14 + + +#EMAIL_BACKEND=smtp +#EMAIL_HOST=smtp.uni-bamberg.de +#EMAIL_PORT=587 +#EMAIL_USE_TLS=False +#EMAIL_USE_SSL=False +#DEFAULT_FROM_EMAIL=vergesslich@uni-bamberg.de +##DEFAULT_FROM_EMAIL=fachschaft-wiai.stuve@uni-bamberg.de +#SERVER_EMAIL=fachschaft-wiai.stuve@uni-bamberg.de diff --git a/src/account_manager/main_views.py b/src/account_manager/main_views.py index a4c8da4..645133d 100644 --- a/src/account_manager/main_views.py +++ b/src/account_manager/main_views.py @@ -105,16 +105,18 @@ def base_dn_available(base_dn): @login_required @is_realm_admin def realm_detail(request, realm_id): + return render_realm_detail_page(realm_id, request) + + +def render_realm_detail_page(realm_id, request, notice=""): realm = Realm.objects.get(id=realm_id) - LdapUser.base_dn = realm.ldap_base_dn - - inactive_users = LdapUser.get_inactive_users().count() - logger.info(inactive_users) ldap_admin_group, ldap_default_group = get_default_admin_group(realm) - + LdapUser.base_dn = realm.ldap_base_dn + inactive_users = LdapUser.get_inactive_users().count() return render(request, 'realm/realm_detailed.jinja2', {'realm': realm, 'ldap_admin_group': ldap_admin_group, 'ldap_default_group': ldap_default_group, - 'inactive_user_count': inactive_users, 'users_count': LdapUser.objects.all().count()}) + 'inactive_user_count': inactive_users, 'users_count': LdapUser.objects.all().count(), + 'notice': notice}) def get_default_admin_group(realm): @@ -241,6 +243,4 @@ def realm_email_test(request, realm_id): 'error': f'Mail konnte nicht versendet werden. Bitte kontaktieren sie den Administrator', 'ldap_admin_group': ldap_admin_group, 'ldap_default_group': ldap_default_group}) - return render(request, 'realm/realm_detailed.jinja2', - {'realm': realm, 'notice': 'Test erfolgreich', 'ldap_admin_group': ldap_admin_group, - 'ldap_default_group': ldap_default_group}) + return render_realm_detail_page(realm_id, request, notice='Test erfolgreich') From 604f7af5ff6381e5c2f04686b2adf49810e5d116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20G=C3=B6tz?= Date: Tue, 28 May 2019 21:17:20 +0200 Subject: [PATCH 2/6] Fix thuy again --- src/account_manager/main_views.py | 2 +- src/account_manager/views/user_views.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/account_manager/main_views.py b/src/account_manager/main_views.py index 645133d..cb320d1 100644 --- a/src/account_manager/main_views.py +++ b/src/account_manager/main_views.py @@ -45,7 +45,7 @@ def realm_list(request): try: LdapUser.base_dn = LdapUser.ROOT_DN user = LdapUser.objects.get(username=user.username) - realm_base_dn = re.compile('(uid=[a-zA-Z0-9_]*),(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('user-detail', realm.id, user.dn) diff --git a/src/account_manager/views/user_views.py b/src/account_manager/views/user_views.py index 7581422..2533436 100644 --- a/src/account_manager/views/user_views.py +++ b/src/account_manager/views/user_views.py @@ -147,7 +147,7 @@ def realm_user_resend_password_reset(request, realm_id, user_dn): ldap_user = LdapUser.objects.get(dn=user_dn) try: if ldap_user.email: - logger.info("Sending email for to this email:", ldap_user.email) + logger.info(f"Sending email to {ldap_user.email}") form = PasswordResetForm({'email': ldap_user.email}) if form.is_valid(): logger.info('CREATE REQUEST') @@ -164,7 +164,7 @@ def realm_user_resend_password_reset(request, realm_id, user_dn): email_template_name='registration/password_reset_email.html') except Exception as e: - logger.info('Error') + logger.error('Error') return redirect('realm-user-detail', realm_id, user_dn) From 62d7b9fe8a9221e50294d4d18b8d05f867e9f33d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20G=C3=B6tz?= Date: Tue, 28 May 2019 23:22:58 +0200 Subject: [PATCH 3/6] Try to fix change pw --- src/account_manager/models.py | 2 +- src/account_manager/views/user_views.py | 11 +++++++++-- src/core/urls.py | 2 ++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/account_manager/models.py b/src/account_manager/models.py index ecadf45..48bb3f6 100644 --- a/src/account_manager/models.py +++ b/src/account_manager/models.py @@ -84,7 +84,7 @@ class LdapUser(Model): 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) + LdapUser.base_dn = re.compile('(uid=[a-zA-Z0-9_-]*),(.*)').match(ldap_user.dn).group(2) ldap_user.save() @staticmethod diff --git a/src/account_manager/views/user_views.py b/src/account_manager/views/user_views.py index 2533436..a4530aa 100644 --- a/src/account_manager/views/user_views.py +++ b/src/account_manager/views/user_views.py @@ -8,7 +8,7 @@ from django.contrib.auth.views import PasswordResetConfirmView, PasswordChangeVi from django.contrib.sites.shortcuts import get_current_site from django.core.exceptions import ObjectDoesNotExist from django.db import IntegrityError -from django.http import HttpRequest +from django.http import HttpRequest, HttpResponseRedirect from django.shortcuts import render, redirect from django.utils.translation import gettext as _ from ldap import ALREADY_EXISTS, OBJECT_CLASS_VIOLATION @@ -498,9 +498,16 @@ class LdapPasswordResetConfirmView(PasswordResetConfirmView): class LdapPasswordChangeView(PasswordChangeView): + def form_valid(self, form): + logger.info('VALIDATED') user = form.save() password = form.cleaned_data['new_password1'] LdapUser.base_dn = LdapUser.ROOT_DN LdapUser.password_reset(user, password) - return super().form_valid(form) + logger.info('VALIDATED') + # return HttpResponseRedirect(self.get_success_url()) + cached_request = super().form_valid(form) + user.set_unusable_password() + user.save() + return cached_request diff --git a/src/core/urls.py b/src/core/urls.py index 3c27ba8..7bbaeb6 100644 --- a/src/core/urls.py +++ b/src/core/urls.py @@ -18,6 +18,7 @@ from django.urls import path, include from django.contrib.auth import views as auth_views from django.contrib.auth.decorators import user_passes_test from account_manager.forms import LdapPasswordResetForm +from account_manager.views.user_views import LdapPasswordChangeView from .views import about login_forbidden = user_passes_test(lambda u: u.is_anonymous(), '/') @@ -31,5 +32,6 @@ urlpatterns = [ auth_views.PasswordResetView.as_view(html_email_template_name='registration/password_reset_email.html', form_class=LdapPasswordResetForm), name='password_reset'), + path('accounts/', include('django.contrib.auth.urls')), ] From 8aca00e943ab746ab44cb51a172039b029192852 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20G=C3=B6tz?= Date: Tue, 28 May 2019 23:53:44 +0200 Subject: [PATCH 4/6] Implement pw reset without django user password setting --- src/account_manager/views/user_views.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/account_manager/views/user_views.py b/src/account_manager/views/user_views.py index a4530aa..e3c3b67 100644 --- a/src/account_manager/views/user_views.py +++ b/src/account_manager/views/user_views.py @@ -160,7 +160,7 @@ def realm_user_resend_password_reset(request, realm_id, user_dn): form.save( request=pw_reset_request, use_https=True, - from_email=os.environ.get('DEFAULT_FROM_EMAIL', 'vergesslich@test.de'), + from_email=settings.DEFAULT_FROM_EMAIL, email_template_name='registration/password_reset_email.html') except Exception as e: @@ -494,7 +494,10 @@ class LdapPasswordResetConfirmView(PasswordResetConfirmView): password = form.cleaned_data['new_password1'] LdapUser.base_dn = LdapUser.ROOT_DN LdapUser.password_reset(user, password) - return super().form_valid(form) + cached_redirect = super().form_valid(form) + user.set_unusable_password() + user.save() + return cached_redirect class LdapPasswordChangeView(PasswordChangeView): From 2237e3577066dd2f330d11bcf85ed569b65fb182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20G=C3=B6tz?= Date: Wed, 29 May 2019 00:55:34 +0200 Subject: [PATCH 5/6] Implement working password change --- src/account_manager/forms.py | 10 ++++- src/account_manager/main_views.py | 1 + src/account_manager/urls.py | 2 + src/account_manager/views/user_views.py | 19 ++++++-- .../registration/password_change_form.html | 43 ++++++++++++------- src/templates/user/user_detail.jinja2 | 2 +- 6 files changed, 55 insertions(+), 22 deletions(-) diff --git a/src/account_manager/forms.py b/src/account_manager/forms.py index d8d7964..9f2c386 100644 --- a/src/account_manager/forms.py +++ b/src/account_manager/forms.py @@ -1,6 +1,6 @@ from django import forms from django.contrib.auth import get_user_model -from django.contrib.auth.forms import PasswordResetForm +from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm from .models import LdapUser, LdapGroup from django.forms import modelformset_factory @@ -90,3 +90,11 @@ class LdapPasswordResetForm(PasswordResetForm): }) logger.debug((u for u in active_users)) return (u for u in active_users) + + +class LdapPasswordChangeForm(PasswordChangeForm): + def clean_old_password(self): + """ + Validates that the old_password field is correct. + """ + return "ralf" diff --git a/src/account_manager/main_views.py b/src/account_manager/main_views.py index cb320d1..e14c0c8 100644 --- a/src/account_manager/main_views.py +++ b/src/account_manager/main_views.py @@ -68,6 +68,7 @@ def _get_group_user_count_wrapper(realm): @login_required +@is_realm_admin def realm_add(request): if request.user.is_superuser: realms = Realm.objects.all().order_by('name') diff --git a/src/account_manager/urls.py b/src/account_manager/urls.py index 68594dc..abdc25a 100644 --- a/src/account_manager/urls.py +++ b/src/account_manager/urls.py @@ -80,6 +80,8 @@ urlpatterns = [ name='user-delete'), path('accounts/reset///', user_views.LdapPasswordResetConfirmView.as_view(), name='ldap_password_reset_confirm'), + path('accounts/password_change/secure/', user_views.password_change_controller, + name='password_change_controller'), path('accounts/password_change/', user_views.LdapPasswordChangeView.as_view(), name='password_change'), diff --git a/src/account_manager/views/user_views.py b/src/account_manager/views/user_views.py index e3c3b67..a8fac30 100644 --- a/src/account_manager/views/user_views.py +++ b/src/account_manager/views/user_views.py @@ -12,14 +12,17 @@ from django.http import HttpRequest, HttpResponseRedirect from django.shortcuts import render, redirect from django.utils.translation import gettext as _ from ldap import ALREADY_EXISTS, OBJECT_CLASS_VIOLATION +from django.urls import reverse +from urllib.parse import urlencode from account_helper.models import Realm, DeletedUser from account_manager.forms import AddLDAPUserForm, UserDeleteListForm, UpdateLDAPUserForm, AdminUpdateLDAPUserForm, \ - UserGroupListForm + UserGroupListForm, LdapPasswordChangeForm from account_manager.main_views import is_realm_admin from account_manager.models import LdapUser, LdapGroup from account_manager.utils.mail_utils import send_welcome_mail, send_deletion_mail +from django.contrib.auth import logout from django.conf import settings logger = logging.getLogger(__name__) @@ -488,6 +491,16 @@ def ldap_add_user_to_groups(ldap_user, user_groups): group.save() +@login_required +def password_change_controller(request): + logout(request) + base_url = reverse('login') + next_param = reverse('password_change') + query_string = urlencode({'next': next_param}) + url = '{}?{}'.format(base_url, query_string) + return redirect(url) + + class LdapPasswordResetConfirmView(PasswordResetConfirmView): def form_valid(self, form): user = form.save() @@ -501,15 +514,13 @@ class LdapPasswordResetConfirmView(PasswordResetConfirmView): class LdapPasswordChangeView(PasswordChangeView): + form_class = LdapPasswordChangeForm def form_valid(self, form): - logger.info('VALIDATED') user = form.save() password = form.cleaned_data['new_password1'] LdapUser.base_dn = LdapUser.ROOT_DN LdapUser.password_reset(user, password) - logger.info('VALIDATED') - # return HttpResponseRedirect(self.get_success_url()) cached_request = super().form_valid(form) user.set_unusable_password() user.save() diff --git a/src/templates/registration/password_change_form.html b/src/templates/registration/password_change_form.html index 9e5f336..bb02d13 100644 --- a/src/templates/registration/password_change_form.html +++ b/src/templates/registration/password_change_form.html @@ -1,22 +1,33 @@ {% extends 'base.jinja2' %} {% import 'macros/form_macros.jinja2' as mform %} {% block content %} -
-
-
-

Passwort ändern

-
- - {{ mform.password_input(form.old_password) }} - {{ mform.password_input(form.new_password1) }} - {{ mform.password_input(form.new_password2) }} -
- - Abbrechen -
-
-
+
+
+
+

Passwort ändern

+
+ + + + + + {{ mform.password_input(form.new_password1) }} + {{ mform.password_input(form.new_password2) }} +
+ + Abbrechen +
+
+
{% endblock %} \ No newline at end of file diff --git a/src/templates/user/user_detail.jinja2 b/src/templates/user/user_detail.jinja2 index d21f253..36d6105 100644 --- a/src/templates/user/user_detail.jinja2 +++ b/src/templates/user/user_detail.jinja2 @@ -32,7 +32,7 @@ class="font-weight-bold">Email: {{ user.user.email }}
  • Passwort: Passwort ändern + href="{{ url('password_change_controller') }}">Passwort ändern
  • Telefon: {{ user.user.phone }}
  • From 15ab8b2ab6c7fd9da6c565980ecbb47b33bd82e6 Mon Sep 17 00:00:00 2001 From: Linux User Date: Thu, 30 May 2019 20:02:25 +0000 Subject: [PATCH 6/6] Add email user and password for secure mail accounts --- src/core/docker_settings.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/docker_settings.py b/src/core/docker_settings.py index 6783c79..8dd6444 100644 --- a/src/core/docker_settings.py +++ b/src/core/docker_settings.py @@ -180,6 +180,8 @@ else: EMAIL_TIMEOUT = 15 EMAIL_HOST = os.environ['EMAIL_HOST'] EMAIL_PORT = int(os.environ['EMAIL_PORT']) + EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER','') + EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD','') EMAIL_USE_TLS = os.environ.get('EMAIL_USE_TLS', 'False') == 'True' EMAIL_USE_SSL = os.environ.get('EMAIL_USE_SSL', 'False') == 'True'