|
@@ -62,11 +62,14 @@ class Member(CoinLdapSyncMixin, AbstractUser):
|
|
|
country = models.CharField(max_length=200, blank=True, null=True,
|
|
|
default='France',
|
|
|
verbose_name='pays')
|
|
|
-
|
|
|
resign_date = models.DateField(null=True, blank=True,
|
|
|
verbose_name="date de départ de "
|
|
|
"l'association",
|
|
|
help_text="En cas de départ prématuré")
|
|
|
+ comments = models.TextField(blank=True, verbose_name='commentaires',
|
|
|
+ help_text="Commentaires libres (informations"
|
|
|
+ " spécifiques concernant l'adhésion,"
|
|
|
+ " raison du départ, etc)")
|
|
|
|
|
|
# Following fields are managed by the parent class AbstractUser :
|
|
|
# username, first_name, last_name, email
|
|
@@ -146,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
|
|
@@ -186,6 +201,7 @@ class Member(CoinLdapSyncMixin, AbstractUser):
|
|
|
ldap_user.uid = self.username
|
|
|
ldap_user.nick_name = self.username
|
|
|
ldap_user.uidNumber = uid_number
|
|
|
+ ldap_user.homeDirectory = '/home/' + self.username
|
|
|
|
|
|
if self.type == 'natural_person':
|
|
|
ldap_user.last_name = self.last_name
|
|
@@ -199,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:
|
|
@@ -296,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'))
|
|
|
|
|
@@ -305,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)
|
|
|
|
|
@@ -360,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,
|
|
@@ -374,6 +400,9 @@ class LdapUser(ldapdb.models.Model):
|
|
|
gidNumber = IntegerField(db_column=b'gidNumber', default=2000)
|
|
|
homeDirectory = CharField(db_column=b'homeDirectory', max_length=255,
|
|
|
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
|