Edgewall Software

Ticket #4245: get_users_with_permission.groupprovider_fix.patch

File get_users_with_permission.groupprovider_fix.patch, 2.5 KB (added by ants.aasma@…, 16 months ago)

Adds support for the implicit group providers

  • trac/perm.py

     
    151151         
    152152        Users are returned as a list of usernames. 
    153153        """ 
    154         # get_user_permissions() takes care of the magic 'authenticated' group. 
    155         # The optimized loop we had before didn't.  This is very inefficient, 
    156         # but it works. 
    157154        db = self.env.get_db_cnx() 
    158155        cursor = db.cursor() 
     156        groups = permissions 
     157        users = set([u[0] for u in self.env.get_known_users()]) 
     158         
     159        # Collect the implicit groups and their members. This too could use a 
     160        # more efficient API 
     161        implicit_groups = {} 
     162        for provider in self.group_providers: 
     163            for username in users: 
     164                for groupname in provider.get_permission_groups(username): 
     165                    try: 
     166                        implicit_groups[groupname].add(username) 
     167                    except KeyError: 
     168                        implicit_groups[groupname] = set(username) 
     169             
    159170        result = set() 
    160         users = set([u[0] for u in self.env.get_known_users()]) 
    161         for user in users: 
    162             userperms = self.get_user_permissions(user) 
    163             for group in permissions: 
    164                 if group in userperms: 
    165                     result.add(user) 
     171 
     172        # First iteration finds all users and groups that have any of the 
     173        # needed permissions. Subsequent iterations expand groups recursively 
     174        # and merge the results 
     175        while len(groups): 
     176            cursor.execute("SELECT p.username, COUNT(m.username) " 
     177                           "FROM permission AS p " 
     178                           "LEFT JOIN permission AS m ON m.action = p.username " 
     179                           "WHERE p.action IN (%s) GROUP BY p.username" 
     180                           % (', '.join(['%s'] * len(groups))), groups) 
     181            groups = [] 
     182            for username, nummembers in cursor: 
     183                if username in implicit_groups: 
     184                    # A group with members provided by group_providers has 
     185                    # the necessary permissions set so add all its members. 
     186                    result.update(implicit_groups[username]) 
     187                if username in users: 
     188                    result.add(username) 
     189                elif nummembers: 
     190                    groups.append(username) 
     191 
    166192        return list(result) 
    167193 
    168194    def get_all_permissions(self):