0002-ldap-allow-provisionning-of-all-user-attributes-fixe.patch
src/authentic2/backends/ldap_backend.py | ||
---|---|---|
316 | 316 |
'connect_with_user_credentials': True, |
317 | 317 |
# can reset password |
318 | 318 |
'can_reset_password': False, |
319 |
# mapping from LDAP attributes to User attributes |
|
320 |
'user_attributes': [], |
|
319 | 321 |
} |
320 | 322 |
_REQUIRED = ('url', 'basedn') |
321 | 323 |
_TO_ITERABLE = ('url', 'groupsu', 'groupstaff', 'groupactive') |
... | ... | |
498 | 500 |
return None |
499 | 501 | |
500 | 502 |
def populate_user_attributes(self, user, block, attributes): |
503 |
# map legacy attributes (columns from Django user model) |
|
501 | 504 |
for legacy_attribute, legacy_field in (('email', 'email_field'), |
502 | 505 |
('first_name', 'fname_field'), |
503 | 506 |
('last_name', 'lname_field')): |
... | ... | |
511 | 514 |
if getattr(user, legacy_attribute) != value: |
512 | 515 |
setattr(user, legacy_attribute, value) |
513 | 516 |
user._changed = True |
517 |
# map new style attributes |
|
518 |
user_attributes = {} |
|
519 |
for mapping in block.get('user_attributes', []): |
|
520 |
from_ldap = mapping.get('from_ldap') |
|
521 |
to_user = mapping.get('to_user') |
|
522 |
if not from_ldap or not to_user: |
|
523 |
continue |
|
524 |
if not attributes.get(from_ldap): |
|
525 |
user_attributes[to_user] = '' |
|
526 |
else: |
|
527 |
user_attributes[to_user] = attributes[from_ldap][0] |
|
528 |
for name in user_attributes: |
|
529 |
value = getattr(user.attributes, name, None) |
|
530 |
if value != user_attributes[name]: |
|
531 |
if not user.pk: |
|
532 |
user.save() |
|
533 |
setattr(user.attributes, name, user_attributes[name]) |
|
534 |
user._changed = True |
|
514 | 535 | |
515 | 536 |
def populate_admin_flags_by_group(self, user, block, group_dns): |
516 | 537 |
'''Attribute admin flags based on groups. |
... | ... | |
745 | 766 |
external_id_tuple)) |
746 | 767 |
for from_at, to_at in block['attribute_mappings']: |
747 | 768 |
attributes.add(to_at) |
769 |
for mapping in block['user_attributes']: |
|
770 |
from_ldap = mapping.get('from_ldap') |
|
771 |
if from_ldap: |
|
772 |
attributes.add(from_ldap) |
|
748 | 773 |
return list(set(map(str.lower, map(str, attributes)))) |
749 | 774 | |
750 | 775 |
@classmethod |
tests/test_ldap.py | ||
---|---|---|
79 | 79 |
cn: Étienne Michu |
80 | 80 |
sn: Michu |
81 | 81 |
gn: Étienne |
82 |
l: Paris |
|
82 | 83 |
mail: etienne.michu@example.net |
83 | 84 | |
84 | 85 |
dn: cn=group1,o=ôrga |
... | ... | |
94 | 95 |
cn: Étienne Michu |
95 | 96 |
sn: Michu |
96 | 97 |
gn: Étienne |
98 |
l: locality{i} |
|
97 | 99 |
mail: etienne.michu@example.net |
98 | 100 | |
99 | 101 |
'''.format(i=i, password=PASS)) |
... | ... | |
649 | 651 |
assert result.status_code == 200 |
650 | 652 |
assert 'Étienne Michu' in str(result) |
651 | 653 |
assert 'name="username"' not in str(result) |
654 | ||
655 | ||
656 |
def test_user_attributes(slapd, settings, client, db): |
|
657 |
settings.LDAP_AUTH_SETTINGS = [{ |
|
658 |
'url': [slapd.ldap_url], |
|
659 |
'basedn': u'o=ôrga', |
|
660 |
'use_tls': False, |
|
661 |
'user_attributes': [ |
|
662 |
{ |
|
663 |
'from_ldap': 'l', |
|
664 |
'to_user': 'locality', |
|
665 |
}, |
|
666 |
] |
|
667 |
}] |
|
668 | ||
669 |
# create a locality attribute |
|
670 |
models.Attribute.objects.create( |
|
671 |
label='locality', |
|
672 |
name='locality', |
|
673 |
kind='string', |
|
674 |
required=False, |
|
675 |
user_visible=True, |
|
676 |
user_editable=False, |
|
677 |
asked_on_registration=False, |
|
678 |
multiple=False) |
|
679 | ||
680 |
client.post('/login/', |
|
681 |
{ |
|
682 |
'login-password-submit': '1', |
|
683 |
'username': USERNAME, |
|
684 |
'password': PASS |
|
685 |
}, |
|
686 |
follow=True) |
|
687 |
username = u'%s@ldap' % USERNAME |
|
688 |
user = User.objects.get(username=username) |
|
689 |
assert user.attributes.locality == u'Paris' |
|
690 |
client.session.flush() |
|
691 |
for i in range(5): |
|
692 |
client.post('/login/', |
|
693 |
{ |
|
694 |
'login-password-submit': '1', |
|
695 |
'username': 'michu%s' % i, |
|
696 |
'password': PASS, |
|
697 |
}, |
|
698 |
follow=True) |
|
699 |
username = u'michu%s@ldap' % i |
|
700 |
user = User.objects.get(username=username) |
|
701 |
assert user.attributes.locality == u'locality%s' % i |
|
702 |
client.session.flush() |
|
652 |
- |