Fix compatibility with Django 2.2 and other dependencies

- drop mockldap in favour of volatildap
- fix URLs and settings
- fix tests
This commit is contained in:
Jan Dittberner 2020-03-02 15:40:08 +01:00
parent c4485945fc
commit 427fdd9c03
15 changed files with 106 additions and 197 deletions

1
.gitignore vendored
View file

@ -44,3 +44,4 @@ _build/
.coverage
coverage-report/
.idea/
.env

View file

@ -4,10 +4,7 @@ This module defines the Celery_ app for gvaldap.
.. _Celery: http://www.celeryproject.org/
"""
from __future__ import absolute_import
import os
from celery import Celery
from django.conf import settings
@ -15,12 +12,12 @@ from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE',
'gvaldap.settings.production')
app = Celery('gvaldap')
def get_installed_apps():
return settings.INSTALLED_APPS
app.config_from_object('django.conf:settings')
app.autodiscover_tasks(get_installed_apps)

View file

@ -2,16 +2,13 @@
This module provides tests for :py:mod:`ldaptasks.tasks`.
"""
from __future__ import absolute_import
import volatildap
from django.conf import settings
from django.test import TestCase
from celery.exceptions import Reject
from mockldap import MockLdap
from ldapentities.models import LdapUser
from ldaptasks.tasks import (
from gvaldap.ldaptasks.tasks import (
add_ldap_user_to_group,
create_ldap_group,
create_ldap_user,
@ -25,9 +22,13 @@ from ldaptasks.tasks import (
class LdapTaskTestCase(TestCase):
databases = ["default", "ldap"]
directory = {
settings.DATABASES['ldap']['USER']: {
'userPassword': [settings.DATABASES['ldap']['PASSWORD']]
'objectClass': ['person'],
'userPassword': [settings.DATABASES['ldap']['PASSWORD']],
'sn': 'Admin',
},
settings.GROUP_BASE_DN: {
'objectClass': ['top', 'organizationalUnit'],
@ -59,19 +60,23 @@ class LdapTaskTestCase(TestCase):
@classmethod
def setUpClass(cls):
cls.mockldap = MockLdap(cls.directory)
super(LdapTaskTestCase, cls).setUpClass()
cls.ldap_server = volatildap.LdapServer(
initial_data=cls.directory,
schemas=['core.schema', 'cosine.schema', 'inetorgperson.schema',
'nis.schema'],
)
settings.DATABASES['ldap']['USER'] = cls.ldap_server.rootdn
settings.DATABASES['ldap']['PASSWORD'] = cls.ldap_server.rootpw
settings.DATABASES['ldap']['NAME'] = cls.ldap_server.uri
@classmethod
def tearDownClass(cls):
del cls.mockldap
cls.ldap_server.stop()
super(LdapTaskTestCase, cls).tearDownClass()
def setUp(self):
self.mockldap.start()
self.ldapobj = self.mockldap[settings.DATABASES['ldap']['NAME']]
def tearDown(self):
self.mockldap.stop()
del self.ldapobj
self.ldap_server.start()
def test_create_ldap_group(self):
result = create_ldap_group('test', 5000, 'test group')
@ -79,9 +84,6 @@ class LdapTaskTestCase(TestCase):
'groupname': 'test', 'gid': 5000, 'description': 'test group',
'group_dn': 'cn=test,%s' % settings.GROUP_BASE_DN
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'add_s'
])
def test_create_ldap_group_existing(self):
result = create_ldap_group('existing', 4711, 'existing test group')
@ -90,10 +92,6 @@ class LdapTaskTestCase(TestCase):
'description': 'existing test group',
'group_dn': 'cn=existing,%s' % settings.GROUP_BASE_DN
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'search_s'
])
def test_create_ldap_group_existing_modify(self):
result = create_ldap_group(
@ -103,10 +101,6 @@ class LdapTaskTestCase(TestCase):
'description': 'change existing test group',
'group_dn': 'cn=existing,%s' % settings.GROUP_BASE_DN
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s',
'search_s', 'search_s', 'modify_s'
])
def test_create_ldap_user(self):
result = create_ldap_user(
@ -117,19 +111,12 @@ class LdapTaskTestCase(TestCase):
'homedir': '/home/test', 'shell': '/bin/bash',
'user_dn': 'uid=test,%s' % settings.USER_BASE_DN
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'add_s', 'search_s', 'search_s', 'modify_s'
])
def test_create_ldap_user_invalid_group(self):
with self.assertRaises(Reject):
create_ldap_user(
'test', 5000, 5000, 'Test User', '/home/test', '/bin/bash',
'secret')
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s'
])
def test_create_ldap_user_no_password(self):
result = create_ldap_user(
@ -140,10 +127,6 @@ class LdapTaskTestCase(TestCase):
'homedir': '/home/test', 'shell': '/bin/bash',
'user_dn': 'uid=test,%s' % settings.USER_BASE_DN
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'add_s', 'search_s', 'search_s', 'modify_s'
])
def test_create_ldap_user_existing(self):
result = create_ldap_user(
@ -151,44 +134,29 @@ class LdapTaskTestCase(TestCase):
'/bin/bash', 'secret'
)
self.assertEqual({
'username': 'existing', 'uid': 815, 'gid': 4711,
'username': 'existing', 'uid': 815, 'gid': 4711,
'gecos': 'existing test user', 'homedir': '/home/existing',
'shell': '/bin/bash',
'user_dn': u'uid=existing,%s' % settings.USER_BASE_DN
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'search_s', 'search_s', 'search_s', 'modify_s'
])
def test_set_ldap_user_password_existing(self):
result = set_ldap_user_password('existing', 'newpassword')
self.assertEqual({
'username': 'existing', 'password_set': True
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'search_s', 'modify_s'
])
def test_set_ldap_user_password_missing(self):
result = set_ldap_user_password('missing', 'newpassword')
self.assertEqual({
'username': 'missing', 'password_set': False
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s'
])
def test_add_ldap_user_to_group_existing(self):
result = add_ldap_user_to_group('existing', 'existing')
self.assertEqual({
'username': 'existing', 'groupname': 'existing', 'added': True
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'search_s'
])
def test_add_ldap_user_to_group_new_user(self):
create_ldap_group('test', 5000, 'test group')
@ -196,39 +164,24 @@ class LdapTaskTestCase(TestCase):
self.assertEqual({
'username': 'existing', 'groupname': 'test', 'added': True
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'add_s', 'search_s',
'search_s', 'search_s', 'search_s', 'search_s', 'search_s',
'modify_s'
])
def test_add_ldap_user_to_group_no_group(self):
result = add_ldap_user_to_group('existing', 'test')
self.assertEqual({
'username': 'existing', 'groupname': 'test', 'added': False
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s'
])
def test_add_ldap_user_to_group_no_user(self):
with self.assertRaises(LdapUser.DoesNotExist):
add_ldap_user_to_group('test', 'existing')
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s'
])
def test_remove_ldap_user_from_group_existing(self):
result = remove_ldap_user_from_group('existing', 'existing')
self.assertEqual({
'username': 'existing', 'groupname': 'existing', 'removed': True
}, result)
self.assertNotIn('memberUid', self.ldapobj.directory[
'cn=existing,' + settings.GROUP_BASE_DN])
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'search_s', 'search_s', 'search_s', 'modify_s'
])
self.assertNotIn('memberUid', self.ldap_server.get(
'cn=existing,' + settings.GROUP_BASE_DN))
def test_remove_ldap_user_from_group_not_in_group(self):
create_ldap_group('test', 5000, 'test group')
@ -236,123 +189,75 @@ class LdapTaskTestCase(TestCase):
self.assertEqual({
'username': 'existing', 'groupname': 'test', 'removed': False
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'add_s', 'search_s',
'search_s', 'search_s', 'search_s'
])
def test_remove_ldap_user_from_group_no_group(self):
result = remove_ldap_user_from_group('existing', 'test')
self.assertEqual({
'username': 'existing', 'groupname': 'test', 'removed': False
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s'
])
def test_remove_ldap_user_from_group_no_user(self):
result = remove_ldap_user_from_group('test', 'existing')
self.assertEqual({
'username': 'test', 'groupname': 'existing', 'removed': False
}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s'
])
def test_delete_ldap_user_existing(self):
result = delete_ldap_user('existing')
self.assertEqual({'username': 'existing', 'deleted': True}, result)
self.assertNotIn(
'uid=existing,' + settings.USER_BASE_DN, self.ldapobj.directory)
self.assertNotIn('memberUid', self.ldapobj.directory[
'cn=existing,' + settings.GROUP_BASE_DN])
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'search_s', 'search_s', 'search_s', 'modify_s', 'delete_s'
])
with self.assertRaises(KeyError):
self.ldap_server.get('uid=existing,' + settings.USER_BASE_DN)
self.assertNotIn('memberUid', self.ldap_server.get(
'cn=existing,' + settings.GROUP_BASE_DN))
def test_delete_ldap_user_missing(self):
result = delete_ldap_user('missing')
self.assertEqual({'username': 'missing', 'deleted': False}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s'
])
def test_delete_ldap_user_no_group(self):
self.ldapobj.directory[
'uid=existing,' + settings.USER_BASE_DN]['gidNumber'] = ['5000']
self.ldap_server.get('uid=existing,' + settings.USER_BASE_DN)[
'gidNumber'] = '5000'
result = delete_ldap_user('existing')
self.assertEqual({'username': 'existing', 'deleted': True}, result)
self.assertNotIn(
'uid=existing,' + settings.USER_BASE_DN, self.ldapobj.directory)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'delete_s'
])
def test_delete_ldap_user_not_in_group(self):
del self.ldapobj.directory[
'cn=existing,' + settings.GROUP_BASE_DN]['memberUid']
result = delete_ldap_user('existing')
self.assertEqual({'username': 'existing', 'deleted': True}, result)
self.assertNotIn(
'uid=existing,' + settings.USER_BASE_DN, self.ldapobj.directory)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'search_s', 'delete_s'
])
with self.assertRaises(KeyError):
self.ldap_server.get('uid=existing,' + settings.USER_BASE_DN)
def test_delete_ldap_user_chained_exsting(self):
result = delete_ldap_user_chained({'username': 'existing'})
self.assertEqual({'username': 'existing', 'deleted': True}, result)
self.assertNotIn(
'uid=existing,' + settings.USER_BASE_DN, self.ldapobj.directory)
self.assertNotIn('memberUid', self.ldapobj.directory[
'cn=existing,' + settings.GROUP_BASE_DN])
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'search_s',
'search_s', 'search_s', 'search_s', 'modify_s', 'delete_s'
])
with self.assertRaises(KeyError):
self.ldap_server.get('uid=existing,' + settings.USER_BASE_DN)
group_object = self.ldap_server.get('cn=existing,' + settings.GROUP_BASE_DN)
self.assertNotIn('memberUid', group_object)
def test_delete_ldap_group_if_empty_nonempty(self):
result = delete_ldap_group_if_empty('existing')
self.assertEqual({'groupname': 'existing', 'deleted': False}, result)
self.assertIn(
'cn=existing,' + settings.GROUP_BASE_DN, self.ldapobj.directory)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s'
])
ldap_object = self.ldap_server.get('cn=existing,' + settings.GROUP_BASE_DN)
self.assertIsNotNone(ldap_object)
def test_delete_ldap_group_if_empty_missing(self):
result = delete_ldap_group_if_empty('missing')
self.assertEqual({'groupname': 'missing', 'deleted': False}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s'
])
def test_delete_ldap_group_if_empty_empty(self):
del self.ldapobj.directory[
'cn=existing,' + settings.GROUP_BASE_DN]['memberUid']
result = delete_ldap_group_if_empty('existing')
self.assertEqual({'groupname': 'existing', 'deleted': True}, result)
self.assertNotIn(
'cn=existing,' + settings.GROUP_BASE_DN, self.ldapobj.directory)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'delete_s'
])
self.ldap_server.add({'cn=emptygroup,' + settings.GROUP_BASE_DN: {
'objectClass': ['posixGroup'],
'gidNumber': ['4712'],
'cn': ['existing'],
'description': ['existing test group'],
}})
result = delete_ldap_group_if_empty('emptygroup')
self.assertEqual({'groupname': 'emptygroup', 'deleted': True}, result)
with self.assertRaises(KeyError):
self.ldap_server.get('cn=emptygroup,' + settings.GROUP_BASE_DN)
def test_delete_ldap_group_existing(self):
result = delete_ldap_group('existing')
self.assertEqual({'groupname': 'existing', 'deleted': True}, result)
self.assertNotIn(
'cn=existing,' + settings.GROUP_BASE_DN, self.ldapobj.directory)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s', 'search_s', 'delete_s'
])
with self.assertRaises(KeyError):
self.ldap_server.get('cn=existing,' + settings.GROUP_BASE_DN)
def test_delete_ldap_group_missing(self):
result = delete_ldap_group('missing')
self.assertEqual({'groupname': 'missing', 'deleted': False}, result)
self.assertEqual(self.ldapobj.methods_called(), [
'initialize', 'simple_bind_s', 'search_s'
])

View file

@ -160,7 +160,7 @@ TEMPLATES = [
# ######### MIDDLEWARE CONFIGURATION
# See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes
MIDDLEWARE_CLASSES = (
MIDDLEWARE = (
# Default Django middleware.
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
@ -201,7 +201,7 @@ DJANGO_APPS = (
# Apps specific for this project go here.
LOCAL_APPS = (
'ldapentities',
'ldaptasks',
'gvaldap.ldaptasks',
)
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps

View file

@ -42,7 +42,7 @@ INSTALLED_APPS += (
'debug_toolbar',
)
MIDDLEWARE_CLASSES += (
MIDDLEWARE += (
'debug_toolbar.middleware.DebugToolbarMiddleware',
)

View file

@ -2,8 +2,6 @@
This module implements tests for :py:mod:`gvaldap.celery`.
"""
from __future__ import absolute_import
from unittest import TestCase
from gvaldap.celery import get_installed_apps

View file

@ -2,8 +2,6 @@
This module provides tests for :py:mod:`gvaldap.wsgi`.
"""
from __future__ import absolute_import
from unittest import TestCase

View file

@ -3,14 +3,15 @@ This module defines the main URLConf for gvaldap.
"""
from django.conf.urls import include, url
from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
admin.autodiscover()
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^admin/', admin.site.urls),
]
# Uncomment the next line to serve media files in dev.
@ -18,6 +19,11 @@ urlpatterns = [
if settings.DEBUG: # pragma: no cover
import debug_toolbar
urlpatterns += [
url(r'^__debug__/', include(debug_toolbar.urls)),
]
urlpatterns = (
[
url(r'^__debug__/', include(debug_toolbar.urls)),
]
+ staticfiles_urlpatterns()
+ urlpatterns
)

View file

@ -7,7 +7,7 @@ Admin classes for easy `django admin`_ based administration of LDAP entities.
from django.contrib import admin
from .models import (
from ldapentities.models import (
LdapGroup,
LdapUser,
)

View file

@ -9,7 +9,6 @@ The models are based on :py:class:`ldapmodels.Model` from `django-ldapdb`_.
from __future__ import unicode_literals
from django.conf import settings
from django.utils.encoding import python_2_unicode_compatible
from ldapdb.models.fields import (
CharField,
IntegerField,
@ -20,7 +19,6 @@ import ldapdb.models as ldapmodels
from passlib.hash import ldap_salted_sha1
@python_2_unicode_compatible
class LdapGroup(ldapmodels.Model):
"""
Class for representing an LDAP group entity with objectClass `posixGroup`.
@ -39,16 +37,16 @@ class LdapGroup(ldapmodels.Model):
# LDAP meta-data
base_dn = settings.GROUP_BASE_DN
#: list of object classes
object_classes = [b'posixGroup']
object_classes = ['posixGroup']
# posixGroup attributes
#: group id (`gidNumber`)
gid = IntegerField(db_column=b'gidNumber', unique=True)
gid = IntegerField(db_column='gidNumber', unique=True)
#: group name (`cn`)
name = CharField(db_column=b'cn', max_length=200, primary_key=True)
name = CharField(db_column='cn', max_length=200, primary_key=True)
#: group description (`description`)
description = CharField(db_column=b'description')
members = ListField(db_column=b'memberUid', blank=True)
description = CharField(db_column='description')
members = ListField(db_column='memberUid', blank=True)
def __str__(self):
"""
@ -57,7 +55,6 @@ class LdapGroup(ldapmodels.Model):
return self.name
@python_2_unicode_compatible
class LdapUser(ldapmodels.Model):
"""
Class for representing an LDAP user entity with objectClasses `account` and
@ -72,25 +69,25 @@ class LdapUser(ldapmodels.Model):
"""
base_dn = settings.USER_BASE_DN
#: list of object classes
object_classes = [b'account', b'posixAccount']
object_classes = ['account', 'posixAccount']
# posixAccount
#: user id (`uidNumber`)
uid = IntegerField(db_column=b'uidNumber', unique=True)
uid = IntegerField(db_column='uidNumber', unique=True)
#: group id (`gidNumber`) of the user's primary group
group = IntegerField(db_column=b'gidNumber')
group = IntegerField(db_column='gidNumber')
#: GECOS field (`gecos`)
gecos = CharField(db_column=b'gecos')
gecos = CharField(db_column='gecos')
#: home directory (`homeDirectory`)
home_directory = CharField(db_column=b'homeDirectory')
home_directory = CharField(db_column='homeDirectory')
#: login shell (`loginShell`)
login_shell = CharField(db_column=b'loginShell', default='/bin/bash')
login_shell = CharField(db_column='loginShell', default='/bin/bash')
#: user name (`uid`)
username = CharField(db_column=b'uid', primary_key=True)
username = CharField(db_column='uid', primary_key=True)
#: password (`userPassword`) in an LDAP compatible format
password = CharField(db_column=b'userPassword')
password = CharField(db_column='userPassword')
#: common name (`cn`)
common_name = CharField(db_column=b'cn')
common_name = CharField(db_column='cn')
def __str__(self):
"""

View file

@ -4,13 +4,11 @@ This module provides tests for :py:mod:`ldapentities.admin`.
"""
from __future__ import absolute_import
import volatildap
from django.conf import settings
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.contrib.auth import get_user_model
from mockldap import MockLdap
from django.urls import reverse
User = get_user_model()
@ -18,38 +16,47 @@ TEST_USER = 'admin'
TEST_EMAIL = 'admin@example.org'
TEST_PASSWORD = 'secret'
admin = (
settings.DATABASES['ldap']['USER'], {
'userPassword': [settings.DATABASES['ldap']['PASSWORD']]})
groups = (
settings.GROUP_BASE_DN, {
'objectClass': ['top', 'organizationalUnit'], 'ou': ['groups']})
admin = (settings.DATABASES['ldap']['USER'], {
'objectClass': ['person'],
'userPassword': [
settings.DATABASES['ldap'][
'PASSWORD']],
'sn': 'Admin',
})
groups = (settings.GROUP_BASE_DN, {
'objectClass': ['top', 'organizationalUnit'], 'ou': ['groups']})
users = (
settings.USER_BASE_DN, {
'objectClass': ['top', 'organizationalUnit'], 'ou': ['users']})
class LdapUserAdminTest(TestCase):
databases = ["default", "ldap"]
directory = dict([admin, groups, users])
@classmethod
def setUpClass(cls):
cls.mockldap = MockLdap(cls.directory)
super(LdapUserAdminTest, cls).setUpClass()
cls.ldap_server = volatildap.LdapServer(
initial_data=cls.directory,
schemas=['core.schema', 'cosine.schema', 'inetorgperson.schema',
'nis.schema'],
)
settings.DATABASES['ldap']['USER'] = cls.ldap_server.rootdn
settings.DATABASES['ldap']['PASSWORD'] = cls.ldap_server.rootpw
settings.DATABASES['ldap']['NAME'] = cls.ldap_server.uri
@classmethod
def tearDownClass(cls):
del cls.mockldap
cls.ldap_server.stop()
super(LdapUserAdminTest, cls).tearDownClass()
def setUp(self):
User.objects.create_superuser(
TEST_USER, email=TEST_EMAIL, password=TEST_PASSWORD)
self.client.login(username=TEST_USER, password=TEST_PASSWORD)
self.mockldap.start()
self.ldapobj = self.mockldap[settings.DATABASES['ldap']['NAME']]
def tearDown(self):
self.mockldap.stop()
del self.ldapobj
self.ldap_server.start()
def test_can_administer_groups(self):
response = self.client.get(reverse(

View file

@ -5,7 +5,7 @@ exclude = migrations
exclude = migrations
[coverage:run]
source = gvaldap,ldapentities,ldaptasks
source = gvaldap,ldapentities,gvaldap.ldaptasks
branch = True
[coverage:report]