Browse Source

Implement SSH key export to LDAP

Baptiste Jonglez 10 years ago
parent
commit
fc8cad6a21
1 changed files with 25 additions and 2 deletions
  1. 25 2
      coin/members/models.py

+ 25 - 2
coin/members/models.py

@@ -149,6 +149,18 @@ class Member(CoinLdapSyncMixin, AbstractUser):
             Q(subscription_date__gt=date) |
             Q(resign_date__lt=date))
 
+    def get_ssh_keys(self):
+        # Quick & dirty, ensure that keys are unique (otherwise, LDAP complains)
+        return list({k.key for k in self.cryptokey_set.filter(type='RSA')})
+
+    def sync_ssh_keys(self):
+        """
+        Called whenever a SSH key is saved
+        """
+        ldap_user = LdapUser.objects.get(pk=self.username)
+        ldap_user.sshPublicKey = self.get_ssh_keys()
+        ldap_user.save()
+
     def sync_to_ldap(self, creation, update_fields, *args, **kwargs):
         """
         Update LDAP data when a member is saved
@@ -203,6 +215,9 @@ class Member(CoinLdapSyncMixin, AbstractUser):
             # Make sure password is hashed
             ldap_user.password = utils.ldap_hash(self._password_ldap)
 
+        # Store SSH keys
+        ldap_user.sshPublicKey = self.get_ssh_keys()
+
         ldap_user.save()
 
         # if creation:
@@ -300,7 +315,7 @@ def get_automatic_username(member):
     return username
 
 
-class CryptoKey(models.Model):
+class CryptoKey(CoinLdapSyncMixin, models.Model):
 
     KEY_TYPE_CHOICES = (('RSA', 'RSA'), ('GPG', 'GPG'))
 
@@ -309,6 +324,13 @@ class CryptoKey(models.Model):
     key = models.TextField(verbose_name='clé')
     member = models.ForeignKey('Member', verbose_name='membre')
 
+    def sync_to_ldap(self, creation, *args, **kwargs):
+        """Simply tell the member object to resync all its SSH keys to LDAP"""
+        self.member.sync_ssh_keys()
+
+    def delete_from_ldap(self, *args, **kwargs):
+        self.member.sync_ssh_keys()
+
     def __unicode__(self):
         return 'Clé %s de %s' % (self.type, self.member)
 
@@ -364,7 +386,7 @@ class LdapUser(ldapdb.models.Model):
     # "ou=users,ou=unix,o=ILLYSE,l=Villeurbanne,st=RHA,c=FR"
     base_dn = settings.LDAP_USER_BASE_DN
     object_classes = [b'inetOrgPerson', b'organizationalPerson', b'person',
-                      b'top', b'posixAccount']
+                      b'top', b'posixAccount', b'ldapPublicKey']
 
     uid = CharField(db_column=b'uid', unique=True, max_length=255)
     nick_name = CharField(db_column=b'cn', unique=True, primary_key=True,
@@ -380,6 +402,7 @@ class LdapUser(ldapdb.models.Model):
                               default='/tmp')
     loginShell = CharField(db_column=b'loginShell', max_length=255,
                               default='/bin/bash')
+    sshPublicKey = ListField(db_column=b'sshPublicKey', default=[])
 
     def __unicode__(self):
         return self.display_name