Implement protect admin, Close #38, Close #37

This commit is contained in:
Götz 2019-04-11 19:48:54 +02:00
parent 508c0d9c8f
commit 754541458d
6 changed files with 136 additions and 13 deletions

View File

@ -95,6 +95,12 @@ class LdapGroup(Model):
name = ldap_fields.CharField(db_column='cn', max_length=200, primary_key=True)
members = ldap_fields.ListField(db_column='member')
@staticmethod
def get_user_groups(realm, user, group_base_dn):
LdapUser.base_dn = f'ou=people,{realm.ldap_base_dn}'
LdapGroup.base_dn = group_base_dn
return LdapGroup.objects.filter(members=user.dn)
def __str__(self):
return self.name

View File

@ -35,7 +35,10 @@ urlpatterns = [
path('realm/<int:realm_id>/user/delete/single/<str:user_dn>/',
account_manager.views.user_views.realm_user_delete,
name='realm-user-delete'),
path('realm/<int:realm_id>/user/delete/multiple', account_manager.views.user_views.realm_multiple_user_delete,
path('realm/<int:realm_id>/user/delete/multiple/confirm/',
account_manager.views.user_views.realm_multiple_user_delete_confirm,
name='realm-multiple-user-delete-confirm'),
path('realm/<int:realm_id>/user/delete/multiple/', account_manager.views.user_views.realm_multiple_user_delete,
name='realm-multiple-user-delete'),
# Realm Group

View File

@ -118,6 +118,8 @@ def realm_user_delete_confirm(request, realm_id, user_dn):
{'realm': realm, 'user': ldap_user, 'deletion_link': deletion_link, 'cancel_link': cancel_link})
@login_required
@is_realm_admin
def realm_multiple_user_delete(request, realm_id):
realm = Realm.objects.get(id=realm_id)
if request.method == 'POST':
@ -125,14 +127,44 @@ def realm_multiple_user_delete(request, realm_id):
if form.is_valid():
ldap_users = form.cleaned_data['ldap_users']
for ldap_user in ldap_users:
# TODO: Failure catchup
user_delete_controller(ldap_user, realm)
if _is_deleteable_user(realm, ldap_user):
user_delete_controller(ldap_user, realm)
return redirect('realm-user-list', realm_id)
return redirect('realm-user-list', realm.id)
@login_required
@is_realm_admin
def realm_multiple_user_delete_confirm(request, realm_id):
realm = Realm.objects.get(id=realm_id)
if request.method == 'POST':
form = UserDeleteListForm(request.POST)
if form.is_valid():
ldap_users = form.cleaned_data['ldap_users']
deletable_users = []
blocked_users = []
for ldap_user in ldap_users:
if _is_deleteable_user(realm, ldap_user):
deletable_users.append(ldap_user)
else:
blocked_users.append(ldap_user)
return render(request, 'realm/realm_user_multiple_delete.jinja2',
{'form': form, 'realm': realm, 'deletable_users': deletable_users,
'blocked_users': blocked_users,
'confirm': True})
# TODO: Form not valid
form = UserDeleteListForm()
LdapUser.base_dn = realm.ldap_base_dn
users = LdapUser.objects.all()
return render(request, 'realm/realm_user_multiple_delete.jinja2', {'form': form, 'realm': realm, 'users': users})
return render(request, 'realm/realm_user_multiple_delete_confirm.jinja2',
{'form': form, 'realm': realm, 'users': users})
def _is_deleteable_user(realm, user):
user_groups = LdapGroup.get_user_groups(realm, user, LdapGroup.ROOT_DN)
user_group_names = [group.name for group in user_groups]
user_admin_realms = Realm.objects.filter(id=realm.id).filter(admin_group__name__in=user_group_names)
return not len(user_admin_realms) > 0
@login_required

View File

@ -28,6 +28,6 @@
</tbody>
</table>
<a href="{{ url('realm-user-add', args=[realm.id]) }}" class="btn btn-primary">Nutzer hinzufügen</a>
<a href="{{ url('realm-multiple-user-delete', args=[realm.id]) }}" class="btn btn-danger"> Mehrere Nutzer
<a href="{{ url('realm-multiple-user-delete-confirm', args=[realm.id]) }}" class="btn btn-danger"> Mehrere Nutzer
Löschen</a>
{% endblock %}

View File

@ -3,6 +3,18 @@
{% block detail_content %}
<h2>Nutzer löschen</h2>
{% if blocked_users %}
<div class="alert alert-warning">
<h3>Admin User festgestellt</h3>
<p>Die folgenden Nutzer können nicht gelöscht werden, da Sie noch Mitglieder von ein oder mehreren Admin
Gruppen sind. Bitte tragen Sie diese vorher aus den Admin Gruppen.</p>
<ul>
{% for blocked_user in blocked_users %}
<li>{{ blocked_user.username }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<div class="form-group w-25 float-right">
<input type="text"
class="form-control"
@ -12,16 +24,10 @@
</div>
<form action="{{ url('realm-multiple-user-delete', args=[realm.id]) }}" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{# {{ form.as_p() }}#}
<table class="table table-hover table-striped table-inverse table-bordered data-table">
<thead>
<tr>
<th scope="col" class="text-center">
<input type="checkbox"
class="table-checkbox-control-input"
id="delete-all-checkbox"
><label class="table-checkbox-control-label" for="delete-all-checkbox"></label>
</th>
<th scope="col" class="text-center"></th>
<th scope="col">Nutzername</th>
<th scope="col">E-Mail</th>
<th scope="col">Vorname</th>
@ -29,7 +35,7 @@
</tr>
</thead>
<tbody>
{% for user in users %}
{% for user in deletable_users %}
<tr>
<td class="text-center">
<input type="checkbox"
@ -37,6 +43,26 @@
id="user_{{ loop.index }}"
value="{{ user.username }}"
name="ldap_users"
checked
disabled
><label class="table-checkbox-control-label" for="user_{{ loop.index }}"></label>
</td>
<td>{{ user.username }}</td>
<td>{{ user.email }}</td>
<td>{{ user.first_name }}</td>
<td>{{ user.last_name }}</td>
</tr>
<input type="checkbox" value="{{ user.username }}" name="ldap_users" checked hidden>
{% endfor %}
{% for user in blocked_users %}
<tr>
<td class="text-center">
<input type="checkbox"
class="table-checkbox-control-input delete-checkbox"
id="user_{{ loop.index }}"
value="{{ user.username }}"
name="ldap_users"
disabled
><label class="table-checkbox-control-label" for="user_{{ loop.index }}"></label>
</td>
<td>{{ user.username }}</td>

View File

@ -0,0 +1,56 @@
{% extends 'realm/realm_detailed.jinja2' %}
{% import 'macros/form_macros.jinja2' as mform %}
{% block detail_content %}
<h2>Nutzer löschen</h2>
<div class="form-group w-25 float-right">
<input type="text"
class="form-control"
placeholder="Personen Suche"
id="data-table-search-input">
<label for="data-table-search-input">Suche</label>
</div>
<form action="{{ url('realm-multiple-user-delete-confirm', args=[realm.id]) }}" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{# {{ form.as_p() }}#}
<table class="table table-hover table-striped table-inverse table-bordered data-table">
<thead>
<tr>
<th scope="col" class="text-center">
<input type="checkbox"
class="table-checkbox-control-input"
id="delete-all-checkbox"
><label class="table-checkbox-control-label" for="delete-all-checkbox"></label>
</th>
<th scope="col">Nutzername</th>
<th scope="col">E-Mail</th>
<th scope="col">Vorname</th>
<th scope="col">Nachname</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td class="text-center">
<input type="checkbox"
class="table-checkbox-control-input delete-checkbox"
id="user_{{ loop.index }}"
value="{{ user.username }}"
name="ldap_users"
><label class="table-checkbox-control-label" for="user_{{ loop.index }}"></label>
</td>
<td>{{ user.username }}</td>
<td>{{ user.email }}</td>
<td>{{ user.first_name }}</td>
<td>{{ user.last_name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="d-flex mt-4">
<button type="submit" class="btn btn-danger mr-auto p-2">Ausführen</button>
<a href="{{ url('realm-user-list', args = [realm.id]) }}"
class="btn btn-secondary p-2">Abbrechen</a>
</div>
</form>
{% endblock %}