mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-24 04:13:12 +00:00
Fix ldap testing
This commit is contained in:
parent
f41fcc843f
commit
3f4dd43fa9
5 changed files with 218 additions and 104 deletions
|
@ -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
|
||||||
|
|
|
@ -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
0
test_utils/__init__.py
Normal file
164
test_utils/runner.py
Normal file
164
test_utils/runner.py
Normal 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)
|
||||||
|
|
152
users/tests.py
152
users/tests.py
|
@ -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')
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue