Repository: goauthentik/authentik

Issue:
Listing all permissions
**Describe the bug**
When attempting to list all the permissions in order to select which ones to assign to a permission, hangs when gets to 141+

**To Reproduce**
Steps to reproduce the behavior:

1. Go to 'Directory'
2. Click on 'Roles'
3. Select (or create a new) role.
4. Click on 'Assign Permissions'
5. Click on '+' to Select Permissions to Grant
6. Scroll through permissions by clicking on '>' until arrive at 121 - 140

**Expected behavior**
Continue displaying all permissions until reaching end of list (Displays 377 Permissions)

**Screenshots**
![image](https://github.com/goauthentik/authentik/assets/54423468/4cbd1788-1066-49df-84e8-1a9f8f00dfbc)

**Logs**
[logs](https://pastebin.com/v4Fd6PDN)

**Version and Deployment (please complete the following information):**

-   authentik version: 2023.10.1
-   Deployment: docker-compose

**Additional context**
Upgraded from 2023.8 -> 2023.10.0 -> 2023.10.1

Can provide more logs or anything else, if needed.


Discussion:

Resolving patch:
diff --git a/authentik/rbac/api/rbac.py b/authentik/rbac/api/rbac.py
--- a/authentik/rbac/api/rbac.py
+++ b/authentik/rbac/api/rbac.py
@@ -32,13 +32,19 @@ class PermissionSerializer(ModelSerializer):
 
     def get_app_label_verbose(self, instance: Permission) -> str:
         """Human-readable app label"""
-        return apps.get_app_config(instance.content_type.app_label).verbose_name
+        try:
+            return apps.get_app_config(instance.content_type.app_label).verbose_name
+        except LookupError:
+            return f"{instance.content_type.app_label}.{instance.content_type.model}"
 
     def get_model_verbose(self, instance: Permission) -> str:
         """Human-readable model name"""
-        return apps.get_model(
-            instance.content_type.app_label, instance.content_type.model
-        )._meta.verbose_name
+        try:
+            return apps.get_model(
+                instance.content_type.app_label, instance.content_type.model
+            )._meta.verbose_name
+        except LookupError:
+            return f"{instance.content_type.app_label}.{instance.content_type.model}"
 
     class Meta:
         model = Permission
diff --git a/authentik/rbac/api/rbac_roles.py b/authentik/rbac/api/rbac_roles.py
--- a/authentik/rbac/api/rbac_roles.py
+++ b/authentik/rbac/api/rbac_roles.py
@@ -28,9 +28,12 @@ def get_app_label_verbose(self, instance: GroupObjectPermission) -> str:
 
     def get_model_verbose(self, instance: GroupObjectPermission) -> str:
         """Get model label from permission's model"""
-        return apps.get_model(
-            instance.content_type.app_label, instance.content_type.model
-        )._meta.verbose_name
+        try:
+            return apps.get_model(
+                instance.content_type.app_label, instance.content_type.model
+            )._meta.verbose_name
+        except LookupError:
+            return f"{instance.content_type.app_label}.{instance.content_type.model}"
 
     def get_object_description(self, instance: GroupObjectPermission) -> Optional[str]:
         """Get model description from attached model. This operation takes at least
@@ -38,7 +41,10 @@ def get_object_description(self, instance: GroupObjectPermission) -> Optional[st
         view_ permission on the object"""
         app_label = instance.content_type.app_label
         model = instance.content_type.model
-        model_class = apps.get_model(app_label, model)
+        try:
+            model_class = apps.get_model(app_label, model)
+        except LookupError:
+            return None
         objects = get_objects_for_group(instance.group, f"{app_label}.view_{model}", model_class)
         obj = objects.first()
         if not obj:
diff --git a/authentik/rbac/api/rbac_users.py b/authentik/rbac/api/rbac_users.py
--- a/authentik/rbac/api/rbac_users.py
+++ b/authentik/rbac/api/rbac_users.py
@@ -28,9 +28,12 @@ def get_app_label_verbose(self, instance: UserObjectPermission) -> str:
 
     def get_model_verbose(self, instance: UserObjectPermission) -> str:
         """Get model label from permission's model"""
-        return apps.get_model(
-            instance.content_type.app_label, instance.content_type.model
-        )._meta.verbose_name
+        try:
+            return apps.get_model(
+                instance.content_type.app_label, instance.content_type.model
+            )._meta.verbose_name
+        except LookupError:
+            return f"{instance.content_type.app_label}.{instance.content_type.model}"
 
     def get_object_description(self, instance: UserObjectPermission) -> Optional[str]:
         """Get model description from attached model. This operation takes at least
@@ -38,7 +41,10 @@ def get_object_description(self, instance: UserObjectPermission) -> Optional[str
         view_ permission on the object"""
         app_label = instance.content_type.app_label
         model = instance.content_type.model
-        model_class = apps.get_model(app_label, model)
+        try:
+            model_class = apps.get_model(app_label, model)
+        except LookupError:
+            return None
         objects = get_objects_for_user(instance.user, f"{app_label}.view_{model}", model_class)
         obj = objects.first()
         if not obj:


Test patch: