Compare commits

..

9 Commits

52 changed files with 1207 additions and 981 deletions

View File

@ -1,7 +1,7 @@
FROM alpine:3.9
ADD ["requirements.txt", "/requirements.txt"]
RUN apk upgrade --update && \
apk add --update python3 build-base openldap-dev python3-dev py3-psycopg2 && \
apk add --update python3 build-base openldap-dev python3-dev py3-psycopg2 gettext && \
pip3 install -r /requirements.txt && rm /requirements.txt
WORKDIR /lama
EXPOSE 80

View File

@ -1,7 +1,7 @@
FROM alpine:3.9
ADD ["requirements.txt", "/requirements.txt"]
RUN apk upgrade --update && \
apk add --update python3 build-base openldap-dev python3-dev py3-psycopg2 && \
apk add --update python3 build-base openldap-dev python3-dev py3-psycopg2 gettext && \
pip3 install -r /requirements.txt && rm /requirements.txt
WORKDIR /lama
EXPOSE 80

View File

@ -30,13 +30,3 @@ 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

View File

@ -3,4 +3,4 @@ python-ldap==3.2.0
django-auth-ldap==1.7.0
django-ldapdb==1.3.0
Jinja2==2.10
Pillow==2.2.1
Pillow==2.2.1

View File

@ -15,24 +15,16 @@ class Command(BaseCommand):
parser.add_argument(
'--delete',
action='store_true',
help='Delete users which deletion time is lower than the current date',
help='Delete poll instead of closing it',
)
parser.add_argument(
'--json',
action='store_true',
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):
if options['all']:
deletables = DeletedUser.objects.all()
else:
deletables = DeletedUser.objects.filter(deletion_date__lte=timezone.now())
deletables = DeletedUser.objects.filter(deletion_date__lte=timezone.now())
output = ""
if options['json']:
json_output = {'deletables': []}
@ -42,6 +34,7 @@ class Command(BaseCommand):
else:
for user in deletables:
output += f'{user}\n'
if options['delete']:
LdapUser.base_dn = LdapUser.ROOT_DN
for user in deletables:
@ -55,10 +48,4 @@ class Command(BaseCommand):
pass
if not options['json']:
output += '\nSuccessfully deleted all listed users'
if output:
self.stdout.write(self.style.SUCCESS(output))
else:
for deletable in deletables:
self.stdout.write(self.style.SUCCESS(deletable))
self.stdout.write(self.style.SUCCESS(output))

View File

@ -1,8 +1,7 @@
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import PasswordResetForm, PasswordChangeForm
from django.contrib.auth.forms import PasswordResetForm
from account_manager.utils.django_user import update_dajngo_user
from .models import LdapUser, LdapGroup
from django.forms import modelformset_factory
import logging
@ -84,10 +83,6 @@ class LdapPasswordResetForm(PasswordResetForm):
that prevent inactive users and users with unusable passwords from
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')
active_users = UserModel._default_manager.filter(**{
'%s__iexact' % UserModel.get_email_field_name(): email,
@ -95,11 +90,3 @@ 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"

View File

@ -1,19 +1,20 @@
import logging
import re
from smtplib import SMTPAuthenticationError, SMTPConnectError, SMTPException
from socket import timeout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group, User
from django.core.exceptions import ObjectDoesNotExist
from django.db import IntegrityError
from django.shortcuts import render, redirect
from ldap import LDAPError
from django.shortcuts import render, redirect, HttpResponse
from account_helper.models import Realm
from account_manager.utils.mail_utils import realm_send_mail
from account_manager.utils.main_views import render_permission_denied_view, render_realm_detail_view, \
get_users_home_view
from .forms import RealmAddForm, RealmUpdateForm
from .models import LdapGroup, LdapUser
from ldap import LDAPError
from django.utils.translation import gettext as _
logger = logging.getLogger(__name__)
@ -26,20 +27,44 @@ def is_realm_admin(view_func):
admin_group__user__username__contains=request.user.username)) > 0):
return view_func(request, *args, **kwargs)
else:
return render_permission_denied_view(request)
return redirect('permission-denied')
return decorator
@login_required
def realm_list(request):
django_user = request.user
if django_user.is_superuser:
user = request.user
if user.is_superuser:
realms = Realm.objects.order_by('name').all()
else:
realms = Realm.objects.filter(admin_group__user__username__contains=django_user.username).order_by('name')
realms = Realm.objects.filter(admin_group__user__username__contains=user.username).order_by('name').order_by(
'name')
show_user = request.GET.get('show_user', False)
if show_user or (len(realms) == 0 and not user.is_superuser):
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 = Realm.objects.get(ldap_base_dn=realm_base_dn)
return get_users_home_view(request, django_user, realms)
return redirect('user-detail', realm.id, user.dn)
except ObjectDoesNotExist as err:
logger.info('Login failed', err)
return HttpResponse(_('InvalidLogin'))
elif len(realms) == 1:
return redirect('realm-detail', realms[0].id)
else:
realm_wrappers = []
for realm in realms:
realm_wrappers.append(_get_group_user_count_wrapper(realm))
return render(request, 'realm/realm_home.jinja2', {'realms': realms, 'realm_wrappers': realm_wrappers})
def _get_group_user_count_wrapper(realm):
LdapUser.base_dn = f'ou=people,{realm.ldap_base_dn}'
LdapGroup.base_dn = f'ou=groups,{realm.ldap_base_dn}'
return {'realm': realm, 'group_count': LdapGroup.objects.count(), 'user_count': LdapUser.objects.count()}
@login_required
@ -54,21 +79,21 @@ def realm_add(request):
try:
base_dn_available(ldap_base_dn)
realm = Realm.objects.create(name=name, ldap_base_dn=ldap_base_dn)
realm.save()
return render_realm_detail_view(request, realm.id, status_code=201)
realm_obj = Realm.objects.create(name=name, ldap_base_dn=ldap_base_dn)
realm_obj.save()
return redirect('realm-detail', realm_obj.id)
except IntegrityError as err:
# TODO: Load no extra fail view, use current add view
return render(request, 'realm/realm_add_failed.jinja2',
{'realm_name': name, 'error': err}, status=409)
{'realm_name': name, 'error': err})
except LDAPError as err:
logger.debug("Ldap Error", err)
return render(request, 'realm/realm_add_failed.jinja2',
{'realm_name': name}, status=409)
{'realm_name': name})
else:
form = RealmAddForm()
return render(request, 'realm/realm_add.jinja2', {'realms': realms, 'form': form})
return render_permission_denied_view(request)
else:
redirect('permission-denied')
def base_dn_available(base_dn):
@ -80,7 +105,28 @@ def base_dn_available(base_dn):
@login_required
@is_realm_admin
def realm_detail(request, realm_id):
return render_realm_detail_view(request, realm_id)
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)
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()})
def get_default_admin_group(realm):
ldap_admin_group = None
ldap_default_group = None
if realm.admin_group:
LdapGroup.base_dn = f'ou=groups,{realm.ldap_base_dn}'
ldap_admin_group = LdapGroup.objects.get(name=realm.admin_group.name)
if realm.default_group:
LdapGroup.base_dn = f'ou=groups,{realm.ldap_base_dn}'
ldap_default_group = LdapGroup.objects.get(name=realm.default_group.name)
return ldap_admin_group, ldap_default_group
@login_required
@ -88,17 +134,19 @@ def realm_detail(request, realm_id):
def realm_update(request, realm_id):
if request.user.is_superuser:
realm = Realm.objects.get(id=realm_id)
LdapGroup.base_dn = f'ou=groups,{realm.ldap_base_dn}'
ldap_admin_group = None if not realm.admin_group else LdapGroup.objects.get(name=realm.admin_group.name)
ldap_default_group = None if not realm.default_group else LdapGroup.objects.get(name=realm.default_group.name)
form_data = {'id': realm.id,
'ldap_base_dn': realm.ldap_base_dn,
'name': realm.name,
'email': realm.email,
'admin_group': ldap_admin_group,
'default_group': ldap_default_group}
ldap_admin_group = None
if realm.admin_group:
ldap_admin_group = LdapGroup.objects.get(name=realm.admin_group.name)
ldap_default_group = None
if realm.default_group:
ldap_default_group = LdapGroup.objects.get(name=realm.default_group.name)
data = {'id': realm.id,
'ldap_base_dn': realm.ldap_base_dn,
'name': realm.name,
'email': realm.email,
'admin_group': ldap_admin_group,
'default_group': ldap_default_group}
if request.method == 'POST':
form = RealmUpdateForm(request.POST)
if form.is_valid():
@ -106,16 +154,23 @@ def realm_update(request, realm_id):
realm.ldap_base_dn = form.cleaned_data['ldap_base_dn']
realm.email = form.cleaned_data['email']
admin_ldap_group = form.cleaned_data['admin_group']
realm.admin_group = None if not admin_ldap_group else admin_ldap_group.get_django_group()
if admin_ldap_group:
realm.admin_group, _ = Group.objects.get_or_create(name=admin_ldap_group.name)
else:
realm.admin_group = None
default_ldap_group = form.cleaned_data['default_group']
realm.default_group = None if not default_ldap_group else default_ldap_group.get_django_group()
if default_ldap_group:
realm.default_group, _ = Group.objects.get_or_create(name=default_ldap_group.name)
else:
realm.default_group = None
realm.save()
return render_realm_detail_view(request, realm_id, status_code=200)
return render(request, 'realm/realm_update.jinja2', {'realm': realm, 'form': form}, status=422)
return redirect('realm-detail', realm.id)
else:
form = RealmUpdateForm(initial=form_data)
form = RealmUpdateForm(initial=data)
return render(request, 'realm/realm_update.jinja2', {'realm': realm, 'form': form})
return render_permission_denied_view(request)
else:
realm = Realm.objects.get(id=realm_id)
return render(request, 'realm/realm_update.jinja2', {'realm': realm})
@login_required
@ -154,27 +209,38 @@ def realm_delete(request, realm_id):
def permission_denied(request):
return render_permission_denied_view(request)
return render(request, 'permission_denied.jinja2', {})
def realm_email_test(request, realm_id):
realm = Realm.objects.get(id=realm_id)
test_msg = f'Du hast die Mail Konfiguration für {realm.name} erfolgreich abgeschlossen.'
success_msg = 'Test erfolgreich'
error_msg_auth = f'Mail konnte nicht versendet werden, Anmeldedaten inkorrekt.'
error_msg_connect = f'Mail konnte nicht versendet werden. Verbindungsaufbau abgelehnt. ' \
f'Bitte überprüfen sie die Server Addresse und den Port'
error_msg_timeout = f'Mail konnte nicht versendet werden. Zeitüberschreitung beim Verbindungsaufbau. ' \
f'Bitte überprüfen sie die Server Addresse und den Port'
error_msg_smtp = f'Mail konnte nicht versendet werden. Bitte kontaktieren sie den Administrator'
ldap_admin_group, ldap_default_group = get_default_admin_group(realm)
try:
realm_send_mail(realm, realm.email, f'{realm.name} Test Mail', test_msg)
except SMTPAuthenticationError:
return render_realm_detail_view(request, realm_id, error_headline="Testmail", error_text=error_msg_auth)
except SMTPConnectError:
return render_realm_detail_view(request, realm_id, error_headline="Testmail", error_text=error_msg_connect)
except timeout:
return render_realm_detail_view(request, realm_id, error_headline="Testmail", error_text=error_msg_timeout)
realm_send_mail(realm, realm.email, f'{realm.name} Test Mail',
f'Du hast die Mail Konfiguration für {realm.name} erfolgreich abgeschlossen.')
except SMTPAuthenticationError as err:
return render(request, 'realm/realm_detailed.jinja2',
{'realm': realm, 'error': f'Mail konnte nicht versendet werden, Anmeldedaten inkorrekt.',
'ldap_admin_group': ldap_admin_group,
'ldap_default_group': ldap_default_group})
except SMTPConnectError as err:
return render(request, 'realm/realm_detailed.jinja2',
{'realm': realm,
'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:
return render(request, 'realm/realm_detailed.jinja2',
{'realm': realm,
'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:
return render_realm_detail_view(request, realm_id, error_headline="Testmail", error_text=error_msg_smtp)
return render_realm_detail_view(request, realm_id, success_headline="Testmail", success_text=success_msg)
return render(request, 'realm/realm_detailed.jinja2',
{'realm': realm,
'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})

View File

@ -4,7 +4,7 @@ import os
import re
from datetime import datetime, timedelta
from django.contrib.auth.models import User, Group
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.db import OperationalError
from django.db.models import Q
@ -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
@ -132,13 +132,6 @@ class LdapUser(Model):
return (LdapUser.objects.filter(last_login__lte=last_semester) | LdapUser.objects.exclude(
last_login__lte=datetime.now() + timedelta(days=1)))
def get_users_realm_base_dn(self):
return re.compile('(uid=[a-zA-Z0-9_-]*),(ou=[a-zA-Z_-]*),(.*)').match(self.dn).group(3)
@staticmethod
def set_root_dn(realm):
LdapUser.base_dn = f'ou=people,{realm.ldap_base_dn}'
class LdapGroup(Model):
"""
@ -169,14 +162,6 @@ class LdapGroup(Model):
group.members.remove(ldap_user_dn)
group.save()
def get_django_group(self):
django_group, _ = Group.objects.get_or_create(name=self.name)
return django_group
@staticmethod
def set_root_dn(realm):
LdapGroup.base_dn = f'ou=groups,{realm.ldap_base_dn}'
def __str__(self):
return self.name

View File

@ -1,3 +1,3 @@
from django.test import TestCase
# Create your tests here.
# Create your tests here.

View File

@ -1,430 +0,0 @@
import logging
from django.contrib.auth.models import User, Group
from django.test import TestCase
# Create your tests here.
from django.urls import reverse
from account_helper.models import Realm
from account_manager.models import LdapUser, LdapGroup
class RealmHomeViewTest(TestCase):
@classmethod
def setUpTestData(cls):
# User.objects.get_or_create(username="test", email="test@test.de")
User.objects.create_superuser(
username='test_superuser',
password=RealmHomeViewTest.get_password(),
email='test@test.de',
is_staff=True,
is_superuser=True,
is_active=True,
)
def create_ldap_objects(self):
self.realm_1, _ = Realm.objects.get_or_create(name="test_realm_1",
ldap_base_dn="ou=test,ou=fachschaften,dc=test,dc=de")
self.realm_2, _ = Realm.objects.get_or_create(name="test_realm_2",
ldap_base_dn="ou=test2,ou=fachschaften,dc=test,dc=de")
LdapUser.set_root_dn(self.realm_1)
self.ldap_user_multiple_admin, _ = LdapUser.objects.get_or_create(username="test_multi_admin",
email="test@test.de",
password=RealmHomeViewTest.get_password(),
first_name="max",
last_name="musterstudent")
self.ldap_user_admin, _ = LdapUser.objects.get_or_create(username="test_admin", email="test@test.de",
password=RealmHomeViewTest.get_password(),
first_name="max",
last_name="musterstudent")
self.ldap_user, _ = LdapUser.objects.get_or_create(username="test", email="test@test.de",
password=RealmHomeViewTest.get_password(),
first_name="max",
last_name="musterstudent")
LdapGroup.set_root_dn(self.realm_1)
self.realm_1_ldap_group = LdapGroup.objects.create(name="test_realm_1_admin_group",
members=[self.ldap_user_multiple_admin.dn,
self.ldap_user_admin.dn])
LdapGroup.set_root_dn(self.realm_1)
self.realm_2_ldap_group = LdapGroup.objects.create(name="test_realm_2_admin_group",
members=[self.ldap_user_multiple_admin.dn])
logging.disable(logging.DEBUG)
self.realm_1.admin_group = self.realm_1_ldap_group.get_django_group()
self.realm_1.save()
self.realm_2.admin_group = self.realm_2_ldap_group.get_django_group()
self.realm_2.save()
@classmethod
def get_password(cls):
return "12345678"
def setUp(self):
self.create_ldap_objects()
self.django_superuser = User.objects.get(username="test_superuser")
def tearDown(self):
self.clear_ldap_objects()
self.django_superuser.delete()
logging.disable(logging.NOTSET)
def clear_ldap_objects(self):
self.realm_1.delete()
self.realm_2.delete()
self.ldap_user_multiple_admin.delete()
self.ldap_user_admin.delete()
self.ldap_user.delete()
self.realm_1_ldap_group.delete()
self.realm_2_ldap_group.delete()
def test_without_login(self):
response = self.client.get(reverse('realm-home'))
self.assertEqual(response.status_code, 302)
def test_with_user_login(self):
self.client.login(username=self.ldap_user.username, password=RealmHomeViewTest.get_password())
response = self.client.get(reverse('realm-home'))
self.assertContains(response, 'Profil löschen', status_code=200)
self.client.logout()
def test_with_admin_login(self):
self.client.login(username=self.ldap_user_admin.username, password=RealmHomeViewTest.get_password())
response = self.client.get(reverse('realm-home'))
self.assertContains(response, 'Bereich ', status_code=200)
self.client.logout()
def test_with_admin_multiple_realms_login(self):
self.client.login(username=self.ldap_user_multiple_admin.username, password=RealmHomeViewTest.get_password())
response = self.client.get(reverse('realm-home'))
self.assertContains(response, 'Bereiche', status_code=200)
self.client.logout()
def test_with_superuser_login(self):
self.client.login(username=self.django_superuser.username, password=RealmHomeViewTest.get_password())
response = self.client.get(reverse('realm-home'))
self.assertContains(response, 'Bereiche', status_code=200)
self.client.logout()
class RealmAddViewTest(TestCase):
@classmethod
def setUpTestData(cls):
realm, _ = Realm.objects.get_or_create(name="test", ldap_base_dn="ou=test,ou=fachschaften,dc=test,dc=de")
LdapUser.set_root_dn(realm)
LdapUser.objects.get_or_create(username="test", email="test@test.de",
password=RealmAddViewTest.get_password(),
first_name="max",
last_name="musterstudent")
User.objects.get_or_create(username="test", email="test@test.de")
logging.disable(logging.DEBUG)
@classmethod
def get_password(cls):
return "12345678"
def setUp(self):
self.realm = Realm.objects.get(name="test")
LdapUser.set_root_dn(self.realm)
self.ldap_user = LdapUser.objects.get(username="test")
self.django_user = User.objects.get(username="test")
self.django_superuser = User.objects.create_superuser(
username='superuser_test',
password='test',
email='test@test.de',
is_staff=True,
is_superuser=True,
is_active=True,
)
def tearDown(self):
self.realm.delete()
self.ldap_user.delete()
self.django_user.delete()
logging.disable(logging.NOTSET)
def test_without_login(self):
response = self.client.get(reverse('realm-add'))
self.assertEqual(response.status_code, 302)
def test_with_login(self):
self.client.login(username=self.ldap_user.username, password=RealmAddViewTest.get_password())
response = self.client.get(reverse('realm-add'))
self.assertContains(response, 'Leider hast du keine Rechte', status_code=403)
self.client.logout()
def test_with_login_and_post_valid_form(self):
self.client.login(username=self.ldap_user.username, password=RealmAddViewTest.get_password())
response = self.client.post(reverse('realm-add'),
{'name': 'test', 'ldap_base_dn': 'ou=test,ou=fachschaften,dc=test,dc=de'})
self.assertContains(response, 'Leider hast du keine Rechte', status_code=403)
self.client.logout()
def test_with_super_user_login(self):
self.client.login(username=self.django_superuser.username, password='test')
response = self.client.get(reverse('realm-add'))
self.assertContains(response, 'Neuen Bereich anlegen', status_code=200)
self.client.logout()
def test_with_super_user_login_add_realm(self):
realm = Realm.objects.get(name=self.realm.name)
realm.delete()
self.client.login(username=self.django_superuser.username, password='test')
response = self.client.post(reverse('realm-add'),
{'name': 'test', 'ldap_base_dn': 'ou=test,ou=fachschaften,dc=test,dc=de'})
self.assertContains(response, 'Bereich test', status_code=201)
self.client.logout()
self.realm, _ = Realm.objects.get_or_create(name="test", ldap_base_dn="ou=test,ou=fachschaften,dc=test,dc=de")
def test_with_super_user_login_add_extisting_realm(self):
self.client.login(username=self.django_superuser.username, password='test')
response = self.client.post(reverse('realm-add'),
{'name': 'test', 'ldap_base_dn': 'ou=test,ou=fachschaften,dc=test,dc=de'})
self.assertContains(response, 'Das hinzufügen des Bereichs ist fehlgeschlagen.', status_code=409)
self.client.logout()
def test_with_super_user_login_add_extisting_realm_with_different_name(self):
self.client.login(username=self.django_superuser.username, password='test')
response = self.client.post(reverse('realm-add'),
{'name': 'test_new', 'ldap_base_dn': 'ou=test,ou=fachschaften,dc=test,dc=de'})
self.assertContains(response, 'Das hinzufügen des Bereichs ist fehlgeschlagen.', status_code=409)
self.client.logout()
def test_with_super_user_login_add_realm_with_not_existing_ldap_base_dn(self):
self.client.login(username=self.django_superuser.username, password='test')
response = self.client.post(reverse('realm-add'),
{'name': 'test_not_extisting_ldap_dn',
'ldap_base_dn': 'ou=not_exists,ou=fachschaften,dc=test,dc=de'})
self.assertContains(response, 'Das hinzufügen des Bereichs ist fehlgeschlagen.', status_code=409)
self.client.logout()
class RealmDetailViewTest(TestCase):
@classmethod
def setUpTestData(cls):
# User.objects.get_or_create(username="test", email="test@test.de")
User.objects.create_superuser(
username='test_superuser',
password=RealmDetailViewTest.get_password(),
email='test@test.de',
is_staff=True,
is_superuser=True,
is_active=True,
)
def create_ldap_objects(self):
self.realm_1, _ = Realm.objects.get_or_create(name="test_realm_1",
ldap_base_dn="ou=test,ou=fachschaften,dc=test,dc=de")
LdapUser.set_root_dn(self.realm_1)
self.ldap_user_admin, _ = LdapUser.objects.get_or_create(username="test_admin", email="test@test.de",
password=RealmDetailViewTest.get_password(),
first_name="max",
last_name="musterstudent")
self.ldap_user, _ = LdapUser.objects.get_or_create(username="test", email="test@test.de",
password=RealmDetailViewTest.get_password(),
first_name="max",
last_name="musterstudent")
LdapGroup.set_root_dn(self.realm_1)
self.realm_1_ldap_group = LdapGroup.objects.create(name="test_realm_1_admin_group",
members=[self.ldap_user_admin.dn])
logging.disable(logging.DEBUG)
self.realm_1.admin_group = self.realm_1_ldap_group.get_django_group()
self.realm_1.save()
@classmethod
def get_password(cls):
return "12345678"
def setUp(self):
self.create_ldap_objects()
self.django_superuser = User.objects.get(username="test_superuser")
def tearDown(self):
self.clear_ldap_objects()
self.django_superuser.delete()
logging.disable(logging.NOTSET)
def clear_ldap_objects(self):
self.realm_1.delete()
self.ldap_user_admin.delete()
self.ldap_user.delete()
self.realm_1_ldap_group.delete()
def test_without_login(self):
response = self.client.get(reverse('realm-detail', args=[self.realm_1.id]))
self.assertEqual(response.status_code, 302)
def test_with_user_login(self):
self.client.login(username=self.ldap_user.username, password=RealmDetailViewTest.get_password())
response = self.client.get(reverse('realm-detail', args=[self.realm_1.id]))
self.assertContains(response, 'Leider hast du keine Rechte', status_code=403)
self.client.logout()
def test_with_admin_login(self):
self.client.login(username=self.ldap_user_admin.username, password=RealmDetailViewTest.get_password())
response = self.client.get(reverse('realm-detail', args=[self.realm_1.id]))
self.assertContains(response, 'Bereich ', status_code=200)
self.client.logout()
def test_with_superuser_login(self):
self.client.login(username=self.django_superuser.username, password=RealmDetailViewTest.get_password())
response = self.client.get(reverse('realm-detail', args=[self.realm_1.id]))
self.assertContains(response, 'Bereich', status_code=200)
self.client.logout()
class RealmUpdateViewTest(TestCase):
@classmethod
def setUpTestData(cls):
# User.objects.get_or_create(username="test", email="test@test.de")
User.objects.create_superuser(
username='test_superuser',
password=RealmUpdateViewTest.get_password(),
email='test@test.de',
is_staff=True,
is_superuser=True,
is_active=True,
)
def create_ldap_objects(self):
self.realm_1, _ = Realm.objects.get_or_create(name="test_realm_1",
ldap_base_dn="ou=test,ou=fachschaften,dc=test,dc=de",
email="test.realm@test.de")
self.realm_2, _ = Realm.objects.get_or_create(name="test_realm_2",
ldap_base_dn="ou=test2,ou=fachschaften,dc=test,dc=de")
LdapUser.set_root_dn(self.realm_1)
self.ldap_user_multiple_admin, _ = LdapUser.objects.get_or_create(username="test_multi_admin",
email="test@test.de",
password=RealmUpdateViewTest.get_password(),
first_name="max",
last_name="musterstudent")
self.ldap_user_admin, _ = LdapUser.objects.get_or_create(username="test_admin", email="test@test.de",
password=RealmUpdateViewTest.get_password(),
first_name="max",
last_name="musterstudent")
self.ldap_user, _ = LdapUser.objects.get_or_create(username="test", email="test@test.de",
password=RealmUpdateViewTest.get_password(),
first_name="max",
last_name="musterstudent")
LdapGroup.set_root_dn(self.realm_1)
self.realm_1_ldap_group = LdapGroup.objects.create(name="test_realm_1_admin_group",
members=[self.ldap_user_multiple_admin.dn,
self.ldap_user_admin.dn])
LdapGroup.set_root_dn(self.realm_1)
self.realm_2_ldap_group = LdapGroup.objects.create(name="test_realm_2_admin_group",
members=[self.ldap_user_multiple_admin.dn])
LdapGroup.set_root_dn(self.realm_1)
self.realm_3_ldap_group = LdapGroup.objects.create(name="test_realm_3_admin_group",
members=[self.ldap_user_admin.dn])
logging.disable(logging.DEBUG)
self.realm_1.admin_group = self.realm_1_ldap_group.get_django_group()
self.realm_1.save()
self.realm_2.admin_group = self.realm_2_ldap_group.get_django_group()
self.realm_2.save()
@classmethod
def get_password(cls):
return "12345678"
def setUp(self):
self.create_ldap_objects()
self.django_superuser = User.objects.get(username="test_superuser")
def tearDown(self):
self.clear_ldap_objects()
self.django_superuser.delete()
logging.disable(logging.NOTSET)
def clear_ldap_objects(self):
self.realm_1.delete()
self.realm_2.delete()
self.ldap_user_multiple_admin.delete()
self.ldap_user_admin.delete()
self.ldap_user.delete()
self.realm_1_ldap_group.delete()
self.realm_2_ldap_group.delete()
self.realm_3_ldap_group.delete()
def test_without_login(self):
response = self.client.get(reverse('realm-update', args=[self.realm_1.id]))
self.assertEqual(response.status_code, 302)
def test_with_user_login(self):
self.client.login(username=self.ldap_user.username, password=RealmUpdateViewTest.get_password())
response = self.client.get(reverse('realm-update', args=[self.realm_1.id]))
self.assertContains(response, 'Leider hast du keine Rechte', status_code=403)
self.client.logout()
def test_with_admin_login(self):
self.client.login(username=self.ldap_user_admin.username, password=RealmUpdateViewTest.get_password())
response = self.client.get(reverse('realm-update', args=[self.realm_1.id]))
self.assertContains(response, 'Leider hast du keine Rechte', status_code=403)
self.client.logout()
def test_with_superuser_login(self):
self.client.login(username=self.django_superuser.username, password=RealmUpdateViewTest.get_password())
response = self.client.get(reverse('realm-update', args=[self.realm_1.id]))
self.assertContains(response, '<label for="id_name">Bereichsname</label>', status_code=200)
self.client.logout()
def test_with_superuser_login_post_single_changes(self):
self.client.login(username=self.django_superuser.username, password=RealmUpdateViewTest.get_password())
new_name = "new test realm"
new_email = "newtest@test.de"
new_admin_group = self.realm_1_ldap_group
new_default_group = self.realm_3_ldap_group
response = self.client.post(reverse('realm-update', args=[self.realm_1.id]),
{'name': new_name, 'email': new_email,
'ldap_base_dn': self.realm_1.ldap_base_dn})
self.assertContains(response, 'Nutzeranzahl', status_code=200)
self.realm_1.refresh_from_db()
self.assertEqual(self.realm_1.name, new_name)
self.assertEqual(self.realm_1.email, new_email)
response = self.client.post(reverse('realm-update', args=[self.realm_1.id]),
{'name': new_name, 'email': new_email,
'ldap_base_dn': self.realm_1.ldap_base_dn, 'admin_group': new_admin_group.name})
self.assertContains(response, 'Nutzeranzahl', status_code=200)
self.realm_1.refresh_from_db()
django_group = Group.objects.get(name=new_admin_group.name)
self.assertEqual(self.realm_1.admin_group, django_group)
response = self.client.post(reverse('realm-update', args=[self.realm_1.id]),
{'name': new_name, 'email': new_email,
'ldap_base_dn': self.realm_1.ldap_base_dn,
'default_group': new_default_group.name})
self.assertContains(response, 'Nutzeranzahl', status_code=200)
self.realm_1.refresh_from_db()
django_group = Group.objects.get(name=new_default_group.name)
self.assertEqual(self.realm_1.default_group, django_group)
self.client.logout()
def test_with_superuser_login_post_with_missing_data(self):
self.client.login(username=self.django_superuser.username, password=RealmUpdateViewTest.get_password())
new_name = "new test realm"
response = self.client.post(reverse('realm-update', args=[self.realm_1.id]),
{'name': new_name,
'ldap_base_dn': self.realm_1.ldap_base_dn})
self.assertContains(response, '<label for="id_name">Bereichsname</label>', status_code=422)
response = self.client.post(reverse('realm-update', args=[self.realm_1.id]),
{'email': "test@test.de",
'ldap_base_dn': self.realm_1.ldap_base_dn})
self.assertContains(response, '<label for="id_name">Bereichsname</label>', status_code=422)
response = self.client.post(reverse('realm-update', args=[self.realm_1.id]),
{'name': new_name, 'email': "test@test.de"})
self.assertContains(response, '<label for="id_name">Bereichsname</label>', status_code=422)
response = self.client.post(reverse('realm-update', args=[self.realm_1.id]),
{'name': new_name, 'email': "abc",
'ldap_base_dn': self.realm_1.ldap_base_dn})
self.assertContains(response, '<label for="id_name">Bereichsname</label>', status_code=422)
self.client.logout()

View File

@ -80,8 +80,6 @@ urlpatterns = [
name='user-delete'),
path('accounts/reset/<uidb64>/<token>/', 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'),

View File

@ -1,7 +0,0 @@
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()

View File

@ -1,62 +0,0 @@
from django.shortcuts import render
from account_helper.models import Realm
from account_manager.models import LdapUser, LdapGroup
from account_manager.utils.user_views import render_user_detail_view
def render_realm_detail_view(request, realm_id, success_headline=None, success_text=None, error_headline=None,
error_text=None, status_code=200):
realm = Realm.objects.get(id=realm_id)
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}, status=status_code)
def get_default_admin_group(realm):
ldap_admin_group = None
ldap_default_group = None
if realm.admin_group:
LdapGroup.base_dn = f'ou=groups,{realm.ldap_base_dn}'
ldap_admin_group = LdapGroup.objects.get(name=realm.admin_group.name)
if realm.default_group:
LdapGroup.base_dn = f'ou=groups,{realm.ldap_base_dn}'
ldap_default_group = LdapGroup.objects.get(name=realm.default_group.name)
return ldap_admin_group, ldap_default_group
def render_permission_denied_view(request):
return render(request, 'permission_denied.jinja2', {}, status=403)
def get_group_user_count_wrapper(realm):
LdapUser.base_dn = f'ou=people,{realm.ldap_base_dn}'
LdapGroup.base_dn = f'ou=groups,{realm.ldap_base_dn}'
return {'realm': realm, 'group_count': LdapGroup.objects.count(), 'user_count': LdapUser.objects.count()}
def get_users_home_view(request, django_user, realms):
show_user = request.GET.get('show_user', False)
if show_user or (len(realms) == 0 and not django_user.is_superuser):
LdapUser.base_dn = LdapUser.ROOT_DN
ldap_user = LdapUser.objects.get(username=django_user.username)
realm = Realm.objects.get(ldap_base_dn=ldap_user.get_users_realm_base_dn())
return render_user_detail_view(request, realm, ldap_user)
elif len(realms) == 1:
return render_realm_detail_view(request, realms[0].id)
else:
realm_wrappers = []
for realm in realms:
realm_wrappers.append(get_group_user_count_wrapper(realm))
return render(request, 'realm/realm_home.jinja2', {'realms': realms, 'realm_wrappers': realm_wrappers})

View File

@ -1,10 +0,0 @@
from django.shortcuts import render
from account_manager.models import LdapUser, LdapGroup
def render_user_detail_view(request, realm, ldap_user):
user_wrapper = LdapUser.get_extended_user(ldap_user)
LdapGroup.base_dn = LdapGroup.ROOT_DN
groups = LdapGroup.objects.filter(members=ldap_user.dn)
return render(request, 'user/user_detail.jinja2', {'user': user_wrapper, 'groups': groups, 'realm': realm})

View File

@ -1,4 +1,5 @@
import logging
import os
from django.contrib.auth.decorators import login_required
from django.contrib.auth.forms import PasswordResetForm
@ -11,22 +12,16 @@ from django.http import HttpRequest
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, LdapPasswordChangeForm
UserGroupListForm
from account_manager.main_views import is_realm_admin
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 django.contrib.auth import logout
from django.conf import settings
from account_manager.utils.user_views import render_user_detail_view
logger = logging.getLogger(__name__)
@ -62,28 +57,26 @@ def realm_user(request, realm_id):
@is_realm_admin
@protect_cross_realm_user_access
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)
LdapUser.base_dn = realm.ldap_base_dn
LdapGroup.base_dn = LdapGroup.ROOT_DN
user = LdapUser.objects.get(dn=user_dn)
user_wrapper = LdapUser.get_extended_user(user)
groups = LdapGroup.objects.filter(members=user.dn)
return render(request, 'user/realm_user_detail.jinja2',
{'user': user_wrapper, 'groups': groups, 'realm': realm, 'success_headline': success_headline,
'success_text': success_text})
return render(request, 'user/realm_user_detail.jinja2', {'user': user_wrapper, 'groups': groups, 'realm': realm})
@login_required
def user_detail(request, realm_id, user_dn):
realm = Realm.objects.get(id=realm_id)
LdapUser.base_dn = realm.ldap_base_dn
ldap_user = LdapUser.objects.get(dn=user_dn)
LdapGroup.base_dn = LdapGroup.ROOT_DN
return render_user_detail_view(request, realm, ldap_user)
user = LdapUser.objects.get(dn=user_dn)
user_wrapper = LdapUser.get_extended_user(user)
groups = LdapGroup.objects.filter(members=user.dn)
return render(request, 'user/user_detail.jinja2', {'user': user_wrapper, 'groups': groups, 'realm': realm})
@login_required
@ -154,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(f"Sending email to {ldap_user.email}")
logger.info("Sending email for to this email:", ldap_user.email)
form = PasswordResetForm({'email': ldap_user.email})
if form.is_valid():
logger.info('CREATE REQUEST')
@ -167,11 +160,11 @@ def realm_user_resend_password_reset(request, realm_id, user_dn):
form.save(
request=pw_reset_request,
use_https=True,
from_email=settings.DEFAULT_FROM_EMAIL,
from_email=os.environ.get('DEFAULT_FROM_EMAIL', 'vergesslich@test.de'),
email_template_name='registration/password_reset_email.html')
except Exception as e:
logger.error('Error')
logger.info('Error')
return redirect('realm-user-detail', realm_id, user_dn)
@ -182,15 +175,13 @@ def realm_user_resend_welcome_mail(request, realm_id, user_dn):
realm = Realm.objects.get(id=realm_id)
LdapUser.base_dn = f'ou=people,{realm.ldap_base_dn}'
ldap_user = LdapUser.objects.get(dn=user_dn)
update_dajngo_user(ldap_user)
current_site = get_current_site(request)
protocol = 'http'
if request.is_secure():
protocol = 'https'
send_welcome_mail(domain=current_site.domain, email=ldap_user.email, protocol=protocol, realm=realm,
user=User.objects.get(username=ldap_user.username))
return get_rendered_user_details(request, realm_id, user_dn, success_headline="Willkommensmail",
success_text="Willkommensmail erfolgreich versendet.")
return redirect('realm-user-detail', realm_id, user_dn)
@login_required
@ -497,37 +488,19 @@ 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()
password = form.cleaned_data['new_password1']
LdapUser.base_dn = LdapUser.ROOT_DN
LdapUser.password_reset(user, password)
cached_redirect = super().form_valid(form)
user.set_unusable_password()
user.save()
return cached_redirect
return super().form_valid(form)
class LdapPasswordChangeView(PasswordChangeView):
form_class = LdapPasswordChangeForm
def form_valid(self, form):
user = form.save()
password = form.cleaned_data['new_password1']
LdapUser.base_dn = LdapUser.ROOT_DN
LdapUser.password_reset(user, password)
cached_request = super().form_valid(form)
user.set_unusable_password()
user.save()
return cached_request
return super().form_valid(form)

View File

@ -13,6 +13,7 @@ https://docs.djangoproject.com/en/2.1/ref/settings/
import os
import ldap
from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
from django.utils.translation import ugettext_lazy as _
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DOMAIN = os.environ['DOMAIN']
@ -37,6 +38,7 @@ INSTALLED_APPS = [
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
@ -113,19 +115,6 @@ AUTH_PASSWORD_VALIDATORS = [
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
@ -180,8 +169,6 @@ 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'
@ -192,6 +179,30 @@ LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'realm-home'
PASSWORD_RESET_TIMEOUT_DAYS = 3
########################################################################################################################
# Languages Config #
########################################################################################################################
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
LANGUAGES = (
('en', _('English')),
('de', _('Deutsch')),
('de-fr', _('Deutsch'))
)
USE_L10N = True
LANGUAGE_CODE = 'de'
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
########################################################################################################################
# Logging Config #
########################################################################################################################

View File

@ -1,13 +1,18 @@
from django.templatetags.static import static
from django.utils.translation import gettext, ngettext
from django.urls import reverse
from django.utils import translation
from jinja2 import Environment
def environment(**options):
options['extensions'] = ['jinja2.ext.i18n']
env = Environment(**options)
env.install_gettext_translations(translation)
# env.install_gettext_callables(gettext=gettext, ngettext=ngettext, newstyle=True)
env.globals.update({
'static': static,
'url': reverse,
})
return env
return env

View File

@ -18,7 +18,6 @@ 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(), '/')
@ -32,6 +31,5 @@ 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')),
]

View File

@ -0,0 +1,406 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-05-18 01:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: account_manager/main_views.py:54
msgid "InvalidLogin"
msgstr ""
#: account_manager/views/user_views.py:37
msgid ""
"Der angefragte Nutzer gehört einem anderen Bereich an. Nutzer können nur von "
"dem Bereich bearbeitet werden, in dem sie erstellt wurden."
msgstr ""
#: core/docker_settings.py:196
msgid "English"
msgstr ""
#: core/docker_settings.py:197 core/docker_settings.py:198
msgid "Deutsch"
msgstr ""
#: templates/admin/list_user.jinja2:8
msgid "DjangoKnownUsers"
msgstr ""
#: templates/admin/list_user.jinja2:9
msgid "DjangoAdminPages"
msgstr ""
#: templates/admin/list_user.jinja2:12
msgid "SuperAdminInfo"
msgstr ""
#: templates/admin/list_user.jinja2:18 templates/macros/utils_macros.jinja2:28
#: templates/macros/utils_macros.jinja2:77
#: templates/macros/utils_macros.jinja2:138
#: templates/realm/realm_user_multiple_delete.jinja2:23
#: templates/realm/realm_user_multiple_delete_confirm.jinja2:11
msgid "Search"
msgstr ""
#: templates/admin/list_user.jinja2:23
msgid "SuperAdmin"
msgstr ""
#: templates/admin/list_user.jinja2:24 templates/macros/form_macros.jinja2:309
#: templates/macros/utils_macros.jinja2:33
msgid "Username"
msgstr ""
#: templates/admin/list_user.jinja2:25 templates/macros/form_macros.jinja2:310
#: templates/macros/utils_macros.jinja2:34
#: templates/realm/realm_detailed.jinja2:28
#: templates/user/realm_user_detail.jinja2:32
msgid "Email"
msgstr ""
#: templates/admin/list_user.jinja2:26 templates/macros/form_macros.jinja2:311
#: templates/macros/utils_macros.jinja2:35
#: templates/user/realm_user_detail.jinja2:30
msgid "FirstName"
msgstr ""
#: templates/admin/list_user.jinja2:27 templates/macros/form_macros.jinja2:312
#: templates/macros/utils_macros.jinja2:36
#: templates/user/realm_user_detail.jinja2:31
msgid "LastName"
msgstr ""
#. Translators: The Application Name: default LAMa
#: templates/base.jinja2:33
msgid "AppName"
msgstr ""
#. Translators: Logout button
#: templates/base.jinja2:40
msgid "Logout"
msgstr ""
#. Translators: Login Button
#: templates/base.jinja2:43
msgid "Login"
msgstr ""
#. Translators: About link title
#: templates/base.jinja2:58 templates/base_admin.jinja2:50
msgid "About"
msgstr ""
#: templates/base_admin.jinja2:10
msgid "DjangoAdminArea"
msgstr ""
#: templates/base_admin.jinja2:14 templates/realm/realm_home.jinja2:6
msgid "Realms"
msgstr ""
#: templates/base_admin.jinja2:24
msgid "RealmOverview"
msgstr ""
#: templates/base_admin.jinja2:27 templates/realm/realm_detailed.jinja2:5
msgid "Realm"
msgstr ""
#: templates/base_admin.jinja2:31
msgid "RealmInformation"
msgstr ""
#: templates/base_admin.jinja2:34 templates/realm/realm_user.jinja2:5
msgid "User"
msgstr ""
#: templates/base_admin.jinja2:37 templates/realm/realm_groups.jinja2:4
#: templates/user/realm_user_detail.jinja2:37
msgid "Groups"
msgstr ""
#: templates/base_admin.jinja2:46 templates/realm/realm_home.jinja2:11
msgid "RealmAdd"
msgstr ""
#: templates/group/group_add.jinja2:6
msgid "AddGroup"
msgstr ""
#: templates/group/group_add.jinja2:18 templates/group/group_detail.jinja2:35
#: templates/realm/realm_update.jinja2:14
#: templates/user/realm_user_add.jinja2:14
#: templates/user/realm_user_detail.jinja2:97
msgid "Save"
msgstr ""
#: templates/group/group_add.jinja2:20
#: templates/group/group_confirm_delete.jinja2:17
#: templates/group/group_detail.jinja2:37
#: templates/realm/realm_update.jinja2:16
#: templates/realm/realm_user_multiple_delete.jinja2:31
#: templates/realm/realm_user_multiple_delete_confirm.jinja2:19
#: templates/user/realm_user_add.jinja2:16
#: templates/user/realm_user_detail.jinja2:99
#: templates/user/user_confirm_delete.jinja2:25
msgid "Cancel"
msgstr ""
#: templates/group/group_confirm_delete.jinja2:19
#: templates/group/group_detail.jinja2:22
msgid "DeleteGroup"
msgstr ""
#: templates/group/group_detail.jinja2:7
msgid "Group"
msgstr ""
#: templates/group/group_detail.jinja2:9
#: templates/user/realm_user_detail.jinja2:22
msgid "LdapDomain"
msgstr ""
#: templates/group/group_detail.jinja2:12 templates/realm/realm_groups.jinja2:9
msgid "Description"
msgstr ""
#: templates/group/group_detail.jinja2:15
msgid "Members"
msgstr ""
#: templates/group/group_detail.jinja2:19
#: templates/group/group_detail.jinja2:25
msgid "UpdateGroup"
msgstr ""
#: templates/macros/form_macros.jinja2:314
#: templates/macros/utils_macros.jinja2:38
#: templates/user/realm_user_detail.jinja2:54
msgid "LastLogin"
msgstr ""
#: templates/macros/utils_macros.jinja2:37
msgid "Active"
msgstr ""
#: templates/macros/utils_macros.jinja2:39
msgid "DeletionDate"
msgstr ""
#: templates/macros/utils_macros.jinja2:82
msgid "RealmName"
msgstr ""
#: templates/macros/utils_macros.jinja2:83
msgid "LdapBaseDN"
msgstr ""
#: templates/macros/utils_macros.jinja2:84
msgid "MailAddress"
msgstr ""
#: templates/macros/utils_macros.jinja2:85
msgid "AdminGroup"
msgstr ""
#: templates/macros/utils_macros.jinja2:86
msgid "DefaultGroup"
msgstr ""
#: templates/macros/utils_macros.jinja2:87
msgid "UserCount"
msgstr ""
#: templates/macros/utils_macros.jinja2:88
msgid "GroupCount"
msgstr ""
#: templates/permission_denied.jinja2:8
msgid "PermissionDeniedInfo"
msgstr ""
#. Translators: Is the Headline of the create new realm view
#: templates/realm/realm_add.jinja2:10
msgid "CreateNewRealm"
msgstr ""
#. Translators: the submit button text for the create new realm form
#: templates/realm/realm_add.jinja2:16
msgid "CreateRealm"
msgstr ""
#: templates/realm/realm_add_failed.jinja2:5
msgid "AddRealmError"
msgstr ""
#: templates/realm/realm_add_failed.jinja2:7
msgid "AddRealmErrorInfo"
msgstr ""
#: templates/realm/realm_add_failed.jinja2:11
msgid "AddRealmErrorLdapInfo"
msgstr ""
#. Translators: The Application Name: default LAMa
#: templates/realm/realm_confirm_delete.jinja2:7
msgid "RealmDelete"
msgstr ""
#: templates/realm/realm_confirm_delete.jinja2:27
msgid "RealmDeleteCancel"
msgstr ""
#: templates/realm/realm_confirm_delete.jinja2:29
msgid "RealmDeleteAgree"
msgstr ""
#: templates/realm/realm_detailed.jinja2:10
msgid "RealmDetailRemoveRealm"
msgstr ""
#: templates/realm/realm_detailed.jinja2:19
msgid "RealmDetailLdapOU"
msgstr ""
#: templates/realm/realm_detailed.jinja2:20
msgid "RealmDetailUserCount"
msgstr ""
#: templates/realm/realm_detailed.jinja2:25
msgid "RealmDetailRemoveInactiveUser"
msgstr ""
#: templates/realm/realm_detailed.jinja2:30
#: templates/realm/realm_detailed.jinja2:37
#: templates/realm/realm_detailed.jinja2:45
msgid "RealmDetailStillPending"
msgstr ""
#: templates/realm/realm_detailed.jinja2:32
msgid "RealmDetailAdminGroup"
msgstr ""
#: templates/realm/realm_detailed.jinja2:40
msgid "RealmDetailDefaultGroup"
msgstr ""
#: templates/realm/realm_detailed.jinja2:52
msgid "RealmDetailChangeRealmInfo"
msgstr ""
#: templates/realm/realm_detailed.jinja2:56
msgid "RealmDetailTestMail"
msgstr ""
#: templates/realm/realm_groups.jinja2:8
msgid "Name"
msgstr ""
#: templates/realm/realm_groups.jinja2:10
msgid "MemberCount"
msgstr ""
#: templates/realm/realm_groups.jinja2:31
msgid "AddGroups"
msgstr ""
#: templates/realm/realm_user.jinja2:8 templates/user/realm_user_add.jinja2:5
msgid "AddUser"
msgstr ""
#: templates/realm/realm_user.jinja2:10
msgid "RemoveMultipleUser"
msgstr ""
#: templates/realm/realm_user_multiple_delete.jinja2:6
#: templates/realm/realm_user_multiple_delete_confirm.jinja2:5
#: templates/user/realm_user_detail.jinja2:85
#: templates/user/user_confirm_delete.jinja2:27
msgid "DeleteUser"
msgstr ""
#: templates/realm/realm_user_multiple_delete.jinja2:10
msgid "MultipleUserDeleteError"
msgstr ""
#: templates/realm/realm_user_multiple_delete.jinja2:29
#: templates/realm/realm_user_multiple_delete_confirm.jinja2:17
msgid "Execute"
msgstr ""
#: templates/user/realm_user_detail.jinja2:23
msgid "UserDisplayName"
msgstr ""
#: templates/user/realm_user_detail.jinja2:27
msgid "NotGeneratedYet"
msgstr ""
#: templates/user/realm_user_detail.jinja2:33
msgid "Password"
msgstr ""
#: templates/user/realm_user_detail.jinja2:34
msgid "UserPasswordReset"
msgstr ""
#: templates/user/realm_user_detail.jinja2:35
msgid "Phone"
msgstr ""
#: templates/user/realm_user_detail.jinja2:36
msgid "MobilePhone"
msgstr ""
#: templates/user/realm_user_detail.jinja2:47
msgid "NoneGroupAssigned"
msgstr ""
#: templates/user/realm_user_detail.jinja2:51
msgid "AssignGroups"
msgstr ""
#: templates/user/realm_user_detail.jinja2:62
msgid "DeletionProcess"
msgstr ""
#: templates/user/realm_user_detail.jinja2:65
msgid "CancelDeletionProcess"
msgstr ""
#: templates/user/realm_user_detail.jinja2:73
msgid "UpdateUser"
msgstr ""
#: templates/user/realm_user_detail.jinja2:79
msgid "ResendWelcomeMail"
msgstr ""
#: templates/user/realm_user_update_groups.jinja2:6
msgid "UpdateGroupMembership"
msgstr ""
#: templates/user/realm_user_update_groups.jinja2:11
msgid "UserGroupDelete"
msgstr ""
#: templates/user/realm_user_update_groups.jinja2:30
msgid "UserGroupAdd"
msgstr ""
#: templates/user/realm_user_update_groups.jinja2:50
msgid "Done"
msgstr ""

View File

@ -0,0 +1,425 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-05-18 01:19+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: account_manager/main_views.py:54
msgid "InvalidLogin"
msgstr "Invalid login. Please try again."
#: account_manager/views/user_views.py:37
msgid ""
"Der angefragte Nutzer gehört einem anderen Bereich an. Nutzer können nur von "
"dem Bereich bearbeitet werden, in dem sie erstellt wurden."
msgstr ""
#: core/docker_settings.py:196
msgid "English"
msgstr ""
#: core/docker_settings.py:197 core/docker_settings.py:198
msgid "Deutsch"
msgstr ""
#: templates/admin/list_user.jinja2:8
msgid "DjangoKnownUsers"
msgstr "Django bekannte Nutzer"
#: templates/admin/list_user.jinja2:9
msgid "DjangoAdminPages"
msgstr "Django Adminbereich"
#: templates/admin/list_user.jinja2:12
msgid "SuperAdminInfo"
msgstr ""
"Um einen Nutzer zum Superadmin zu ernennen, klicke auf das Superadmin Icon"
#: templates/admin/list_user.jinja2:18 templates/macros/utils_macros.jinja2:28
#: templates/macros/utils_macros.jinja2:77
#: templates/macros/utils_macros.jinja2:138
#: templates/realm/realm_user_multiple_delete.jinja2:23
#: templates/realm/realm_user_multiple_delete_confirm.jinja2:11
msgid "Search"
msgstr "Suche"
#: templates/admin/list_user.jinja2:23
msgid "SuperAdmin"
msgstr "Superadmin"
#: templates/admin/list_user.jinja2:24 templates/macros/form_macros.jinja2:309
#: templates/macros/utils_macros.jinja2:33
msgid "Username"
msgstr "Nutzername"
#: templates/admin/list_user.jinja2:25 templates/macros/form_macros.jinja2:310
#: templates/macros/utils_macros.jinja2:34
#: templates/realm/realm_detailed.jinja2:28
#: templates/user/realm_user_detail.jinja2:32
msgid "Email"
msgstr "E-Mail"
#: templates/admin/list_user.jinja2:26 templates/macros/form_macros.jinja2:311
#: templates/macros/utils_macros.jinja2:35
#: templates/user/realm_user_detail.jinja2:30
msgid "FirstName"
msgstr "Vorname"
#: templates/admin/list_user.jinja2:27 templates/macros/form_macros.jinja2:312
#: templates/macros/utils_macros.jinja2:36
#: templates/user/realm_user_detail.jinja2:31
msgid "LastName"
msgstr "Nachname"
#. Translators: The Application Name: default LAMa
#: templates/base.jinja2:33
msgid "AppName"
msgstr "LAMa"
#. Translators: Logout button
#: templates/base.jinja2:40
msgid "Logout"
msgstr ""
#. Translators: Login Button
#: templates/base.jinja2:43
msgid "Login"
msgstr ""
#. Translators: About link title
#: templates/base.jinja2:58 templates/base_admin.jinja2:50
msgid "About"
msgstr "Über"
#: templates/base_admin.jinja2:10
msgid "DjangoAdminArea"
msgstr "Django Adminbereich"
#: templates/base_admin.jinja2:14 templates/realm/realm_home.jinja2:6
msgid "Realms"
msgstr "Bereiche"
#: templates/base_admin.jinja2:24
msgid "RealmOverview"
msgstr "Bereichsübersicht"
#: templates/base_admin.jinja2:27 templates/realm/realm_detailed.jinja2:5
msgid "Realm"
msgstr "Bereich"
#: templates/base_admin.jinja2:31
msgid "RealmInformation"
msgstr "Bereichsinformationen"
#: templates/base_admin.jinja2:34 templates/realm/realm_user.jinja2:5
msgid "User"
msgstr "Nutzer"
#: templates/base_admin.jinja2:37 templates/realm/realm_groups.jinja2:4
#: templates/user/realm_user_detail.jinja2:37
msgid "Groups"
msgstr "Gruppen"
#: templates/base_admin.jinja2:46 templates/realm/realm_home.jinja2:11
msgid "RealmAdd"
msgstr "Bereich hinzufügen"
#: templates/group/group_add.jinja2:6
msgid "AddGroup"
msgstr "Gruppe anlegen"
#: templates/group/group_add.jinja2:18 templates/group/group_detail.jinja2:35
#: templates/realm/realm_update.jinja2:14
#: templates/user/realm_user_add.jinja2:14
#: templates/user/realm_user_detail.jinja2:97
msgid "Save"
msgstr "Sichern"
#: templates/group/group_add.jinja2:20
#: templates/group/group_confirm_delete.jinja2:17
#: templates/group/group_detail.jinja2:37
#: templates/realm/realm_update.jinja2:16
#: templates/realm/realm_user_multiple_delete.jinja2:31
#: templates/realm/realm_user_multiple_delete_confirm.jinja2:19
#: templates/user/realm_user_add.jinja2:16
#: templates/user/realm_user_detail.jinja2:99
#: templates/user/user_confirm_delete.jinja2:25
msgid "Cancel"
msgstr "Abbrechen"
#: templates/group/group_confirm_delete.jinja2:19
#: templates/group/group_detail.jinja2:22
msgid "DeleteGroup"
msgstr "Gruppe löschen"
#: templates/group/group_detail.jinja2:7
msgid "Group"
msgstr "Gruppe"
#: templates/group/group_detail.jinja2:9
#: templates/user/realm_user_detail.jinja2:22
msgid "LdapDomain"
msgstr "Ldap Domain"
#: templates/group/group_detail.jinja2:12 templates/realm/realm_groups.jinja2:9
msgid "Description"
msgstr "Beschreibung"
#: templates/group/group_detail.jinja2:15
msgid "Members"
msgstr "Mitglieder"
#: templates/group/group_detail.jinja2:19
#: templates/group/group_detail.jinja2:25
msgid "UpdateGroup"
msgstr "Gruppe bearbeiten"
#: templates/macros/form_macros.jinja2:314
#: templates/macros/utils_macros.jinja2:38
#: templates/user/realm_user_detail.jinja2:54
msgid "LastLogin"
msgstr "Letzter Login"
#: templates/macros/utils_macros.jinja2:37
msgid "Active"
msgstr "Aktiv"
#: templates/macros/utils_macros.jinja2:39
msgid "DeletionDate"
msgstr "Löschdatum"
#: templates/macros/utils_macros.jinja2:82
msgid "RealmName"
msgstr "Bereichsname"
#: templates/macros/utils_macros.jinja2:83
msgid "LdapBaseDN"
msgstr "Ldap Basis DN"
#: templates/macros/utils_macros.jinja2:84
msgid "MailAddress"
msgstr "Mailadresse"
#: templates/macros/utils_macros.jinja2:85
msgid "AdminGroup"
msgstr "Admingruppe"
#: templates/macros/utils_macros.jinja2:86
msgid "DefaultGroup"
msgstr "Defaultgruppe"
#: templates/macros/utils_macros.jinja2:87
msgid "UserCount"
msgstr "Nutzeranzahl"
#: templates/macros/utils_macros.jinja2:88
msgid "GroupCount"
msgstr "Gruppenanzahl"
#: templates/permission_denied.jinja2:8
msgid "PermissionDeniedInfo"
msgstr "Leider hast du keine Rechte :´("
#. Translators: Is the Headline of the create new realm view
#: templates/realm/realm_add.jinja2:10
msgid "CreateNewRealm"
msgstr "Neuen Bereich anlegen"
#. Translators: the submit button text for the create new realm form
#: templates/realm/realm_add.jinja2:16
msgid "CreateRealm"
msgstr "Bereich anlegen"
#: templates/realm/realm_add_failed.jinja2:5
msgid "AddRealmError"
msgstr "Hinzufügen Fehlgeschlagen"
#: templates/realm/realm_add_failed.jinja2:7
msgid "AddRealmErrorInfo"
msgstr "Das hinzufügen des Bereichs ist fehlgeschlagen."
#: templates/realm/realm_add_failed.jinja2:11
msgid "AddRealmErrorLdapInfo"
msgstr "Bitte überprüfe den Ldap base dn, ob dieser auch wirklich existiert."
#. Translators: The Application Name: default LAMa
#: templates/realm/realm_confirm_delete.jinja2:7
msgid "RealmDelete"
msgstr "Löschen des Bereichs"
#: templates/realm/realm_confirm_delete.jinja2:27
msgid "RealmDeleteCancel"
msgstr "Abbrechen"
#: templates/realm/realm_confirm_delete.jinja2:29
msgid "RealmDeleteAgree"
msgstr "Bereich löschen"
#: templates/realm/realm_detailed.jinja2:10
msgid "RealmDetailRemoveRealm"
msgstr "Bereich löschen"
#: templates/realm/realm_detailed.jinja2:19
msgid "RealmDetailLdapOU"
msgstr "LDAP Organisationseinheit"
#: templates/realm/realm_detailed.jinja2:20
msgid "RealmDetailUserCount"
msgstr "Nutzeranzahl (Aktive/Inaktive)"
#: templates/realm/realm_detailed.jinja2:25
msgid "RealmDetailRemoveInactiveUser"
msgstr "Inaktive Nutzer löschen"
#: templates/realm/realm_detailed.jinja2:30
#: templates/realm/realm_detailed.jinja2:37
#: templates/realm/realm_detailed.jinja2:45
msgid "RealmDetailStillPending"
msgstr "Noch ausstehend"
#: templates/realm/realm_detailed.jinja2:32
msgid "RealmDetailAdminGroup"
msgstr "Admin Gruppe"
#: templates/realm/realm_detailed.jinja2:40
msgid "RealmDetailDefaultGroup"
msgstr "Default Gruppe"
#: templates/realm/realm_detailed.jinja2:52
msgid "RealmDetailChangeRealmInfo"
msgstr "Bereichsinformationen anpassen"
#: templates/realm/realm_detailed.jinja2:56
msgid "RealmDetailTestMail"
msgstr "Test Mail senden"
#: templates/realm/realm_groups.jinja2:8
msgid "Name"
msgstr "Name"
#: templates/realm/realm_groups.jinja2:10
msgid "MemberCount"
msgstr "Mitgliederanzahl"
#: templates/realm/realm_groups.jinja2:31
msgid "AddGroups"
msgstr "Gruppen hinzufügen"
#: templates/realm/realm_user.jinja2:8 templates/user/realm_user_add.jinja2:5
msgid "AddUser"
msgstr "Nutzer hinzufügen"
#: templates/realm/realm_user.jinja2:10
msgid "RemoveMultipleUser"
msgstr "Mehrere Nutzer löschen"
#: templates/realm/realm_user_multiple_delete.jinja2:6
#: templates/realm/realm_user_multiple_delete_confirm.jinja2:5
#: templates/user/realm_user_detail.jinja2:85
#: templates/user/user_confirm_delete.jinja2:27
msgid "DeleteUser"
msgstr "Nutzer löschen"
#: templates/realm/realm_user_multiple_delete.jinja2:10
msgid "MultipleUserDeleteError"
msgstr ""
" <h3>Admin User festgestellt</h3><p>Die folgenden Nutzer können nicht "
"gelöscht werden, da Sie noch Mitglieder von ein oder mehreren AdminGruppen "
"sind. Bitte tragen Sie diese vorher aus den Admin Gruppen.</p>"
#: templates/realm/realm_user_multiple_delete.jinja2:29
#: templates/realm/realm_user_multiple_delete_confirm.jinja2:17
msgid "Execute"
msgstr "Ausführen"
#: templates/user/realm_user_detail.jinja2:23
msgid "UserDisplayName"
msgstr "Anzeigename"
#: templates/user/realm_user_detail.jinja2:27
msgid "NotGeneratedYet"
msgstr "Noch nicht generiert"
#: templates/user/realm_user_detail.jinja2:33
msgid "Password"
msgstr "Passwort"
#: templates/user/realm_user_detail.jinja2:34
msgid "UserPasswordReset"
msgstr "Nutzerpasswort zurücksetzen"
#: templates/user/realm_user_detail.jinja2:35
msgid "Phone"
msgstr "Telefon"
#: templates/user/realm_user_detail.jinja2:36
msgid "MobilePhone"
msgstr "Mobiltelefon"
#: templates/user/realm_user_detail.jinja2:47
msgid "NoneGroupAssigned"
msgstr "Keine zugewiesen"
#: templates/user/realm_user_detail.jinja2:51
msgid "AssignGroups"
msgstr "Gruppen zuweisen"
#: templates/user/realm_user_detail.jinja2:62
msgid "DeletionProcess"
msgstr "Löschvorgang"
#: templates/user/realm_user_detail.jinja2:65
msgid "CancelDeletionProcess"
msgstr "Löschvorgang abbrechen"
#: templates/user/realm_user_detail.jinja2:73
msgid "UpdateUser"
msgstr "Nutzer bearbeiten"
#: templates/user/realm_user_detail.jinja2:79
msgid "ResendWelcomeMail"
msgstr "Willkommensmail erneut senden"
#: templates/user/realm_user_update_groups.jinja2:6
msgid "UpdateGroupMembership"
msgstr "Gruppenzuweisung ändern"
#: templates/user/realm_user_update_groups.jinja2:11
msgid "UserGroupDelete"
msgstr "Gruppe entfernen"
#: templates/user/realm_user_update_groups.jinja2:30
msgid "UserGroupAdd"
msgstr "Gruppe hinzufügen"
#: templates/user/realm_user_update_groups.jinja2:50
msgid "Done"
msgstr "Fertig"
#~ msgid "RealmDeleteInformation %(realm)s %(realm_ldap_base_dn)"
#~ msgstr ""
#~ "<p>Achtung! Sie sind gerade dabei den Bereich <span class='text-uppercase "
#~ "font-weight-bold'>%(realm)s</span> zu löschen.</p><p>Falls Sie sich "
#~ "sicher sind, dass Sie diesen Bereich löschen wollen, klicken Sie bitte "
#~ "auf \"Bereich löschen\".<p>Hierdurch werden <strong>Alle</strong> Nutzer "
#~ "und Gruppen gelöscht, die unter der Ldap BasisDN %(realm_ldap_base_dn)s "
#~ "eingetragen sind. Die Ldap Basis DN mit Ihren Organisationseinheiten "
#~ "\"groups\" und \"people\" bleiben bestehen.</p><p>Bitte beachten Sie, "
#~ "dass die Daten der Nutzer, die in den Diensten hochgeladen wurden, "
#~ "weiterhin bestehen bleiben. Diese Daten müssen vom Systemadministrator "
#~ "seperat gelöscht werden. </p><p>Möchten Sie das Löschen der Accountdaten "
#~ "verhindern, klicken Sie auf \"Abbrechen\"</p>"

View File

@ -120,6 +120,10 @@
}
}
.realm-name{
text-transform: uppercase;
}
/* ------------------------------------------------------------------------------------------------------------------ */
/* -- Data Tables -- */
/* ------------------------------------------------------------------------------------------------------------------ */
@ -215,21 +219,6 @@
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 -- */
/* ------------------------------------------------------------------------------------------------------------------ */

View File

@ -3,10 +3,6 @@ const TABLE_CLASS = '.data-table';
const TABLE_CLASS_NO_PAGING = '.data-table-npaging';
$(document).ready(function () {
// Bottstrap Toast
$('.toast').toast('show');
//Datatables
const data_table = $(TABLE_CLASS).DataTable({
"paging": true,
"pageLength": 10,

View File

@ -3,7 +3,8 @@
<div class="col-12 ">
<div class="row justify-content-center justify-content-sm-center">
<div class="col-12 col-sm-8 col-md-7 col-lg-6 col-xl-5 bg-white text-dark text-center p-3 mt-5">
<p>Diese App wurde mit viel <i style="color: #DC143C;" class="fas fa-spin fa-heart"></i> von Micheal
{# TODO: Translation #}
<p>Diese App wurde mit viel <i style="color: #DC143C;" class="fas fa-spin fa-heart"></i> von Michael
Götz entwickelt.</p>
<br>
<h2>Icons</h2>

View File

@ -5,26 +5,26 @@
{% block admin_content %}
<div class="row">
<div class="col-12">
<h2>Django bekannte Nutzer
<small><a href="/admin" class="float-right h5">Django Admin Seiten</a></small>
<h2>{{ _('DjangoKnownUsers') }}
<small><a href="/admin" class="float-right h5">{{ _('DjangoAdminPages') }}</a></small>
</h2>
{{ mutils.get_warning_box(extra_errors) }}
<div class="alert alert-info">Um einen Nutzer zum Superadmin zu ernennen, klicke auf das Superadmin Icon
<div class="alert alert-info">{{ _('SuperAdminInfo') }}
</div>
<div class="table-search-field form-group w-25 float-right">
<input type="text"
class="form-control"
id="data-table-search-input">
<label for="data-table-search-input">Suche</label>
<label for="data-table-search-input">{{ _('Search') }}</label>
</div>
<table class="table table-hover table-striped table-inverse table-bordered data-table">
<thead>
<tr>
<th scope="col">Superadmin</th>
<th scope="col">Nutzername</th>
<th scope="col">E-Mail</th>
<th scope="col">Vorname</th>
<th scope="col">Nachname</th>
<th scope="col">{{ _('SuperAdmin') }}</th>
<th scope="col">{{ _('Username') }}</th>
<th scope="col">{{ _('Email') }}</th>
<th scope="col">{{ _('FirstName') }}</th>
<th scope="col">{{ _('LastName') }}</th>
</tr>
</thead>
<tbody>

View File

@ -1,4 +1,3 @@
{#{% load static %}#}
{# ===== HTML ===== #}
<!DOCTYPE html>
<html lang="en" dir="ltr">
@ -30,15 +29,18 @@
<a class="navbar-brand" href="{{ url('realm-home') }}">
<img src="{{ static('images/lama.svg') }}" width="30" height="30" class="d-inline-block align-top"
alt="">
LAMa
{# Translators: The Application Name: default LAMa #}
{{ _('AppName') }}
</a>
{% if request.user.is_authenticated %}
<span class="navbar-text">
Hi <a href="{{ url('realm-home') }}?show_user=True">{{ request.user.username }}</a>!
<a href="{{ url('logout') }}?next=/">Logout <i class="fas fa-sign-out-alt"></i></a>
{# Translators: Logout button #}
<a href="{{ url('logout') }}?next=/">{{ _('Logout') }} <i class="fas fa-sign-out-alt"></i></a>
{% else %}
<a href="{{ url('login') }}"><i class="fas fa-sign-in-alt"></i> Login</a>
{# Translators: Login Button #}
<a href="{{ url('login') }}"><i class="fas fa-sign-in-alt"></i> {{ _('Login') }}</a>
{% endif %}
</span>
</nav>
@ -47,12 +49,13 @@
{% block content %}{% endblock %}
{% endblock %}
{% if not realms and not realm and not request.user.is_superuser%}
{% if not realms and not realm and not request.user.is_superuser %}
<footer class="bg-light footer mt-auto py-3 text-center">
<div class="container">
<span class="text-muted">
<a href="{{ url('about') }}">Über</a>
{# Translators: About link title #}
<a href="{{ url('about') }}">{{ _('About') }}</a>
</span>
</div>
</footer>
@ -65,7 +68,6 @@
<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/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>
</body>

View File

@ -7,11 +7,11 @@
{% if request.user.is_superuser %}
<div class="list-group list-group-flush">
<a class="list-group-item list-group-item-action bg-light"
href="{{ url('django-additional-admin-list') }}"><i class="fas fa-crown"></i> Django Adminbereich</a>
href="{{ url('django-additional-admin-list') }}"><i class="fas fa-crown"></i> {{ _('DjangoAdminArea') }}</a>
</div>
{% endif %}
{% if realms %}
<h2 class="sidebar-heading">Bereiche</h2>
<h2 class="sidebar-heading">{{ _('Realms') }}</h2>
<div class="list-group list-group-flush">
{% for realm_item in realms %}
<a href="{{ url('realm-detail', args=[realm_item.id]) }}"
@ -21,20 +21,20 @@
{% else %}
<div class="list-group-flush">
<a href="{{ url('realm-home') }}" class="list-group-item list-group-item-action bg-light">
<i class="fas fa-list"></i> Bereichsübersicht</a>
<i class="fas fa-list"></i> {{ _('RealmOverview') }}</a>
</div>
{% if realm %}
<h2 class="sidebar-heading">Bereich {{ realm.name }}</h2>
<h2 class="sidebar-heading">{{ _('Realm') }} <span class="text-uppercase">{{ realm.name }}</span></h2>
<div class="list-group list-group-flush">
<a href="{{ url('realm-detail', args=[realm.id]) }}"
class="list-group-item list-group-item-action bg-light"><i class="fas fa-cogs"></i>
Bereichsinformationen</a>
{{ _('RealmInformation') }}</a>
<a href="{{ url('realm-user-list', args=[realm.id]) }}"
class="list-group-item list-group-item-action bg-light"><i class="fas fa-users"></i>
Nutzer</a>
{{ _('User') }}</a>
<a href="{{ url('realm-group-list', args=[realm.id]) }}"
class="list-group-item list-group-item-action bg-light"><i class="fas fa-user-friends"></i>
Gruppen</a>
{{ _('Groups') }}</a>
</div>
{% endif %}
{% endif %}
@ -43,11 +43,11 @@
<div class="list-group-item bg-light border-0"></div>
<a href="{{ url('realm-add') }}"
class="list-group-item list-group-item-action bg-light"><i class="fas fa-plus-square"></i>
Bereich hinufügen</a>
{{ _('RealmAdd') }}</a>
</div>
{% endif %}
<div class="sidebar-bottom list-group-flush border-top">
<a href="{{ url('about') }}" class="list-group-item list-group-item-action bg-light">Über</a>
<a href="{{ url('about') }}" class="list-group-item list-group-item-action bg-light">{{ _('About') }}</a>
</div>
</div>

View File

@ -3,7 +3,7 @@
{% import 'macros/utils_macros.jinja2' as uform %}
{% block detail_content %}
<h2>Gruppe anlegen</h2>
<h2>{{ _('AddGroup') }}</h2>
{% if extra_error %}
<div class="alert alert-warning">{{ extra_error }}</div>
{% endif %}
@ -15,9 +15,9 @@
{{ uform.get_data_table_search_field() }}
{{ mform.user_select_table_input(users, field=form.members) }}
<div class="d-flex mt-4">
<button type="submit" class="btn btn-primary mr-auto p-2">Speichern</button>
<button type="submit" class="btn btn-primary mr-auto p-2">{{ _('Save') }}</button>
<a href="{{ url('realm-group-list', args = [realm.id]) }}"
class="btn btn-secondary p-2">Abbrechen</a>
class="btn btn-secondary p-2">{{ _('Cancel') }}</a>
</div>
</form>
{% endblock %}

View File

@ -4,6 +4,7 @@
<div class="row justify-content-center justify-content-sm-center">
<div class="col-12 col-sm-8 col-md-7 col-lg-5 col-xl-4 bg-white text-dark p-3 mt-5">
<div class="alert alert-warning" role="alert">
{# TODO: Add translation #}
<p>Achtung! Sie sind gerade dabei die Gruppe <strong>{{ group.name }}</strong> aus dem
Bereich <strong>{{ realm.name }}</strong> zu löschen.
</p>
@ -13,9 +14,9 @@
</div>
<div class="d-flex">
<a href="{{ url('realm-group-detail', args = [realm.id, group.dn]) }}"
class="btn btn-secondary mr-auto p-2">Abbrechen</a>
class="btn btn-secondary mr-auto p-2">{{ _('Cancel') }}</a>
<a href="{{ url('realm-group-delete', args = [realm.id, group.dn]) }}"
class="btn btn-danger p-2">Gruppe löschen</a>
class="btn btn-danger p-2">{{ _('DeleteGroup') }}</a>
</div>
</div>
</div>

View File

@ -4,23 +4,25 @@
{% block detail_content %}
{% if not form %}
<h3>Gruppe {{ group.name }}</h3>
<h3>{{ _('Group') }} {{ group.name }}</h3>
<ul class="list-group list-group-flush w-100 mb-3">
<li class="list-group-item">Ldap Domain: {{ group.dn }}</li>
<li class="list-group-item">{{ _('LdapDomain') }}: {{ group.dn }}</li>
{% if group.description %}
<li class="list-group-item">Beschreibung: {{ group.description }}</li>
<li class="list-group-item">{{ _('Description') }}: {{ group.description }}</li>
{% endif %}
</ul>
<h3>Mitglieder</h3>
<h3>{{ _('Members') }}</h3>
{{ mutils.get_user_table(realm, users) }}
<div class="d-flex mt-3">
<a href="{{ url('realm-group-update', args = [realm.id, group.dn]) }}" class="btn btn-primary mr-auto p-2">
<i class="fas fa-pen-square"></i> Gruppe bearbeiten</a>
<i class="fas fa-pen-square"></i> {{ _('UpdateGroup') }}</a>
<a href="{{ url('realm-group-delete-confirm', args = [realm.id, group.dn]) }}" class="btn btn-danger p-2"><i
class="fas fa-trash"></i> <span class="d-sm-none d-md-inline-block">Gruppe löschen</span></a>
class="fas fa-trash"></i> <span
class="d-sm-none d-md-inline-block">{{ _('DeleteGroup') }}</span></a>
</div>
{% else %}
<h3>{{ _('UpdateGroup') }} {{ group.name }}</h3>
{{ mutils.get_warning_box(extra_error) }}
<form method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
@ -30,9 +32,9 @@
{{ mutils.get_data_table_search_field() }}
{{ mform.user_select_table_input(users, field=form.members) }}
<div class="d-flex mt-4">
<button type="submit" class="btn btn-primary mr-auto p-2">Speichern</button>
<button type="submit" class="btn btn-primary mr-auto p-2">{{ _('Save') }}</button>
<a href="{{ url('realm-group-detail', args = [realm.id, group.dn]) }}"
class="btn btn-secondary p-2">Abbrechen</a>
class="btn btn-secondary p-2">{{ _('Cancel') }}</a>
</div>
</form>
{% endif %}

View File

@ -299,16 +299,19 @@
id="delete-all-checkbox"
>
<label class="
{% if checkbox_label_classes %}{{ checkbox_label_classes }}{% else %}table-checkbox-control-label table-checkbox-control-label-add{% endif %}"
for="delete-all-checkbox"></label>
{% if checkbox_label_classes %}
{{ checkbox_label_classes }}
{% else %}
table-checkbox-control-label table-checkbox-control-label-add
{% endif %}" for="delete-all-checkbox"></label>
{% endif %}
</th>
<th scope="col">Nutzername</th>
<th scope="col">E-Mail</th>
<th scope="col">Vorname</th>
<th scope="col">Nachname</th>
<th scope="col">{{ _('Username') }}</th>
<th scope="col">{{ _('Email') }}</th>
<th scope="col">{{ _('FirstName') }}</th>
<th scope="col">{{ _('LastName') }}</th>
{% if show_lastlogin %}
<th scope="col">Letzter Login</th>
<th scope="col">{{ _('LastLogin') }}</th>
{% endif %}
</tr>
</thead>
@ -325,27 +328,11 @@
{% if field and field.value() and user.username in field.value() %}checked{% endif %}
>
<label class="
{% if checkbox_label_classes %}{{ checkbox_label_classes }}{% else %}table-checkbox-control-label table-checkbox-control-label-add{% endif %}"
for="{{ user.username }}_{{ loop.index }}">
{% if checkbox_label_classes %}
{{ checkbox_label_classes }}
{% else %}
table-checkbox-control-label table-checkbox-control-label-add
{% endif %}" for="{{ user.username }}_{{ loop.index }}">
</label>
</td>
<td>{{ user.username }}</td>

View File

@ -25,18 +25,18 @@
<input type="text"
class="form-control"
id="data-table-search-input">
<label for="data-table-search-input">Suche</label>
<label for="data-table-search-input">{{ _('Search') }}</label>
</div>
<table class="table table-hover table-striped table-inverse table-bordered data-table">
<thead>
<tr>
<th scope="col">Nutzername</th>
<th scope="col">E-Mail</th>
<th scope="col">Vorname</th>
<th scope="col">Nachname</th>
<th scope="col">Aktiv</th>
<th scope="col">Letzer Login</th>
<th scope="col">Löschdatum</th>
<th scope="col">{{ _('Username') }}</th>
<th scope="col">{{ _('Email') }}</th>
<th scope="col">{{ _('FirstName') }}</th>
<th scope="col">{{ _('LastName') }}</th>
<th scope="col">{{ _('Active') }}</th>
<th scope="col">{{ _('LastLogin') }}</th>
<th scope="col">{{ _('DeletionDate') }}</th>
</tr>
</thead>
<tbody>
@ -74,18 +74,18 @@
<input type="text"
class="form-control"
id="data-table-search-input">
<label for="data-table-search-input">Suche</label>
<label for="data-table-search-input">{{ _('Search') }}</label>
</div>
<table class="table table-hover table-striped table-inverse table-bordered data-table text-center">
<thead>
<tr>
<th scope="col">Bereichsname</th>
<th scope="col">Ldap Basis DN</th>
<th scope="col">Mailadresse</th>
<th scope="col">Admingruppe</th>
<th scope="col">Defaultgruppe</th>
<th scope="col">Nutzeranzahl</th>
<th scope="col">Gruppenanzahl</th>
<th scope="col">{{ _('RealmName') }}</th>
<th scope="col">{{ _('LdapBaseDN') }}</th>
<th scope="col">{{ _('MailAddress') }}</th>
<th scope="col">{{ _('AdminGroup') }}</th>
<th scope="col">{{ _('DefaultGroup') }}</th>
<th scope="col">{{ _('UserCount') }}</th>
<th scope="col">{{ _('GroupCount') }}</th>
</tr>
</thead>
<tbody>
@ -119,7 +119,6 @@
<td>{{ realm_wrapper.user_count }}</td>
<td>{{ realm_wrapper.group_count }}</td>
</tr>
{% endfor %}
</tbody>
</table>
@ -131,35 +130,12 @@
{% endif %}
{% 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") -%}
<div class="form-group w-25 float-right">
<input type="text"
class="form-control"
id="{{ input_id }}">
<label for="{{ input_id }}">Suche</label>
<label for="{{ input_id }}">{{ _('Search') }}</label>
</div>
{% endmacro %}

View File

@ -5,7 +5,7 @@
<div class="col-12 ">
<div class="row justify-content-center justify-content-sm-center">
<div class="col-12 col-sm-8 col-md-7 col-lg-5 col-xl-4 bg-white text-dark text-center p-3 mt-5">
<p>Leider hast du keine Rechte :´(</p>
<p>{{ _('PermissionDeniedInfo') }}</p>
{{ mutils.get_warning_box(extra_errors) }}
<a href="{{ url('realm-home') }}">Zurück zur Startseite</a>
</div>

View File

@ -6,12 +6,14 @@
<div class="row justify-content-center justify-content-sm-center">
<div class="col-12 col-sm-8 col-md-8 col-lg-6 col-xl-5 bg-white text-dark p-3 mt-5">
{% if request.user.is_superuser %}
<h2>Neuen Bereich anlegen</h2>
{# Translators: Is the Headline of the create new realm view #}
<h2>{{ _('CreateNewRealm') }}</h2>
<form method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{ mform.text_input(form.name) }}
{{ mform.text_input(form.ldap_base_dn) }}
<button type="submit" class="btn btn-primary btn-block">Anlegen</button>
{# Translators: the submit button text for the create new realm form#}
<button type="submit" class="btn btn-primary btn-block">{{ _('CreateRealm') }}</button>
</form>
{% endif %}
</div>

View File

@ -2,13 +2,13 @@
{% block admin_content %}
<div class="row ">
<div class="col-12 p-3">
<h1>Fehler {{ realm_name }}</h1>
<h1>{{ _('AddRealmError') }} <span class="realm-name">{{ realm_name }}</span></h1>
<div class="alert alert-danger">
<p>Das hinzufügen des Bereichs ist fehlgeschlagen.</p>
<p>{{ _('AddRealmErrorInfo') }}</p>
{% if error %}
<p>{{ error }}</p>
{% else %}
<p>Bitte überprüfe den Ldap base dn, ob dieser auch wirklich existiert.</p>
<p>{{ _('AddRealmErrorLdapInfo') }}</p>
{% endif %}
</div>
</div>

View File

@ -3,15 +3,19 @@
<div class="col-12 ">
<div class="row justify-content-center justify-content-sm-center">
<div class="col-12 col-sm-8 col-md-7 col-lg-5 col-xl-4 bg-white text-dark p-3 mt-5">
<h1>Löschen des Bereichs
{# Translators: The Application Name: default LAMa #}
<h1>{{ _('RealmDelete') }}
<span class="text-uppercase font-weight-bold">{{ realm.name }}</span></h1>
<div class="alert alert-warning" role="alert">
{# Translators: The Application Name: default LAMa #}
{# {{ gettext('RealmDeleteInformation %(realm)s %(realm_ldap_base_dn)')|safe|format(realm=realm, realm_ldap_base_dn=realm.ldap_base_dn) }}#}
<p>Achtung! Sie sind gerade dabei den Bereich <span
class="text-uppercase font-weight-bold">{{ realm.name }}</span> zu löschen.</p>
class="text-uppercase font-weight-bold">{{ realm }}</span> zu löschen.</p>
<p>Falls Sie sich sicher sind, dass Sie diesen Bereich löschen wollen, klicken Sie bitte auf
"Bereich löschen".
<p>Hierdurch werden <strong>Alle</strong> Nutzer und Gruppen gelöscht, die unter der Ldap Basis
DN {{ realm.ldap_base_dn }} eingetragen sind. Die Ldap Basis DN mit Ihren Organisationseinheiten
DN {{ realm.ldap_base_dn }} eingetragen sind. Die Ldap Basis DN mit Ihren
Organisationseinheiten
"groups" und "people" bleiben bestehen.</p>
<p>Bitte beachten Sie, dass die Daten der Nutzer, die in den
Diensten hochgeladen wurden, weiterhin bestehen bleiben. Diese Daten müssen vom
@ -20,9 +24,9 @@
</div>
<div class="d-flex">
<a href="{{ url('realm-detail', args = [realm.id]) }}"
class="btn btn-secondary mr-auto p-2">Abbrechen</a>
class="btn btn-secondary mr-auto p-2"> {{ _('RealmDeleteCancel') }}</a>
<a href="{{ url('realm-delete', args = [realm.id]) }}"
class="btn btn-danger p-2">Bereich löschen</a>
class="btn btn-danger p-2"> {{ _('RealmDeleteAgree') }}</a>
</div>
</div>
</div>

View File

@ -1,11 +0,0 @@
{% extends 'realm/realm_detailed.jinja2' %}
{% block realm_form %}
<h2>Email Account erstellen oder updaten</h2>
{% if form %}
<form method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{ form.as_p()|safe }}
<button type="submit">Speichern</button>
</form>
{% endif %}
{% endblock %}

View File

@ -1,87 +1,63 @@
{% extends 'base_admin.jinja2' %}
{% import 'macros/utils_macros.jinja2' as mutils %}
{% block admin_content %}
<div class="row ">
<div class="col-12 p-3">
<h1>Bereich <span style="text-transform: uppercase">{{ realm.name }}</span>
<h1> {{ _('Realm') }} <span style="text-transform: uppercase">{{ realm.name }}</span>
<small>
{% if request.user.is_superuser %}
<a href="{{ url('realm-delete-confirm', args=[realm.id]) }}"
class="h5 realm-delete-link"><i class="fas fa-dumpster"></i> <span
class="d-none d-md-inline-block">Bereich löschen</span></a>
class="d-none d-md-inline-block"> {{ _('RealmDetailRemoveRealm') }}</span></a>
{% endif %}
</small>
</h1>
{% if notice %}
<p style="color: green">{{ notice }}</p>
{% endif %}
{% if error %}
<p style="color: darkred">{{ error }}</p>
{% endif %}
{% if notice %}<p style="color: green">{{ notice }}</p>{% endif %}
{% if error %}<p style="color: darkred">{{ error }}</p>{% endif %}
{% block detail_content %}
{{ mutils.get_success_toast(success_headline, success_text, error_headline, error_text) }}
<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">Nutzeranzahl (Aktive/Inaktive): {{ users_count }}
<li class="list-group-item"> {{ _('RealmDetailLdapOU') }}: {{ realm.ldap_base_dn }}</li>
<li class="list-group-item"> {{ _('RealmDetailUserCount') }}: {{ users_count }}
({{ users_count-inactive_user_count }}/{{ inactive_user_count }})
<a
href="{{ url('realm-multiple-user-delete-inactive', args=[realm.id]) }}"
class="float-right">
Inaktive Nutzer löschen
{{ _('RealmDetailRemoveInactiveUser') }}
</a>
</li>
{% if realm.email %}
<li class="list-group-item">Email: {{ realm.email }}</li>
{% else %}
<li class="list-group-item">Email: <span class="text-danger">Noch ausstehend</span></li>
{% endif %}
{% if realm.admin_group %}
<li class="list-group-item">Admin Gruppe: <a
href="{{ url('realm-group-detail', args=[realm.id, ldap_admin_group.dn]) }}"
class="badge badge-primary p-2">
{{ realm.admin_group }}</a></li>
{% else %}
<li class="list-group-item">Admin Gruppe: <span class="text-warning">Noch ausstehend</span></li>
{% endif %}
{% if realm.default_group %}
<li class="list-group-item">Default Gruppe: <a
href="{{ url('realm-group-detail', args=[realm.id, ldap_default_group.dn]) }}"
class="badge badge-secondary p-2">
{{ realm.default_group }}</a>
</li>
{% else %}
<li class="list-group-item">Default Gruppe: <span class="text-warning">Noch ausstehend</span>
</li>
{% endif %}
<li class="list-group-item">{{ _('Email') }}:
{% if realm.email %}{{ realm.email }}{% else %}
<span class="text-danger">{{ _('RealmDetailStillPending') }}</span>{% endif %}
</li>
<li class="list-group-item">{{ _('RealmDetailAdminGroup') }}:
{% if realm.admin_group %}
<a href="{{ url('realm-group-detail', args=[realm.id, ldap_admin_group.dn]) }}"
class="badge badge-primary p-2">{{ realm.admin_group }}</a>
{% else %}
<span class="text-warning">{{ _('RealmDetailStillPending') }}</span>
{% endif %}
</li>
<li class="list-group-item">{{ _('RealmDetailDefaultGroup') }}:
{% if realm.default_group %}
<a href="{{ url('realm-group-detail', args=[realm.id, ldap_default_group.dn]) }}"
class="badge badge-secondary p-2">{{ realm.default_group }}</a>
{% else %}
<span class="text-warning">{{ _('RealmDetailStillPending') }}</span>
{% endif %}
</li>
</ul>
<div class="d-flex mt-3">
{% if request.user.is_superuser %}
<a href="{{ url('realm-update', args=[realm.id]) }}" class="btn btn-primary mr-auto p-2"><i
class="fas fa-info-circle"></i> Bereichsinformationen
anpassen</a>
class="fas fa-info-circle"></i> {{ _('RealmDetailChangeRealmInfo') }}</a>
{% if realm.email %}
<a href="{{ url('realm-mail-test', args=[realm.id]) }}" class="btn btn-secondary p-2"><i
class="fas fa-paper-plane"></i> Test Mail</a>
class="fas fa-paper-plane"></i> {{ _('RealmDetailTestMail') }}</a>
{% endif %}
{% endif %}
</div>
{% block realm_form %}
{% endblock %}
{% endblock %}
{# <h2><a href="{{ url('realm-user-add', args=[realm.id]) }}">Nutzer hinzufügen</a></h2>#}
{# {% block user_content %}#}
{# <h2><a href="{{ url('realm-user-list', args=[realm.id]) }}">Nutzer</a></h2>#}
{# {% endblock %}#}
{# <h2><a href="{{ url('realm-group-add', args=[realm.id]) }}">Gruppen hinzufügen</a></h2>#}
{# {% block groups_content %}#}
{# <h2><a href="{{ url('realm-group-list', args=[realm.id]) }}">Gruppen</a></h2>#}
{# {% endblock %}#}
{# {% block extra_content %}#}
{# {% endblock %}#}
</div>
</div>
{% endblock %}

View File

@ -1,13 +1,13 @@
{% extends 'realm/realm_detailed.jinja2' %}
{% block detail_content %}
<h3>Gruppen</h3>
<h3>{{ _('Groups') }}</h3>
<table class="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Ldap Domain</th>
<th scope="col">Mitgliederanzahl</th>
<th scope="col">{{ _('Name') }}</th>
<th scope="col">{{ _('Description') }}</th>
<th scope="col">{{ _('MemberCount') }}</th>
</tr>
</thead>
<tbody>
@ -19,12 +19,14 @@
title="{{ group.description }}"
>{{ group.name }}</a>
</td>
<td>{{ group.dn }}</td>
<td data-toggle="tooltip"
data-placement="right"
title="{{ group.description }}">{{ group.description|truncate(100) }}</td>
<td>{{ group.members|length }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{{ url('realm-group-add', args=[realm.id]) }}" class="btn btn-primary"><i class="far fa-plus-square"></i>
Gruppen hinzufügen</a>
{{ _('AddGroups') }}</a>
{% endblock %}

View File

@ -3,12 +3,12 @@
{% import 'macros/utils_macros.jinja2' as mutils %}
{% block admin_content %}
<h2>Bereiche</h2>
<h2>{{ _('Realms') }}</h2>
{{ mutils.get_realm_table(realm_wrappers) }}
{% if request.user.is_superuser %}
<div class="row justify-content-center justify-content-sm-center">
<div class="col-12 col-sm-8 col-md-8 col-lg-6 col-xl-5 bg-white text-dark p-3 mt-5">
<a href="{{ url('realm-add') }}" class="btn btn-primary w-100">Bereich hinzufügen</a>
<a href="{{ url('realm-add') }}" class="btn btn-primary w-100">{{ _('RealmAdd') }}</a>
</div>
</div>
{% endif %}

View File

@ -11,9 +11,9 @@
{{ mform.select_input(form.admin_group) }}
{{ mform.select_input(form.default_group) }}
<div class="d-flex mt-4">
<button type="submit" class="btn btn-primary mr-auto p-2">Speichern</button>
<button type="submit" class="btn btn-primary mr-auto p-2">{{ _('Save') }}</button>
<a href="{{ url('realm-detail', args = [realm.id]) }}"
class="btn btn-secondary p-2">Abbrechen</a>
class="btn btn-secondary p-2">{{ _('Cancel') }}</a>
</div>
</form>
{% endif %}

View File

@ -2,11 +2,10 @@
{% import 'macros/utils_macros.jinja2' as mutils %}
{% block detail_content %}
<h2>Nutzer </h2>
<h2>{{ _('User') }}</h2>
{{ mutils.get_user_table(realm, realm_user) }}
<a href="{{ url('realm-user-add', args=[realm.id]) }}" class="btn btn-primary"><i class="fas fa-user-plus"></i>
Nutzer hinzufügen</a>
{{ _('AddUser') }}</a>
<a href="{{ url('realm-multiple-user-delete-confirm', args=[realm.id]) }}" class="btn btn-danger float-right"><i
class="fas fa-trash"></i> Mehrere Nutzer
Löschen</a>
class="fas fa-trash"></i> {{ _('RemoveMultipleUser') }}</a>
{% endblock %}

View File

@ -3,13 +3,11 @@
{% import 'macros/utils_macros.jinja2' as mutils %}
{% block detail_content %}
<h2>Nutzer löschen</h2>
<h2>{{ _('DeleteUser') }}</h2>
{{ mutils.get_warning_box(extra_errors) }}
{% 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>
{{ _('MultipleUserDeleteError')|safe }}
<ul>
{% for blocked_user in blocked_users %}
<li>{{ blocked_user.username }}</li>
@ -22,15 +20,15 @@
class="form-control"
placeholder="Personen Suche"
id="data-table-search-input">
<label for="data-table-search-input">Suche</label>
<label for="data-table-search-input">{{ _('Search') }}Suche</label>
</div>
<form action="{{ url('realm-multiple-user-delete', args=[realm.id]) }}" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{ mform.user_select_table_input(users=[], deletable_users=deletable_users, blocked_users=blocked_users, name="ldap_users",css_classes='',show_lastlogin=True, checkbox_label_classes='table-checkbox-control-label') }}
<div class="d-flex mt-4">
<button type="submit" class="btn btn-danger mr-auto p-2">Ausführen</button>
<button type="submit" class="btn btn-danger mr-auto p-2">{{ _('Execute') }}</button>
<a href="{{ url('realm-user-list', args = [realm.id]) }}"
class="btn btn-secondary p-2">Abbrechen</a>
class="btn btn-secondary p-2">{{ _('Cancel') }}</a>
</div>
</form>
{% endblock %}

View File

@ -2,21 +2,21 @@
{% import 'macros/form_macros.jinja2' as mform %}
{% block detail_content %}
<h2>Nutzer löschen</h2>
<h2>{{ _('DeleteUser') }}</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>
<label for="data-table-search-input">{{ _('Search') }}</label>
</div>
<form action="{{ url('realm-multiple-user-delete-confirm', args=[realm.id]) }}" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{ mform.user_select_table_input(users, name="ldap_users",css_classes='',show_lastlogin=True, checkbox_label_classes='table-checkbox-control-label') }}
<div class="d-flex mt-4">
<button type="submit" class="btn btn-danger mr-auto p-2">Ausführen</button>
<button type="submit" class="btn btn-danger mr-auto p-2">{{ _('Execute') }}</button>
<a href="{{ url('realm-user-list', args = [realm.id]) }}"
class="btn btn-secondary p-2">Abbrechen</a>
class="btn btn-secondary p-2">{{ _('Cancel') }}</a>
</div>
</form>
{% endblock %}

View File

@ -1,33 +1,22 @@
{% extends 'base.jinja2' %}
{% import 'macros/form_macros.jinja2' as mform %}
{% block content %}
<div class="col-12 ">
<div class="row justify-content-center justify-content-sm-center">
<div class="col-12 col-sm-8 col-md-7 col-lg-5 col-xl-4 bg-white text-dark p-3 mt-5 border">
<h1 class="mb-4">Passwort ändern</h1>
<form method="post" class="floating-label-form">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<!-- {{form.errors}}-->
<input type="password"
class="form-control"
placeholder="Old password"
aria-describedby="id_old_password_help"
name="old_password"
id="id_old_password"
maxlength="None"
value="ralf"
hidden>
<!-- {{ mform.password_input(form.old_password) }}-->
{{ mform.password_input(form.new_password1) }}
{{ mform.password_input(form.new_password2) }}
<div class="d-flex mt-4">
<button type="submit" class="btn btn-primary mr-auto p-2">Speichern</button>
<a href="{{ url('realm-home')}}"
class="btn btn-secondary p-2">Abbrechen</a>
</div>
</form>
<div class="col-12 ">
<div class="row justify-content-center justify-content-sm-center">
<div class="col-12 col-sm-8 col-md-7 col-lg-5 col-xl-4 bg-white text-dark p-3 mt-5 border">
<h1 class="mb-4">Passwort ändern</h1>
<form method="post" class="floating-label-form">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{{ mform.password_input(form.old_password) }}
{{ mform.password_input(form.new_password1) }}
{{ mform.password_input(form.new_password2) }}
<div class="d-flex mt-4">
<button type="submit" class="btn btn-primary mr-auto p-2">Speichern</button>
<a href="{{ url('realm-home')}}"
class="btn btn-secondary p-2">Abbrechen</a>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -5,6 +5,7 @@
<div class="col-12 col-sm-8 col-md-7 col-lg-5 col-xl-4 bg-white text-dark p-3 mt-5">
<div class="alert alert-info" role="alert">
<p>
{# TODO: Translation #}
Ihr Account im Bereich {{ realm.name }} und Ihre Gruppenzugehörigkeiten wurden erfolgreich
gelöscht.
</p>

View File

@ -2,19 +2,18 @@
{% import 'macros/form_macros.jinja2' as mform %}
{% block detail_content %}
<h2>Nutzer anlegen</h2>
<h2>{{ _('AddUser') }}</h2>
{% if extra_error %}
<div class="alert alert-warning">{{ extra_error }}</div>
{% endif %}
<form action="{{ url('realm-user-add', args=[realm.id]) }}" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
{# {{ form.as_p() }}#}
{{ mform.text_input(form.username) }}
{{ mform.email_input(form.email) }}
<div class="d-flex mt-4">
<button type="submit" class="btn btn-primary mr-auto p-2">Speichern</button>
<button type="submit" class="btn btn-primary mr-auto p-2">{{ _('Save') }}</button>
<a href="{{ url('realm-user-list', args = [realm.id]) }}"
class="btn btn-secondary p-2">Abbrechen</a>
class="btn btn-secondary p-2">{{ _('Cancel') }}</a>
</div>
</form>
{% endblock %}

View File

@ -1,12 +1,11 @@
{% extends 'realm/realm_detailed.jinja2' %}
{% import 'macros/form_macros.jinja2' as mform %}
{% import 'macros/utils_macros.jinja2' as mutils %}
{% block detail_content %}
{{ mutils.get_success_toast(success_headline, success_text) }}
{% if user.user %}
{% if user.deleted_user.deletion_date %}
<h3 class="text-danger">{{ user.user.username }}
{# TODO: translate #}
<small>Nutzer wird vorraussichtlich am {{ user.deleted_user.deletion_date.strftime('%d.%m.%Y') }}
gelöscht
</small>
@ -20,31 +19,22 @@
{% endif %}
{% if not form %}
<ul class="list-group list-group-flush w-100">
<li class="list-group-item">Ldap Domain: {{ user.user.dn }}</li>
<li class="list-group-item"> Anzeigename:
<li class="list-group-item">{{ _('LdapDomain') }}: {{ user.user.dn }}</li>
<li class="list-group-item">{{ _('UserDisplayName') }}
{% if user.user.display_name %}
{{ user.user.display_name }}
{% else %}
<span class="text-warning"> Noch nicht generiert </span>
<span class="text-warning"> {{ _('NotGeneratedYet') }}</span>
{% endif %}
</li>
{% if user.user.phone %}
<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">Passwort: <a
href="{{ url('realm-user-password-reset', args = [realm.id, user.user.dn]) }}" class="float-right">Nutzerpasswort
zurücksetzen</a></li>
{% if user.user.phone %}
<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">{{ _('FirstName') }}: {{ user.user.first_name }}</li>
<li class="list-group-item">{{ _('LastName') }}: {{ user.user.last_name }}</li>
<li class="list-group-item">{{ _('Email') }}: {{ user.user.email }}</li>
<li class="list-group-item">{{ _('Password') }}: <a
href="{{ url('realm-user-password-reset', args = [realm.id, user.user.dn]) }}" class="float-right">{{ _('UserPasswordReset') }}</a></li>
<li class="list-group-item">{{ _('Phone') }}: {{ user.user.phone }}</li>
<li class="list-group-item">{{ _('MobilePhone') }}: {{ user.user.mobile_phone }}</li>
<li class="list-group-item">{{ _('Groups') }}:
{% if groups %}
{% for group in groups %}
<a href="{{ url('realm-group-detail', args=[realm.id, group.dn]) }}"
@ -54,14 +44,14 @@
class="badge badge-secondary p-1">{{ group.name }}</a>
{% endfor %}
{% else %}
<span class="text-warning">Keine zugewiesen</span>
<span class="text-warning">{{ _('NoneGroupAssigned') }}</span>
{% endif %}
{% if not user.deleted_user.deletion_date %}
<a href="{{ url('realm-user-group-update', args=[realm.id, user.user.dn]) }}" class="float-right">
Gruppen zuweisen</a>
{{ _('AssignGroups') }}</a>
{% endif %}
</li>
<li class="list-group-item">Zuletzt eingeloggt:
<li class="list-group-item">{{ _('LastLogin') }}:
{% if user.user.last_login %}
{{ user.user.last_login.strftime('%d.%m.%Y') }}
{% else %}
@ -69,10 +59,10 @@
{% endif %}</li>
{% if user.deleted_user.deletion_date %}
<li class="list-group-item text-danger">
Löschvorgang: {{ user.deleted_user.deletion_date.strftime('%d.%m.%Y') }}
{{ _('DeletionProcess') }}: {{ user.deleted_user.deletion_date.strftime('%d.%m.%Y') }}
<a href="{{ url('realm-user-delete-cancel', args=[realm.id, user.user.dn]) }}"
class="float-right">
Löschvorgang abbrechen</a>
{{ _('CancelDeletionProcess') }}</a>
</li>
{% endif %}
</ul>
@ -80,19 +70,19 @@
{% if not user.deleted_user.deletion_date %}
<a href="{{ url('realm-user-update', args = [realm.id, user.user.dn]) }}"
class="btn btn-primary mr-auto p-2">
<i class="fas fa-user-cog"></i> Nutzer bearbeiten
<i class="fas fa-user-cog"></i> {{ _('UpdateUser') }}
</a>
{% if not user.user.last_login %}
<a href="{{ url('realm-user-resend-welcome-mail', args = [realm.id, user.user.dn]) }}"
class="btn btn-secondary p-2 mr-2">
<i class="fas fa-paper-plane"></i> Wilkommensmail erneut senden
<i class="fas fa-paper-plane"></i> {{ _('ResendWelcomeMail') }}
</a>
{% endif %}
<a href="{{ url('realm-user-delete-confirm', args = [realm.id, user.user.dn]) }}"
class="btn btn-danger p-2">
<i class="fas fa-trash"></i> Nutzer löschen
<i class="fas fa-trash"></i> {{ _('DeleteUser') }}
</a>
{% endif %}
</div>
@ -104,9 +94,9 @@
{{ mform.text_input(form.first_name) }}
{{ mform.text_input(form.last_name) }}
<div class="d-flex mt-4">
<button type="submit" class="btn btn-primary mr-auto p-2">Speichern</button>
<button type="submit" class="btn btn-primary mr-auto p-2">{{ _('Save') }}</button>
<a href="{{ url('realm-user-detail', args = [realm.id, user.dn]) }}"
class="btn btn-secondary p-2">Abbrechen</a>
class="btn btn-secondary p-2">{{ _('Cancel') }}</a>
</div>
</form>
{% endif %}

View File

@ -3,12 +3,12 @@
{% import 'macros/utils_macros.jinja2' as mutils %}
{% block detail_content %}
<h3><span class="text-uppercase">{{ user.username }}</span> - Gruppenzuweisung ändern</h3>
<h3><span class="text-uppercase">{{ user.username }}</span> - {{ _('UpdateGroupMembership') }}</h3>
{{ mutils.get_warning_box(extra_error) }}
<div class="row">
<div class="col-6">
<form method="post" action="{{ url('realm-user-group-update-delete', args = [realm.id, user.dn]) }}">
<button type="submit" class="btn btn-warning w-100 mb-2"><i class="fas fa-minus-square"></i> Entfernen
<button type="submit" class="btn btn-warning w-100 mb-2"><i class="fas fa-minus-square"></i> {{ _('UserGroupDelete') }}
</button>
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<ul>
@ -27,7 +27,7 @@
</div>
<div class="col-6">
<form method="post" action="{{ url('realm-user-group-update-add', args = [realm.id, user.dn]) }}">
<button type="submit" class="btn btn-success w-100 mb-2"><i class="fas fa-plus-square"></i> Hinzufügen
<button type="submit" class="btn btn-success w-100 mb-2"><i class="fas fa-plus-square"></i> {{ _('UserGroupAdd') }}
</button>
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<ul>
@ -47,6 +47,6 @@
</div>
<div class="mt-4">
<a href="{{ url('realm-user-detail', args = [realm.id, user.dn]) }}"
class="btn btn-primary p-2 float-right w-25">Fertig</a>
class="btn btn-primary p-2 float-right w-25">{{ _('Done') }}</a>
</div>
{% endblock %}

View File

@ -7,6 +7,7 @@
<div class="row justify-content-center justify-content-sm-center">
<div class="col-12 col-sm-8 col-md-7 col-lg-5 col-xl-4 bg-white text-dark p-3 mt-5">
<div class="alert alert-warning" role="alert">
{# TODO: Translation #}
<p><strong>Achtung!</strong> Sie sind gerade dabei den Account von <strong>{{ user.username }}</strong> zu schließen.
</p>
<p>Falls Sie sich sicher sind, dass Sie diesen Nutzer löschen wollen, klicken Sie bitte auf "Nutzer
@ -21,9 +22,9 @@
</div>
<div class="d-flex">
<a href="{{ url(cancel_link.name, args = cancel_link.args) }}"
class="btn btn-secondary mr-auto p-2">Abbrechen</a>
class="btn btn-secondary mr-auto p-2">{{ _('Cancel') }}</a>
<a href="{{ url(deletion_link.name, args = deletion_link.args) }}"
class="btn btn-danger p-2">Nutzer löschen</a>
class="btn btn-danger p-2">{{ _('DeleteUser') }}</a>
</div>
</div>
</div>

View File

@ -32,7 +32,7 @@
class="font-weight-bold">Email:</span> {{ user.user.email }}</li>
<li class="list-group-item"><span
class="font-weight-bold">Passwort:</span> <a
href="{{ url('password_change_controller') }}">Passwort ändern</a>
href="{{ url('password_change') }}">Passwort ändern</a>
</li>
<li class="list-group-item"><span
class="font-weight-bold">Telefon:</span> {{ user.user.phone }}</li>