Projet

Général

Profil

0001-DRAFT-A2-roles-mapped-to-LDAP-groups-16523.patch

Paul Marillonnet, 02 juin 2017 11:26

Télécharger (5,88 ko)

Voir les différences:

Subject: [PATCH] DRAFT A2 roles mapped to LDAP groups (#16523)

 src/authentic2/backends/ldap_backend.py | 69 ++++++++++++++++++++++++++++++---
 1 file changed, 63 insertions(+), 6 deletions(-)
src/authentic2/backends/ldap_backend.py
209 209
        'sync_ldap_users_filter': None,
210 210
        'user_basedn': None,
211 211
        'group_dn_template': None,
212
        'member_of_attribute': None,
212
        'group_member_of_attribute': None,
213
        'role_member_of_attribute': None,
213 214
        'group_filter': '(&(member={user_dn})(objectClass=groupOfNames))',
215
        'role_filter': '(&(member={user_dn})(objectClass=groupOfNames))',
214 216
        'group': None,
215 217
        'groupsu': None,
216 218
        'groupstaff': None,
217 219
        'groupactive': None,
218 220
        'group_mapping': (),
221
        'role_mapping': (),
219 222
        'replicas': True,
220 223
        'email_field': 'mail',
221 224
        'fname_field': 'givenName',
......
514 517
                elif dn not in group_dns and group in groups:
515 518
                    user.groups.remove(group)
516 519

  
520
    def populate_roles_by_mapping(self, user, dn, conn, block, role_dns):
521
        '''Assign role to user based on a mapping from role DNs'''
522
        role_mapping = block.get('role_mapping')
523
        if not role_mapping:
524
            return
525
        if not user.pk:
526
            user.save()
527
            user._changed = False
528
        roles = user.roles.all()
529
        for dn, role_names in role_mapping:
530
            for role_name in role_names:
531
                role = self.get_role_by_name(block, role_name)
532
                if role is None:
533
                    continue
534
                # Add missing roles
535
                if dn in role_dns and role not in roles:
536
                    user.roles.add(role)
537
                # Remove extra roles
538
                elif dn not in role_dns and role in roles:
539
                    user.roles.remove(role)
540

  
517 541
    def get_ldap_group_dns(self, user, dn, conn, block, attributes):
518 542
        '''Retrieve group DNs from the LDAP by attributes (memberOf) or by
519 543
           filter.
520 544
        '''
521 545
        group_base_dn = block.get('group_basedn', block['basedn'])
522
        member_of_attribute = block['member_of_attribute']
546
        group_member_of_attribute = block['group_member_of_attribute']
523 547
        group_filter = block['group_filter']
524 548
        group_dns = set()
525
        if member_of_attribute:
526
            member_of_attribute = str(member_of_attribute)
527
            results = conn.search_s(dn, ldap.SCOPE_BASE, '', [member_of_attribute])
528
            group_dns.update(results[0][1].get(member_of_attribute, []))
549
        if group_member_of_attribute:
550
            group_member_of_attribute = str(group_member_of_attribute)
551
            results = conn.search_s(dn, ldap.SCOPE_BASE, '', [group_member_of_attribute])
552
            group_dns.update(results[0][1].get(group_member_of_attribute, []))
529 553
        if group_filter:
530 554
            group_filter = str(group_filter)
531 555
            params = attributes.copy()
......
540 564
                group_dns.update(dn for dn, attributes in results if dn)
541 565
        return group_dns
542 566

  
567
    def get_ldap_role_dns(self, user, dn, conn, block, attributes):
568
        '''Retrieve role DNs from the LDAP by attributes (memberOf) or by
569
           filter.
570
        '''
571
        role_base_dn = block.get('role_basedn', block['basedn'])
572
        role_member_of_attribute = block['role_member_of_attribute']
573
        role_filter = block['role_filter']
574
        role_dns = set()
575
        if role_member_of_attribute:
576
            role_member_of_attribute = str(role_member_of_attribute)
577
            results = conn.search_s(dn, ldap.SCOPE_BASE, '', [role_member_of_attribute])
578
            role_dns.update(results[0][1].get(role_member_of_attribute, []))
579
        if role_filter:
580
            role_filter = str(role_filter)
581
            params = attributes.copy()
582
            params['user_dn'] = dn
583
            query = FilterFormatter().format(role_filter, **params)
584
            try:
585
                results = conn.search_s(role_base_dn, ldap.SCOPE_SUBTREE, query, [])
586
            except ldap.NO_SUCH_OBJECT:
587
                pass
588
            else:
589
                # ignore referrals by checking if bool(dn) is True
590
                role_dns.update(dn for dn, attributes in results if dn)
591
        return role_dns
592

  
543 593
    def populate_user_groups(self, user, dn, conn, block, attributes):
544 594
        group_dns = self.get_ldap_group_dns(user, dn, conn, block, attributes)
545 595
        log.debug('groups for dn %r: %r', dn, group_dns)
546 596
        self.populate_admin_flags_by_group(user, block, group_dns)
547 597
        self.populate_groups_by_mapping(user, dn, conn, block, group_dns)
548 598

  
599
    def populate_user_roles(self, user, dn, conn, block, attributes):
600
        role_dns = self.get_ldap_role_dns(user, dn, conn, block, attributes)
601
        log.debug('roles for dn %r: %r', dn, role_dns)
602
        # Admin flags by roles ?
603
        self.populate_roles_by_mapping(user, dn, conn, block, role_dns)
604

  
549 605
    def get_group_by_name(self, block, group_name, create=None):
550 606
        '''Obtain a Django group'''
551 607
        if create is None:
......
621 677
        self.populate_mandatory_groups(user, block)
622 678
        self.populate_mandatory_roles(user, block)
623 679
        self.populate_user_groups(user, dn, conn, block, attributes)
680
        self.populate_user_roles(user, dn, conn, block, attributes)
624 681

  
625 682
    def populate_user_ou(self, user, dn, conn, block, attributes):
626 683
        '''Assign LDAP user to an ou, the default one if ou_slug setting is
627
-