8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-23 07:23:46 +00:00

Fix ldap testing

This commit is contained in:
Maël Kervella 2018-06-21 14:19:08 +00:00
parent f41fcc843f
commit 3f4dd43fa9
5 changed files with 218 additions and 104 deletions

View file

@ -49,6 +49,10 @@ install_re2o.sh help
## MR 172: Refactor API ## MR 172: Refactor API
Creates a new (nearly) REST API to expose all models of Re2o. See [the dedicated wiki page](https://gitlab.federez.net/federez/re2o/wikis/API/Raw-Usage) for more details on how to use it. Creates a new (nearly) REST API to expose all models of Re2o. See [the dedicated wiki page](https://gitlab.federez.net/federez/re2o/wikis/API/Raw-Usage) for more details on how to use it.
* For testing purpose, add `volatildap` package:
```
pip3 install volatildap
```
* Activate HTTP Authorization passthrough in by adding the following in `/etc/apache2/site-available/re2o.conf` (example in `install_utils/apache2/re2o.conf`): * Activate HTTP Authorization passthrough in by adding the following in `/etc/apache2/site-available/re2o.conf` (example in `install_utils/apache2/re2o.conf`):
``` ```
WSGIPassAuthorization On WSGIPassAuthorization On

View file

@ -1,3 +1,5 @@
django-bootstrap3 django-bootstrap3
django-ldapdb==0.9.0 django-ldapdb==0.9.0
django-macaddress django-macaddress
# For testing purpose
volatildap

0
test_utils/__init__.py Normal file
View file

164
test_utils/runner.py Normal file
View file

@ -0,0 +1,164 @@
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il
# se veut agnostique au réseau considéré, de manière à être installable en
# quelques clics.
#
# Copyright © 2017 Gabriel Détraz
# Copyright © 2017 Goulven Kermarec
# Copyright © 2017 Augustin Lemesle
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""Defines the custom runners for Re2o.
"""
import volatildap
import os.path
from django.test.runner import DiscoverRunner
from django.conf import settings
from users.models import LdapUser, LdapUserGroup, LdapServiceUser, LdapServiceUserGroup
# The path of this file
__here = os.path.dirname(os.path.realpath(__file__))
# The absolute path where to find the schemas for the LDAP
schema_path = os.path.abspath(os.path.join(__here, 'ldap', 'schema'))
# The absolute path of the "radius.schema" file
radius_schema_path = os.path.join(schema_path, 'radius.schema')
# The absolute path of the "samba.schema" file
samba_schema_path = os.path.join(schema_path, 'samba.schema')
# The suffix for the LDAP
suffix = 'dc=example,dc=net'
# The admin CN of the LDAP
rootdn = 'cn=admin,'+suffix
# Defines all ldap_entry mandatory for Re2o under a key-value list format
# that can be used directly by volatildap. For more on how to generate this
# data, see https://gitlab.federez.net/re2o/scripts/blob/master/print_ldap_entries.py
ldapentry_Utilisateurs = ('cn=Utilisateurs,'+suffix, {
'cn': ['Utilisateurs'],
'sambaSID': ['500'],
'uid': ['Users'],
'objectClass': ['posixGroup', 'top', 'sambaSamAccount', 'radiusprofile'],
'gidNumber': ['500'],
})
ldapentry_groups = ('ou=groups,'+suffix, {
'ou': ['groups'],
'objectClass': ['organizationalUnit'],
'description': ["Groupes d'utilisateurs"],
})
ldapentry_services = ('ou=services,ou=groups,'+suffix, {
'ou': ['services'],
'objectClass': ['organizationalUnit'],
'description': ['Groupes de comptes techniques'],
})
ldapentry_service_users = ('ou=service-users,'+suffix, {
'ou': ['service-users'],
'objectClass': ['organizationalUnit'],
'description': ["Utilisateurs techniques de l'annuaire"],
})
ldapentry_freeradius = ('cn=freeradius,ou=service-users,'+suffix, {
'cn': ['freeradius'],
'objectClass': ['applicationProcess', 'simpleSecurityObject'],
'userPassword': ['FILL_IT'],
})
ldapentry_nssauth = ('cn=nssauth,ou=service-users,'+suffix, {
'cn': ['nssauth'],
'objectClass': ['applicationProcess', 'simpleSecurityObject'],
'userPassword': ['FILL_IT'],
})
ldapentry_auth = ('cn=auth,ou=services,ou=groups,'+suffix, {
'cn': ['auth'],
'objectClass': ['groupOfNames'],
'member': ['cn=nssauth,ou=service-users,'+suffix],
})
ldapentry_posix = ('ou=posix,ou=groups,'+suffix, {
'ou': ['posix'],
'objectClass': ['organizationalUnit'],
'description': ['Groupes de comptes POSIX'],
})
ldapentry_wifi = ('cn=wifi,ou=service-users,'+suffix, {
'cn': ['wifi'],
'objectClass': ['applicationProcess', 'simpleSecurityObject'],
'userPassword': ['FILL_IT'],
})
ldapentry_usermgmt = ('cn=usermgmt,ou=services,ou=groups,'+suffix, {
'cn': ['usermgmt'],
'objectClass': ['groupOfNames'],
'member': ['cn=wifi,ou=service-users,'+suffix],
})
ldapentry_replica = ('cn=replica,ou=service-users,'+suffix, {
'cn': ['replica'],
'objectClass': ['applicationProcess', 'simpleSecurityObject'],
'userPassword': ['FILL_IT'],
})
ldapentry_readonly = ('cn=readonly,ou=services,ou=groups,'+suffix, {
'cn': ['readonly'],
'objectClass': ['groupOfNames'],
'member': ['cn=replica,ou=service-users,'+suffix, 'cn=freeradius,ou=service-users,'+suffix],
})
ldapbasic = dict([ldapentry_Utilisateurs, ldapentry_groups,
ldapentry_services, ldapentry_service_users,
ldapentry_freeradius, ldapentry_nssauth, ldapentry_auth,
ldapentry_posix, ldapentry_wifi, ldapentry_usermgmt,
ldapentry_replica, ldapentry_readonly])
class DiscoverLdapRunner(DiscoverRunner):
"""Discovers all the tests in the project
This is a simple subclass of the default test runner
`django.test.runner.DiscoverRunner` that creates a test LDAP
right after the test databases are setup and destroys it right
before the test databases are setup.
It also ensure re2o's settings are using this new LDAP.
"""
# The `volatildap.LdapServer` instance initiated with the minimal
# structure required by Re2o
ldap_server = volatildap.LdapServer(
suffix=suffix,
rootdn=rootdn,
initial_data=ldapbasic,
schemas=['core.schema', 'cosine.schema', 'inetorgperson.schema',
'nis.schema', radius_schema_path, samba_schema_path]
)
def __init__(self, *args, **kwargs):
settings.DATABASES['ldap']['USER'] = self.ldap_server.rootdn
settings.DATABASES['ldap']['PASSWORD'] = self.ldap_server.rootpw
settings.DATABASES['ldap']['NAME'] = self.ldap_server.uri
settings.LDAP['base_user_dn'] = ldapentry_Utilisateurs[0]
settings.LDAP['base_userservice_dn'] = ldapentry_service_users[0]
settings.LDAP['base_usergroup_dn'] = ldapentry_posix[0]
settings.LDAP['base_userservicegroup_dn'] = ldapentry_services[0]
settings.LDAP['user_gid'] = ldapentry_Utilisateurs[1].get('gidNumber', ["500"])[0]
LdapUser.base_dn = settings.LDAP['base_user_dn']
LdapUserGroup.base_dn = settings.LDAP['base_usergroup_dn']
LdapServiceUser.base_dn = settings.LDAP['base_userservice_dn']
LdapServiceUserGroup.base_dn = settings.LDAP['base_userservicegroup_dn']
super(DiscoverLdapRunner, self).__init__(*args, **kwargs)
def setup_databases(self, *args, **kwargs):
ret = super(DiscoverLdapRunner, self).setup_databases(*args, **kwargs)
self.ldap_server.start()
return ret
def teardown_databases(self, *args, **kwargs):
self.ldap_server.stop()
super(DiscoverLdapRunner, self).teardown_databases(*args, **kwargs)

View file

@ -23,121 +23,65 @@
The tests for the Users module. The tests for the Users module.
""" """
import os.path
from django.test import TestCase from django.test import TestCase
from django.conf import settings from django.conf import settings
from .models import School, ListShell, LdapUserGroup, ListRight from . import models
import volatildap import volatildap
# Réglages bidon pour volatildap
LdapUserGroup.base_dn='ou=groups,dc=example,dc=org'
groups = ('ou=groups,dc=example,dc=org', {
'objectClass': ['top', 'organizationalUnit'], 'ou': ['groups']})
people = ('ou=people,dc=example,dc=org', {
'objectClass': ['top', 'organizationalUnit'], 'ou': ['groups']})
contacts = ('ou=contacts,ou=groups,dc=example,dc=org', {
'objectClass': ['top', 'organizationalUnit'], 'ou': ['groups']})
foogroup = ('cn=foogroup,ou=groups,dc=example,dc=org', {
'objectClass': ['posixGroup'], 'memberUid': ['foouser', 'baruser'],
'gidNumber': ['1000'], 'cn': ['foogroup']})
bargroup = ('cn=bargroup,ou=groups,dc=example,dc=org', {
'objectClass': ['posixGroup'], 'memberUid': ['zoouser', 'baruser'],
'gidNumber': ['1001'], 'cn': ['bargroup']})
wizgroup = ('cn=wizgroup,ou=groups,dc=example,dc=org', {
'objectClass': ['posixGroup'], 'memberUid': ['wizuser', 'baruser'],
'gidNumber': ['1002'], 'cn': ['wizgroup']})
foouser = ('uid=foouser,ou=people,dc=example,dc=org', {
'cn': [b'F\xc3\xb4o Us\xc3\xa9r'],
'objectClass': ['posixAccount', 'shadowAccount', 'inetOrgPerson'],
'loginShell': ['/bin/bash'],
'jpegPhoto': [
b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x01\x00H\x00H\x00\x00\xff'
b'\xfe\x00\x1cCreated with GIMP on a Mac\xff\xdb\x00C\x00\x05\x03\x04'
b'\x04\x04\x03\x05\x04\x04\x04\x05\x05\x05\x06\x07\x0c\x08\x07\x07\x07'
b'\x07\x0f\x0b\x0b\t\x0c\x11\x0f\x12\x12\x11\x0f\x11\x11\x13\x16\x1c'
b'\x17\x13\x14\x1a\x15\x11\x11\x18!\x18\x1a\x1d\x1d\x1f\x1f\x1f\x13'
b'\x17"$"\x1e$\x1c\x1e\x1f\x1e\xff\xdb\x00C\x01\x05\x05\x05\x07\x06\x07'
b'\x0e\x08\x08\x0e\x1e\x14\x11\x14\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e'
b'\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e'
b'\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e'
b'\x1e\x1e\x1e\x1e\x1e\x1e\x1e\xff\xc0\x00\x11\x08\x00\x08\x00\x08\x03'
b'\x01"\x00\x02\x11\x01\x03\x11\x01\xff\xc4\x00\x15\x00\x01\x01\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\xff\xc4\x00'
b'\x19\x10\x00\x03\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x01\x02\x06\x11A\xff\xc4\x00\x14\x01\x01\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xc4\x00\x14\x11\x01'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff'
b'\xda\x00\x0c\x03\x01\x00\x02\x11\x03\x11\x00?\x00\x9d\xf29wU5Q\xd6'
b'\xfd\x00\x01\xff\xd9'],
'uidNumber': ['2000'], 'gidNumber': ['1000'], 'sn': [b'Us\xc3\xa9r'],
'homeDirectory': ['/home/foouser'], 'givenName': [b'F\xc3\xb4o'],
'uid': ['foouser']})
class LdapTestCase(TestCase):
directory = {}
@classmethod
def setUpClass(cls):
super(LdapTestCase, 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):
cls.ldap_server.stop()
super(LdapTestCase, cls).tearDownClass()
def setUp(self):
super(LdapTestCase, self).setUp()
self.ldap_server.start()
class SchoolTestCase(TestCase): class SchoolTestCase(TestCase):
def setUp(self):
School.objects.create(name="ENS Paris-Saclay")
School.objects.create(name="Supelec")
def test_school_are_created(self): def test_school_are_created(self):
pass s = models.School.objects.create(name="My awesome school")
self.assertEqual(s.name, "My awesome school")
class ListShellTestCase(TestCase): class ListShellTestCase(TestCase):
def setUp(self):
ListShell.objects.create(shell="/bin/zsh")
ListShell.objects.create(shell="/bin/bash")
def test_shell_are_created(self): def test_shell_are_created(self):
pass s = models.ListShell.objects.create(shell="/bin/zsh")
self.assertEqual(s.shell, "/bin/zsh")
class GroupTestCase(LdapTestCase):
directory = dict([groups, foogroup, bargroup, wizgroup, people, foouser])
def test_create_ldapgroup(self):
mygroup = LdapUserGroup()
mygroup.name='re2o'
mygroup.gid=1010
mygroup.members=['someuser', 'foouser']
mygroup.save()
# check ldap group was created
new = LdapUserGroup.objects.get(name='re2o')
self.assertEqual(new.name, 're2o')
self.assertEqual(new.gid, 1010)
self.assertEqual(new.members, ['someuser', 'foouser'])
def test_create_re2ogroup(self):
ListRight.objects.create(gid='1011', unix_name='admins', details='test')
#check re2o
lr = ListRight.objects.get(gid=1011)
self.asserEqual(lr.gid, 1011)
self.asserEqual(lr.details, 'test')
class LdapUserTestCase(TestCase):
def test_create_ldap_user(self):
g = models.LdapUser.objects.create(
gid="500",
name="users_test_ldapuser",
uid="users_test_ldapuser",
uidNumber="21001",
sn="users_test_ldapuser",
login_shell="/bin/false",
mail="user@example.net",
given_name="users_test_ldapuser",
home_directory="/home/moamoak",
display_name="users_test_ldapuser",
dialupAccess="False",
sambaSID="21001",
user_password="{SSHA}aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
sambat_nt_password="0123456789ABCDEF0123456789ABCDEF",
macs=[],
shadowexpire="0"
)
self.assertEqual(g.name, 'users_test_ldapuser')
class LdapUserGroupTestCase(TestCase):
def test_create_ldap_user_group(self):
g = models.LdapUserGroup.objects.create(
gid="501",
members=[],
name="users_test_ldapusergroup"
)
self.assertEqual(g.name, 'users_test_ldapusergroup')
class LdapServiceUserTestCase(TestCase):
def test_create_ldap_service_user(self):
g = models.LdapServiceUser.objects.create(
name="users_test_ldapserviceuser",
user_password="{SSHA}AbCdEfGhIjKlMnOpQrStUvWxYz987654"
)
self.assertEqual(g.name, 'users_test_ldapserviceuser')