Edgewall Software

Ticket #4245: trac.get_users_with_permission.trunk.patch

File trac.get_users_with_permission.trunk.patch, 4.3 KB (added by ants.aasma@…, 2 years ago)

Patch

  • trac/ticket/api.py

     
    101101        field = {'name': 'owner', 'label': 'Owner'} 
    102102        if self.restrict_owner: 
    103103            field['type'] = 'select' 
    104             users = [''] # for clearing assignment 
    105104            perm = PermissionSystem(self.env) 
    106             for username, name, email in self.env.get_known_users(db): 
    107                 if perm.get_user_permissions(username).get('TICKET_MODIFY'): 
    108                     users.append(username) 
     105            users = perm.get_users_with_permission('TICKET_MODIFY') 
    109106            field['options'] = users 
    110107            field['optional'] = True 
    111108        else: 
     
    258255                          title="Comment %s for %s:%s" % (cnum, type, id)) 
    259256        else: 
    260257            return label 
    261   
    262  No newline at end of file 
     258  
  • trac/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        users = {} 
     142        # First iteration finds all users and groups that have any of the 
     143        # needed permissions. Subsequent iterations expand groups recursively 
     144        # and merge the results 
     145        while len(groups): 
     146            cursor.execute("SELECT p.username, COUNT(s.sid) AS authenticated, " 
     147                "COUNT(p2.username) AS numusers FROM permission AS p " 
     148                "LEFT JOIN session AS s ON p.username = s.sid AND s.authenticated = 1 "+ 
     149                "LEFT JOIN permission AS p2 ON s.sid IS NULL AND p2.action = p.username "+ 
     150                "WHERE p.action IN (%s) GROUP BY p.username" 
     151                % (', '.join(['%s'] * len(groups))), 
     152                groups 
     153            ) 
     154            groups = [] 
     155            for username, authenticated, numusers in cursor: 
     156                if authenticated: 
     157                    users[username] = True 
     158                if numusers: 
     159                    groups.append(username) 
     160        return users.keys() 
     161 
    129162    def get_all_permissions(self): 
    130163        """Return all permissions for all users. 
    131164 
     
    247280        formatted tuples.""" 
    248281        return self.store.get_all_permissions() 
    249282 
     283    def get_users_with_permission(self, permission): 
     284        """Return all users that have the specified permission 
     285         
     286        Users are returned as a list of usernames""" 
     287        # this should probably be cached 
     288        parentMap = {} 
     289        for requestor in self.requestors: 
     290            for action in requestor.get_permission_actions(): 
     291                if isinstance(action, tuple): 
     292                    for child in action[1]: 
     293                        if (parentMap.has_key(child) == False): 
     294                            parentMap[child] = [] 
     295                        parentMap[child] += [action[0]] 
     296        satisfyingPermissions = {} 
     297        def _append_with_parents(action): 
     298            # avoid unneccesary work and infinite loops 
     299            if (satisfyingPermissions.has_key(action)): 
     300                return 
     301            satisfyingPermissions[action] = True 
     302            if parentMap.has_key(action): 
     303                for parentaction in parentMap[action]: 
     304                    _append_with_parents(parentaction) 
     305        _append_with_parents(permission) 
     306        return self.store.get_users_with_permissions(satisfyingPermissions.keys()) 
     307 
    250308    # IPermissionRequestor methods 
    251309 
    252310    def get_permission_actions(self):