Browse Source

Change LdapUser model to comply posixAccount LDAP schema
Set default group "coin" to new members

Fabs 11 years ago
parent
commit
cd3a51dee2
3 changed files with 63 additions and 29 deletions
  1. 51 15
      coin/members/models.py
  2. 9 11
      coin/members/tests.py
  3. 3 3
      coin/settings.py

+ 51 - 15
coin/members/models.py

@@ -6,7 +6,7 @@ import base64
 import hashlib
 from django.db import models
 from ldapdb.models.fields import CharField, IntegerField, ListField
-from django.db.models.signals import post_save, pre_save
+from django.db.models.signals import post_save, pre_save, post_delete
 from django.dispatch import receiver
 from south.modelsinspector import add_ignored_fields
 import datetime
@@ -98,12 +98,10 @@ class MembershipFee(models.Model):
         return (u'%s - %s - %i€' % (self.member, self.start_date, self.amount))
 
 
-
-
 class LdapUser(ldapdb.models.Model):
     # TODO: déplacer ligne suivante dans settings.py
     base_dn = "ou=users,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR"
-    object_classes = ['inetOrgPerson', 'organizationalPerson', 'person', 'top']
+    object_classes = ['inetOrgPerson', 'organizationalPerson', 'person', 'top', 'posixAccount']
 
     uid = CharField(db_column='uid', unique=True, max_length=255)
     nick_name = CharField(db_column='cn', unique=True, primary_key=True,
@@ -113,6 +111,9 @@ class LdapUser(ldapdb.models.Model):
     display_name = CharField(db_column='displayName', max_length=255,
                              blank=True)
     password = CharField(db_column='userPassword', max_length=255)
+    uidNumber = IntegerField(db_column='uidNumber', unique=True)
+    gidNumber = IntegerField(db_column='gidNumber', default=2000)
+    homeDirectory = CharField(db_column='homeDirectory', max_length=255 , default='/tmp')
 
     def __unicode__(self):
         return self.display_name
@@ -120,15 +121,36 @@ class LdapUser(ldapdb.models.Model):
     class Meta:
         managed = False  # Indique à South de ne pas gérer le model LdapUser
 
-#Indique à South de ne pas gérer le model LdapUser
+class LdapGroup(ldapdb.models.Model):
+    """
+    Class for representing an LDAP group entry.
+    """
+    # LDAP meta-data
+    base_dn = "ou=groups,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR"
+    object_classes = ['posixGroup']
+
+    # posixGroup attributes
+    gid = IntegerField(db_column='gidNumber', unique=True)
+    name = CharField(db_column='cn', max_length=200, primary_key=True)
+    members = ListField(db_column='memberUid')
+
+    def __unicode__(self):
+        return self.name
+
+    class Meta:
+        managed = False  # Indique à South de ne pas gérer le model LdapGroup
+
+#Indique à South de ne pas gérer les models LdapUser et LdapGroup
 add_ignored_fields(["^ldapdb\.models\.fields"])
 
 
-# Lors de la sauvegarde d'un utilisateur Ldap, cette fonction est exécutée
-# avant la sauvegare pour chiffrer le mot de passe s'il est définit
-# et s'il n'est pas déjà chiffré
 @receiver(pre_save, sender=LdapUser)
 def change_password(sender, instance, **kwargs):
+    """
+    Lors de la sauvegarde d'un utilisateur Ldap, cette fonction est exécutée
+    avant la sauvegare pour chiffrer le mot de passe s'il est définit
+    et s'il n'est pas déjà chiffré
+    """
     # Si le mot de passe est définit et n'est pas déjà chiffré,
     # alors ça le chiffre
     if instance.password and not instance.password.startswith('{SSHA}'):
@@ -142,24 +164,38 @@ def sync_ldap(sender, instance, created, **kwargs):
     """
     Update LDAP data when a member is saved
     """
-
     if not created:
-       # try:
-            ldap_user = LdapUser.objects.get(pk=instance.ldap_cn)
-       # except exceptions.ObjectDoesNotExist:
-       #     created = True
+       ldap_user = LdapUser.objects.get(pk=instance.ldap_cn)
 
     if created:
+        max_uidNumber = LdapUser.objects.order_by('-uidNumber')[0].uidNumber
+        
         ldap_user = LdapUser()
         ldap_user.pk = instance.ldap_cn
         ldap_user.uid = instance.ldap_cn
         ldap_user.nick_name = instance.ldap_cn
-
+        ldap_user.uidNumber = max_uidNumber + 1
+        
     ldap_user.last_name = instance.last_name
     ldap_user.first_name = instance.first_name
-    # ldap_user.password = instance.password
     ldap_user.save()
 
+    if created:
+        ldap_group = LdapGroup.objects.get(pk='coin')
+        ldap_group.members.append(ldap_user.pk)
+        ldap_group.save()
+
+
+@receiver(post_delete, sender=Member)
+def remove_ldap_user_from_coin_group_when_deleting_member(sender, instance, **kwargs):
+    """
+    Lorsqu'un membre est supprimé du SI, son utilisateur LDAP correspondant est
+    sorti du groupe "coin"
+    """
+    ldap_group = LdapGroup.objects.get(pk='coin')
+    if instance.ldap_cn in ldap_group.members:
+        ldap_group.members.remove(instance.ldap_cn)
+        ldap_group.save()
 
 #==============================================================================
 # @receiver(pre_save, sender = LdapUser)

+ 9 - 11
coin/members/tests.py

@@ -65,27 +65,25 @@ class MemberTests(TestCase):
         ldap_user.delete();
     
     def test_change_password_and_auth(self):
+        """
+        Test que la fonction change_password de member fonctionne et permet
+        l'authentification avec le nouveau mot de passe
+        """
         ldap_cn = self.get_random_ldap_cn()
-        password = "MotDePasseTest"
-        logger.debug(ldap_cn)
-         #~ Créé un membre
-        member = Member(first_name = u'Passe-partout', last_name = u'Du fort Boyard', ldap_cn = ldap_cn)
+        password = "1234"
         
+         #~ Créé un nouveau membre
+        member = Member(first_name = u'Passe-partout', last_name = u'Du fort Boyard', ldap_cn = ldap_cn)
         member.save()
+        
         #~ Récupère l'utilisateur LDAP
         ldap_user = LdapUser.objects.get(pk=ldap_cn)
-        #~ logger.debug('Ask member to change password');
         
         #~ Change son mot de passe
         member.change_password(password)
-        #~ ldap_user.password = password
-        #~ ldap_user.save()
-        #~ 
+
         #~ Test l'authentification
-        # logger.debug(ldap_cn)
         c = Client()
-        
-        # TODO : Ce test échoue systématiquement, voir pourquoi
         self.assertEqual(c.login(username=ldap_cn, password=password), True)
         
         member.delete();

+ 3 - 3
coin/settings.py

@@ -212,9 +212,9 @@ AUTH_LDAP_USER_ATTR_MAP = {
 }
 
 AUTH_LDAP_USER_FLAGS_BY_GROUP = {
-    "is_active": "cn=users,ou=groups,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR",
-    "is_staff": "cn=users,ou=groups,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR",
-    "is_superuser": "cn=users,ou=groups,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR"
+    "is_active": "cn=coin,ou=groups,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR",
+    "is_staff": "cn=coin_admin,ou=groups,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR",
+    "is_superuser": "cn=coin_admin,ou=groups,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR"
 }