ldap: allow provisionning of all user attributes (fixes #30535)
This commit is contained in:
parent
9d96274c7b
commit
d28a6bba25
|
@ -316,6 +316,8 @@ class LDAPBackend(object):
|
|||
'connect_with_user_credentials': True,
|
||||
# can reset password
|
||||
'can_reset_password': False,
|
||||
# mapping from LDAP attributes to User attributes
|
||||
'user_attributes': [],
|
||||
}
|
||||
_REQUIRED = ('url', 'basedn')
|
||||
_TO_ITERABLE = ('url', 'groupsu', 'groupstaff', 'groupactive')
|
||||
|
@ -498,6 +500,7 @@ class LDAPBackend(object):
|
|||
return None
|
||||
|
||||
def populate_user_attributes(self, user, block, attributes):
|
||||
# map legacy attributes (columns from Django user model)
|
||||
for legacy_attribute, legacy_field in (('email', 'email_field'),
|
||||
('first_name', 'fname_field'),
|
||||
('last_name', 'lname_field')):
|
||||
|
@ -511,6 +514,24 @@ class LDAPBackend(object):
|
|||
if getattr(user, legacy_attribute) != value:
|
||||
setattr(user, legacy_attribute, value)
|
||||
user._changed = True
|
||||
# map new style attributes
|
||||
user_attributes = {}
|
||||
for mapping in block.get('user_attributes', []):
|
||||
from_ldap = mapping.get('from_ldap')
|
||||
to_user = mapping.get('to_user')
|
||||
if not from_ldap or not to_user:
|
||||
continue
|
||||
if not attributes.get(from_ldap):
|
||||
user_attributes[to_user] = ''
|
||||
else:
|
||||
user_attributes[to_user] = attributes[from_ldap][0]
|
||||
for name in user_attributes:
|
||||
value = getattr(user.attributes, name, None)
|
||||
if value != user_attributes[name]:
|
||||
if not user.pk:
|
||||
user.save()
|
||||
setattr(user.attributes, name, user_attributes[name])
|
||||
user._changed = True
|
||||
|
||||
def populate_admin_flags_by_group(self, user, block, group_dns):
|
||||
'''Attribute admin flags based on groups.
|
||||
|
@ -745,6 +766,10 @@ class LDAPBackend(object):
|
|||
external_id_tuple))
|
||||
for from_at, to_at in block['attribute_mappings']:
|
||||
attributes.add(to_at)
|
||||
for mapping in block['user_attributes']:
|
||||
from_ldap = mapping.get('from_ldap')
|
||||
if from_ldap:
|
||||
attributes.add(from_ldap)
|
||||
return list(set(map(str.lower, map(str, attributes))))
|
||||
|
||||
@classmethod
|
||||
|
|
|
@ -79,6 +79,7 @@ uid: {uid}
|
|||
cn: Étienne Michu
|
||||
sn: Michu
|
||||
gn: Étienne
|
||||
l: Paris
|
||||
mail: etienne.michu@example.net
|
||||
|
||||
dn: cn=group1,o=ôrga
|
||||
|
@ -94,6 +95,7 @@ uid: michu{i}
|
|||
cn: Étienne Michu
|
||||
sn: Michu
|
||||
gn: Étienne
|
||||
l: locality{i}
|
||||
mail: etienne.michu@example.net
|
||||
|
||||
'''.format(i=i, password=PASS))
|
||||
|
@ -649,3 +651,52 @@ def test_tls(db, tls_slapd, settings, client):
|
|||
assert result.status_code == 200
|
||||
assert 'Étienne Michu' in str(result)
|
||||
assert 'name="username"' not in str(result)
|
||||
|
||||
|
||||
def test_user_attributes(slapd, settings, client, db):
|
||||
settings.LDAP_AUTH_SETTINGS = [{
|
||||
'url': [slapd.ldap_url],
|
||||
'basedn': u'o=ôrga',
|
||||
'use_tls': False,
|
||||
'user_attributes': [
|
||||
{
|
||||
'from_ldap': 'l',
|
||||
'to_user': 'locality',
|
||||
},
|
||||
]
|
||||
}]
|
||||
|
||||
# create a locality attribute
|
||||
models.Attribute.objects.create(
|
||||
label='locality',
|
||||
name='locality',
|
||||
kind='string',
|
||||
required=False,
|
||||
user_visible=True,
|
||||
user_editable=False,
|
||||
asked_on_registration=False,
|
||||
multiple=False)
|
||||
|
||||
client.post('/login/',
|
||||
{
|
||||
'login-password-submit': '1',
|
||||
'username': USERNAME,
|
||||
'password': PASS
|
||||
},
|
||||
follow=True)
|
||||
username = u'%s@ldap' % USERNAME
|
||||
user = User.objects.get(username=username)
|
||||
assert user.attributes.locality == u'Paris'
|
||||
client.session.flush()
|
||||
for i in range(5):
|
||||
client.post('/login/',
|
||||
{
|
||||
'login-password-submit': '1',
|
||||
'username': 'michu%s' % i,
|
||||
'password': PASS,
|
||||
},
|
||||
follow=True)
|
||||
username = u'michu%s@ldap' % i
|
||||
user = User.objects.get(username=username)
|
||||
assert user.attributes.locality == u'locality%s' % i
|
||||
client.session.flush()
|
||||
|
|
Loading…
Reference in New Issue