Commits

Matthew Schinckel  committed 9cb2118

User.objects.with_permissions(*permission_names) added.
Permission().users_with_permission() added.

These will filter a queryset of users, or return a queryset of users.

  • Participants
  • Parent commits e3fed7b

Comments (0)

Files changed (1)

File auth_additions/models.py

     increase_field_length(field, 128)
 
 
+# Add a queryset method that will allow for
+#
+#       User.objects.with_permissions('foo.bar')
+#
+class PermissionFilterMixin:
+    def with_permissions(self, *permission_names):
+        """
+        Filter the queryset of Users so that only those that would
+        pass the 'has_perm' test for _all_ Permissions described by
+        *permission_names are included.
+        
+        This would be all superusers, Users who have the Permissions
+        directly, or Users who are a members of Groups that between them
+        all have the Permissions.
+        
+        That is, if they have one Permission directly, another by virtue
+        of being in a Group, and the rest by virtue of being in another
+        Group, they would match.
+        
+        If they do not have _all_ of the Permissions, then they are
+        removed from the queryset.
+        """
+        permission_filters = models.Q(pk=None)
+        
+        for permission_name in permission_names:
+            app_label, codename = permission_name.split('.')
+            permission_filters = permission_filters | models.Q(content_type__app_label=app_label, codename=codename)
+        
+        permissions = Permission.objects.filter(permission_filters)
+
+        superuser_filter = models.Q(is_superuser=True)
+        
+        if len(permissions) != len(permission_names):
+            return self.filter(superuser_filter).distinct()
+
+        perm_filter = models.Q()
+        
+        for perm in permissions:
+            groups_filter = models.Q(groups__in=perm.group_set.all())
+            user_filter = models.Q(pk__in=perm.user_set.values_list('pk', flat=True))
+            perm_filter = perm_filter & (groups_filter | user_filter)
+        
+        return self.filter(superuser_filter | perm_filter ).distinct()
+
+# Queryset method for active users
+class ActiveMixin:
+    def active(self):
+        return self.filter(is_active=True)
+
+UserQuerySet = User.objects.all().__class__
+UserQuerySet.__bases__ = (PermissionFilterMixin, ActiveMixin) + UserQuerySet.__bases__
+
+
 #############################
 #                           #
 #  Permission additions    #
 #############################
 
 field = Permission._meta.get_field_by_name('name')[0]
-increase_field_length(field, 128)
+increase_field_length(field, 128)
+
+
+def users_with_permission(self):
+    """
+    Return all Users who have this Permission.
+    
+    This will be all Users who are a member of a Group that has this
+    Permission, Users who have this permission directly, or Users
+    who have is_superuser=True.
+    """
+    groups_filter = models.Q(groups__in=self.group_set.all())
+    user_filter = models.Q(pk__in=self.user_set.values_list('pk', flat=True))
+    superuser_filter = models.Q(is_superuser=True)
+    
+    return User.objects.filter(user_filter | groups_filter | superuser_filter).distinct()
+
+Permission.users_with_permission = users_with_permission