Edgewall Software

Ticket #4245: trac.get_users_with_permission.v2.patch

File trac.get_users_with_permission.v2.patch, 4.0 KB (added by ants.aasma@…, 22 months ago)

Second version of the patch. Using the env.get_known_users() interface to get users.

  • ticket/api.py

     
    103103        if self.restrict_owner: 
    104104            field['type'] = 'select' 
    105105            perm = PermissionSystem(self.env) 
    106             def valid_owner(username): 
    107                 return perm.get_user_permissions(username).get('TICKET_MODIFY') 
    108             field['options'] = [username for username, name, email 
    109                                 in self.env.get_known_users() 
    110                                 if valid_owner(username)] 
     106            field['options'] = perm.get_users_with_permission('TICKET_MODIFY') 
    111107            field['optional'] = True 
    112108        else: 
    113109            field['type'] = 'text' 
  • perm.py

     
    6060        of the permission, and the value is either `True` for granted 
    6161        permissions or `False` for explicitly denied permissions.""" 
    6262 
     63    def get_users_with_permissions(self, permissions): 
     64        """Retrieve a list of users that have any of the specified permissions 
     65 
     66        Users are returned as a list of usernames.""" 
     67 
    6368    def get_all_permissions(): 
    6469        """Return all permissions for all users. 
    6570 
     
    126131                break 
    127132        return [action for action in actions if not action.islower()] 
    128133 
     134    def get_users_with_permissions(self, permissions): 
     135        """Retrieve a list of users that have any of the specified permissions 
     136         
     137        Users are returned as a list of usernames.""" 
     138        db = self.env.get_db_cnx() 
     139        cursor = db.cursor() 
     140        groups = permissions 
     141        valid_users = set(self.env.get_known_users()) 
     142        resultusers = set() 
     143        # First iteration finds all users and groups that have any of the 
     144        # needed permissions. Subsequent iterations expand groups recursively 
     145        # and merge the results 
     146        while len(groups): 
     147            cursor.execute("SELECT p.username, COUNT(member.username) AS nummembers FROM permission AS p "+ 
     148                "LEFT JOIN permission AS member ON member.action = p.username" + 
     149                "WHERE p.action IN (%s) GROUP BY p.username" 
     150                % (', '.join(['%s'] * len(groups))), 
     151                groups 
     152            ) 
     153            groups = [] 
     154            for username, nummembers in cursor: 
     155                if username in valid_users: 
     156                    resultusers.add(username) 
     157                elif nummembers: 
     158                    groups.append(username) 
     159        return list(resultusers) 
     160 
    129161    def get_all_permissions(self): 
    130162        """Return all permissions for all users. 
    131163 
     
    243275        formatted tuples.""" 
    244276        return self.store.get_all_permissions() 
    245277 
     278    def get_users_with_permission(self, permission): 
     279        """Return all users that have the specified permission 
     280         
     281        Users are returned as a list of usernames""" 
     282        # this should probably be cached 
     283        parentMap = {} 
     284        for requestor in self.requestors: 
     285            for action in requestor.get_permission_actions(): 
     286                if isinstance(action, tuple): 
     287                    for child in action[1]: 
     288                        if (parentMap.has_key(child) == False): 
     289                            parentMap[child] = [] 
     290                        parentMap[child] += [action[0]] 
     291        satisfyingPermissions = {} 
     292        def _append_with_parents(action): 
     293            # avoid unneccesary work and infinite loops 
     294            if (satisfyingPermissions.has_key(action)): 
     295                return 
     296            satisfyingPermissions[action] = True 
     297            if parentMap.has_key(action): 
     298                for parentaction in parentMap[action]: 
     299                    _append_with_parents(parentaction) 
     300        _append_with_parents(permission) 
     301        return self.store.get_users_with_permissions(satisfyingPermissions.keys()) 
     302 
    246303    # IPermissionRequestor methods 
    247304 
    248305    def get_permission_actions(self):