Merge branch 'master' of https://git.wiai.de/mgoetz/ldap_account_manager
This commit is contained in:
commit
b9b23d6627
@ -15,16 +15,24 @@ class Command(BaseCommand):
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--delete',
|
'--delete',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Delete poll instead of closing it',
|
help='Delete users which deletion time is lower than the current date',
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--json',
|
'--json',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Return an json encoded String',
|
help='Return an json encoded String',
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
'--all',
|
||||||
|
action='store_true',
|
||||||
|
help='Delete all marked user, --delete is required',
|
||||||
|
)
|
||||||
|
|
||||||
def handle(self, *args, **options):
|
def handle(self, *args, **options):
|
||||||
deletables = DeletedUser.objects.filter(deletion_date__lte=timezone.now())
|
if options['all']:
|
||||||
|
deletables = DeletedUser.objects.all()
|
||||||
|
else:
|
||||||
|
deletables = DeletedUser.objects.filter(deletion_date__lte=timezone.now())
|
||||||
output = ""
|
output = ""
|
||||||
if options['json']:
|
if options['json']:
|
||||||
json_output = {'deletables': []}
|
json_output = {'deletables': []}
|
||||||
@ -34,7 +42,6 @@ class Command(BaseCommand):
|
|||||||
else:
|
else:
|
||||||
for user in deletables:
|
for user in deletables:
|
||||||
output += f'{user}\n'
|
output += f'{user}\n'
|
||||||
|
|
||||||
if options['delete']:
|
if options['delete']:
|
||||||
LdapUser.base_dn = LdapUser.ROOT_DN
|
LdapUser.base_dn = LdapUser.ROOT_DN
|
||||||
for user in deletables:
|
for user in deletables:
|
||||||
@ -48,4 +55,10 @@ class Command(BaseCommand):
|
|||||||
pass
|
pass
|
||||||
if not options['json']:
|
if not options['json']:
|
||||||
output += '\nSuccessfully deleted all listed users'
|
output += '\nSuccessfully deleted all listed users'
|
||||||
self.stdout.write(self.style.SUCCESS(output))
|
if output:
|
||||||
|
self.stdout.write(self.style.SUCCESS(output))
|
||||||
|
else:
|
||||||
|
for deletable in deletables:
|
||||||
|
self.stdout.write(self.style.SUCCESS(deletable))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ from django import forms
|
|||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm
|
from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm
|
||||||
|
|
||||||
|
from account_manager.utils.django_user import update_dajngo_user
|
||||||
from .models import LdapUser, LdapGroup
|
from .models import LdapUser, LdapGroup
|
||||||
from django.forms import modelformset_factory
|
from django.forms import modelformset_factory
|
||||||
import logging
|
import logging
|
||||||
@ -83,6 +84,10 @@ class LdapPasswordResetForm(PasswordResetForm):
|
|||||||
that prevent inactive users and users with unusable passwords from
|
that prevent inactive users and users with unusable passwords from
|
||||||
resetting their password.
|
resetting their password.
|
||||||
"""
|
"""
|
||||||
|
LdapUser.base_dn = LdapUser.ROOT_DN
|
||||||
|
ldap_users = LdapUser.objects.filter(email=email)
|
||||||
|
for ldap_user in ldap_users:
|
||||||
|
update_dajngo_user(ldap_user)
|
||||||
logger.debug('Pasword reset get users')
|
logger.debug('Pasword reset get users')
|
||||||
active_users = UserModel._default_manager.filter(**{
|
active_users = UserModel._default_manager.filter(**{
|
||||||
'%s__iexact' % UserModel.get_email_field_name(): email,
|
'%s__iexact' % UserModel.get_email_field_name(): email,
|
||||||
|
|||||||
@ -106,7 +106,26 @@ def base_dn_available(base_dn):
|
|||||||
@login_required
|
@login_required
|
||||||
@is_realm_admin
|
@is_realm_admin
|
||||||
def realm_detail(request, realm_id):
|
def realm_detail(request, realm_id):
|
||||||
return render_realm_detail_page(realm_id, request)
|
return get_realm_detail_rendered(request, realm_id)
|
||||||
|
|
||||||
|
|
||||||
|
def get_realm_detail_rendered(request, realm_id, success_headline=None, success_text=None, error_headline=None,
|
||||||
|
error_text=None):
|
||||||
|
realm = Realm.objects.get(id=realm_id)
|
||||||
|
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()
|
||||||
|
ldap_admin_group, ldap_default_group = get_default_admin_group(realm)
|
||||||
|
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(),
|
||||||
|
'success_headline': success_headline,
|
||||||
|
'success_text': success_text,
|
||||||
|
'error_headline': error_headline,
|
||||||
|
'error_text': error_text})
|
||||||
|
|
||||||
|
|
||||||
def get_default_admin_group(realm):
|
def get_default_admin_group(realm):
|
||||||
@ -206,31 +225,19 @@ def permission_denied(request):
|
|||||||
|
|
||||||
def realm_email_test(request, realm_id):
|
def realm_email_test(request, realm_id):
|
||||||
realm = Realm.objects.get(id=realm_id)
|
realm = Realm.objects.get(id=realm_id)
|
||||||
ldap_admin_group, ldap_default_group = get_default_admin_group(realm)
|
|
||||||
try:
|
try:
|
||||||
realm_send_mail(realm, realm.email, f'{realm.name} Test Mail',
|
realm_send_mail(realm, realm.email, f'{realm.name} Test Mail',
|
||||||
f'Du hast die Mail Konfiguration für {realm.name} erfolgreich abgeschlossen.')
|
f'Du hast die Mail Konfiguration für {realm.name} erfolgreich abgeschlossen.')
|
||||||
except SMTPAuthenticationError as err:
|
except SMTPAuthenticationError as err:
|
||||||
return render(request, 'realm/realm_detailed.jinja2',
|
return get_realm_detail_rendered(request, realm_id, error_headline="Testmail",
|
||||||
{'realm': realm, 'error': f'Mail konnte nicht versendet werden, Anmeldedaten inkorrekt.',
|
error_text=f'Mail konnte nicht versendet werden, Anmeldedaten inkorrekt.')
|
||||||
'ldap_admin_group': ldap_admin_group,
|
|
||||||
'ldap_default_group': ldap_default_group})
|
|
||||||
except SMTPConnectError as err:
|
except SMTPConnectError as err:
|
||||||
return render(request, 'realm/realm_detailed.jinja2',
|
return get_realm_detail_rendered(request, realm_id, error_headline="Testmail",
|
||||||
{'realm': realm,
|
error_text=f'Mail konnte nicht versendet werden. Verbindungsaufbau abgelehnt. Bitte überprüfen sie die Server Addresse und den Port')
|
||||||
'error': f'Mail konnte nicht versendet werden. Verbindungsaufbau abgelehnt. Bitte überprüfen sie die Server Addresse und den Port',
|
|
||||||
'ldap_admin_group': ldap_admin_group,
|
|
||||||
'ldap_default_group': ldap_default_group})
|
|
||||||
except timeout as err:
|
except timeout as err:
|
||||||
return render(request, 'realm/realm_detailed.jinja2',
|
return get_realm_detail_rendered(request, realm_id, error_headline="Testmail",
|
||||||
{'realm': realm,
|
error_text=f'Mail konnte nicht versendet werden. Zeitüberschreitung beim Verbindungsaufbau. Bitte überprüfen sie die Server Addresse und den Port')
|
||||||
'error': f'Mail konnte nicht versendet werden. Zeitüberschreitung beim Verbindungsaufbau. Bitte überprüfen sie die Server Addresse und den Port',
|
|
||||||
'ldap_admin_group': ldap_admin_group,
|
|
||||||
'ldap_default_group': ldap_default_group})
|
|
||||||
except SMTPException:
|
except SMTPException:
|
||||||
return render(request, 'realm/realm_detailed.jinja2',
|
return get_realm_detail_rendered(request, realm_id, error_headline="Testmail",
|
||||||
{'realm': realm,
|
error_text=f'Mail konnte nicht versendet werden. Bitte kontaktieren sie den Administrator')
|
||||||
'error': f'Mail konnte nicht versendet werden. Bitte kontaktieren sie den Administrator',
|
return get_realm_detail_rendered(request, realm_id, success_headline="Testmail", success_text='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')
|
|
||||||
|
|||||||
7
src/account_manager/utils/django_user.py
Normal file
7
src/account_manager/utils/django_user.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
|
||||||
|
def update_dajngo_user(ldap_user):
|
||||||
|
user, _ = User.objects.get_or_create(username=ldap_user.username)
|
||||||
|
user.email = ldap_user.email
|
||||||
|
user.save()
|
||||||
@ -20,6 +20,7 @@ from account_manager.forms import AddLDAPUserForm, UserDeleteListForm, UpdateLDA
|
|||||||
UserGroupListForm, LdapPasswordChangeForm
|
UserGroupListForm, LdapPasswordChangeForm
|
||||||
from account_manager.main_views import is_realm_admin
|
from account_manager.main_views import is_realm_admin
|
||||||
from account_manager.models import LdapUser, LdapGroup
|
from account_manager.models import LdapUser, LdapGroup
|
||||||
|
from account_manager.utils.django_user import update_dajngo_user
|
||||||
from account_manager.utils.mail_utils import send_welcome_mail, send_deletion_mail
|
from account_manager.utils.mail_utils import send_welcome_mail, send_deletion_mail
|
||||||
|
|
||||||
from django.contrib.auth import logout
|
from django.contrib.auth import logout
|
||||||
@ -60,14 +61,19 @@ def realm_user(request, realm_id):
|
|||||||
@is_realm_admin
|
@is_realm_admin
|
||||||
@protect_cross_realm_user_access
|
@protect_cross_realm_user_access
|
||||||
def realm_user_detail(request, realm_id, user_dn):
|
def realm_user_detail(request, realm_id, user_dn):
|
||||||
|
return get_rendered_user_details(request, realm_id, user_dn)
|
||||||
|
|
||||||
|
|
||||||
|
def get_rendered_user_details(request, realm_id, user_dn, success_headline=None, success_text=None):
|
||||||
realm = Realm.objects.get(id=realm_id)
|
realm = Realm.objects.get(id=realm_id)
|
||||||
LdapUser.base_dn = realm.ldap_base_dn
|
LdapUser.base_dn = realm.ldap_base_dn
|
||||||
LdapGroup.base_dn = LdapGroup.ROOT_DN
|
LdapGroup.base_dn = LdapGroup.ROOT_DN
|
||||||
|
|
||||||
user = LdapUser.objects.get(dn=user_dn)
|
user = LdapUser.objects.get(dn=user_dn)
|
||||||
user_wrapper = LdapUser.get_extended_user(user)
|
user_wrapper = LdapUser.get_extended_user(user)
|
||||||
groups = LdapGroup.objects.filter(members=user.dn)
|
groups = LdapGroup.objects.filter(members=user.dn)
|
||||||
return render(request, 'user/realm_user_detail.jinja2', {'user': user_wrapper, 'groups': groups, 'realm': realm})
|
return render(request, 'user/realm_user_detail.jinja2',
|
||||||
|
{'user': user_wrapper, 'groups': groups, 'realm': realm, 'success_headline': success_headline,
|
||||||
|
'success_text': success_text})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -178,13 +184,15 @@ def realm_user_resend_welcome_mail(request, realm_id, user_dn):
|
|||||||
realm = Realm.objects.get(id=realm_id)
|
realm = Realm.objects.get(id=realm_id)
|
||||||
LdapUser.base_dn = f'ou=people,{realm.ldap_base_dn}'
|
LdapUser.base_dn = f'ou=people,{realm.ldap_base_dn}'
|
||||||
ldap_user = LdapUser.objects.get(dn=user_dn)
|
ldap_user = LdapUser.objects.get(dn=user_dn)
|
||||||
|
update_dajngo_user(ldap_user)
|
||||||
current_site = get_current_site(request)
|
current_site = get_current_site(request)
|
||||||
protocol = 'http'
|
protocol = 'http'
|
||||||
if request.is_secure():
|
if request.is_secure():
|
||||||
protocol = 'https'
|
protocol = 'https'
|
||||||
send_welcome_mail(domain=current_site.domain, email=ldap_user.email, protocol=protocol, realm=realm,
|
send_welcome_mail(domain=current_site.domain, email=ldap_user.email, protocol=protocol, realm=realm,
|
||||||
user=User.objects.get(username=ldap_user.username))
|
user=User.objects.get(username=ldap_user.username))
|
||||||
return redirect('realm-user-detail', realm_id, user_dn)
|
return get_rendered_user_details(request, realm_id, user_dn, success_headline="Willkommensmail",
|
||||||
|
success_text="Willkommensmail erfolgreich versendet.")
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
|||||||
@ -215,6 +215,21 @@
|
|||||||
color: #6c757d;
|
color: #6c757d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
/* -- Toast -- */
|
||||||
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
.toast {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: -250px;
|
||||||
|
width: 250px;
|
||||||
|
min-height: 50px;
|
||||||
|
z-index: 1000;
|
||||||
|
transform: translateX(-280px);
|
||||||
|
transition: transform 2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
/* -- Footer -- */
|
/* -- Footer -- */
|
||||||
/* ------------------------------------------------------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||||||
|
|||||||
@ -3,6 +3,10 @@ const TABLE_CLASS = '.data-table';
|
|||||||
const TABLE_CLASS_NO_PAGING = '.data-table-npaging';
|
const TABLE_CLASS_NO_PAGING = '.data-table-npaging';
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
// Bottstrap Toast
|
||||||
|
$('.toast').toast('show');
|
||||||
|
|
||||||
|
//Datatables
|
||||||
const data_table = $(TABLE_CLASS).DataTable({
|
const data_table = $(TABLE_CLASS).DataTable({
|
||||||
"paging": true,
|
"paging": true,
|
||||||
"pageLength": 10,
|
"pageLength": 10,
|
||||||
|
|||||||
@ -65,6 +65,7 @@
|
|||||||
<script src="{{ static('libs/DataTables/DataTables-1.10.18/js/jquery.dataTables.js') }}"></script>
|
<script src="{{ static('libs/DataTables/DataTables-1.10.18/js/jquery.dataTables.js') }}"></script>
|
||||||
<script src="{{ static('libs/DataTables/RowReorder-1.2.4/js/dataTables.rowReorder.min.js') }}"></script>
|
<script src="{{ static('libs/DataTables/RowReorder-1.2.4/js/dataTables.rowReorder.min.js') }}"></script>
|
||||||
<script src="{{ static('libs/DataTables/Responsive-2.2.2/js/dataTables.responsive.min.js') }}"></script>
|
<script src="{{ static('libs/DataTables/Responsive-2.2.2/js/dataTables.responsive.min.js') }}"></script>
|
||||||
|
<script src="{{ static('libs/bootstrap-4.3.1-dist/js/bootstrap.min.js') }}"></script>
|
||||||
<script src="{{ static('js/main.js') }}"></script>
|
<script src="{{ static('js/main.js') }}"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@ -131,6 +131,29 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro get_success_toast(success_head, success_text, error_headline, error_text) -%}
|
||||||
|
{% if success_text and success_head %}
|
||||||
|
<div class="toast" role="alert" aria-live="polite" aria-atomic="true" data-delay="5000">
|
||||||
|
<div role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div role="alert" aria-live="assertive" aria-atomic="true" class="" data-autohide="false">
|
||||||
|
<div class="toast-header text-success"><strong class="mr-auto">{{ success_head }}</strong></div>
|
||||||
|
<div class="toast-body">{{ success_text }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if error_text and error_headline %}
|
||||||
|
<div class="toast" role="alert" aria-live="polite" aria-atomic="true" data-delay="5000">
|
||||||
|
<div role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div role="alert" aria-live="assertive" aria-atomic="true" class="" data-autohide="false">
|
||||||
|
<div class="toast-header text-error"><strong class="mr-auto">{{ error_headline }}</strong></div>
|
||||||
|
<div class="toast-body">{{ error_text }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro get_data_table_search_field(input_id="data-table-search-input") -%}
|
{% macro get_data_table_search_field(input_id="data-table-search-input") -%}
|
||||||
<div class="form-group w-25 float-right">
|
<div class="form-group w-25 float-right">
|
||||||
<input type="text"
|
<input type="text"
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
{% extends 'base_admin.jinja2' %}
|
{% extends 'base_admin.jinja2' %}
|
||||||
|
{% import 'macros/utils_macros.jinja2' as mutils %}
|
||||||
|
|
||||||
{% block admin_content %}
|
{% block admin_content %}
|
||||||
<div class="row ">
|
<div class="row ">
|
||||||
<div class="col-12 p-3">
|
<div class="col-12 p-3">
|
||||||
@ -19,6 +21,7 @@
|
|||||||
<p style="color: darkred">{{ error }}</p>
|
<p style="color: darkred">{{ error }}</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% block detail_content %}
|
{% block detail_content %}
|
||||||
|
{{ mutils.get_success_toast(success_headline, success_text, error_headline, error_text) }}
|
||||||
<ul class="list-group list-group-flush w-100">
|
<ul class="list-group list-group-flush w-100">
|
||||||
<li class="list-group-item">LDAP Organisationseinheit: {{ realm.ldap_base_dn }}</li>
|
<li class="list-group-item">LDAP Organisationseinheit: {{ realm.ldap_base_dn }}</li>
|
||||||
<li class="list-group-item">Nutzeranzahl (Aktive/Inaktive): {{ users_count }}
|
<li class="list-group-item">Nutzeranzahl (Aktive/Inaktive): {{ users_count }}
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
{% extends 'realm/realm_detailed.jinja2' %}
|
{% extends 'realm/realm_detailed.jinja2' %}
|
||||||
{% import 'macros/form_macros.jinja2' as mform %}
|
{% import 'macros/form_macros.jinja2' as mform %}
|
||||||
|
{% import 'macros/utils_macros.jinja2' as mutils %}
|
||||||
|
|
||||||
{% block detail_content %}
|
{% block detail_content %}
|
||||||
|
{{ mutils.get_success_toast(success_headline, success_text) }}
|
||||||
{% if user.user %}
|
{% if user.user %}
|
||||||
{% if user.deleted_user.deletion_date %}
|
{% if user.deleted_user.deletion_date %}
|
||||||
<h3 class="text-danger">{{ user.user.username }}
|
<h3 class="text-danger">{{ user.user.username }}
|
||||||
@ -26,14 +28,22 @@
|
|||||||
<span class="text-warning"> Noch nicht generiert </span>
|
<span class="text-warning"> Noch nicht generiert </span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</li>
|
</li>
|
||||||
<li class="list-group-item">Vorname: {{ user.user.first_name }}</li>
|
{% if user.user.phone %}
|
||||||
<li class="list-group-item">Nachname: {{ user.user.last_name }}</li>
|
<li class="list-group-item">Vorname: {{ user.user.first_name }}</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if user.user.phone %}
|
||||||
|
<li class="list-group-item">Nachname: {{ user.user.last_name }}</li>
|
||||||
|
{% endif %}
|
||||||
<li class="list-group-item">Email: {{ user.user.email }}</li>
|
<li class="list-group-item">Email: {{ user.user.email }}</li>
|
||||||
<li class="list-group-item">Passwort: <a
|
<li class="list-group-item">Passwort: <a
|
||||||
href="{{ url('realm-user-password-reset', args = [realm.id, user.user.dn]) }}" class="float-right">Nutzerpasswort
|
href="{{ url('realm-user-password-reset', args = [realm.id, user.user.dn]) }}" class="float-right">Nutzerpasswort
|
||||||
zurücksetzen</a></li>
|
zurücksetzen</a></li>
|
||||||
<li class="list-group-item">Telefon: {{ user.user.phone }}</li>
|
{% if user.user.phone %}
|
||||||
<li class="list-group-item">Mobiltelefon: {{ user.user.mobile_phone }}</li>
|
<li class="list-group-item">Telefon: {{ user.user.phone }}</li>
|
||||||
|
{% endif %}
|
||||||
|
{% if user.user.mobile_phone %}
|
||||||
|
<li class="list-group-item">Mobiltelefon: {{ user.user.mobile_phone }}</li>
|
||||||
|
{% endif %}
|
||||||
<li class="list-group-item">Gruppen:
|
<li class="list-group-item">Gruppen:
|
||||||
{% if groups %}
|
{% if groups %}
|
||||||
{% for group in groups %}
|
{% for group in groups %}
|
||||||
|
|||||||
Reference in New Issue
Block a user