From 14c5d9ff066be146e1a8882d388091500779e238 Mon Sep 17 00:00:00 2001
From: Art Lukyanchyk <artiom.lukyanchyk@hs-hannover.de>
Date: Thu, 6 Jan 2022 13:58:13 +0100
Subject: [PATCH] Better documentation and error handling when setting up
 predefined groups and permissions

---
 .../ssoauth_setup_groups_and_perms.py         | 27 +++++++++++++------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/ssoauth/management/commands/ssoauth_setup_groups_and_perms.py b/ssoauth/management/commands/ssoauth_setup_groups_and_perms.py
index 4c74434..9f9183d 100644
--- a/ssoauth/management/commands/ssoauth_setup_groups_and_perms.py
+++ b/ssoauth/management/commands/ssoauth_setup_groups_and_perms.py
@@ -16,16 +16,23 @@ def get_or_create_permission(codename, create_with_name=None):
     :return: permission object
     Ensures the permissions exists. Creates it if needed.
     """
-    try:
-        perm = Permission.objects.get(codename=codename)
-    except Permission.DoesNotExist:
+    # the intended content type of the existing permission is not known
+    # therefore there might me multiple permissions with this codename
+    matching_perms = list(Permission.objects.filter(codename=codename))
+    if len(matching_perms) == 0:
         perm = Permission.objects.create(
             codename=codename,
             name=create_with_name or codename,
-            content_type=get_user_content_type()
+            content_type=get_user_content_type()  # user model as fallback, also it fits perfectly for staff/superuser
         )
         logger.info("Created permission: {0}".format(perm))
-    return perm
+        return perm
+    elif len(matching_perms) == 1:
+        return matching_perms[0]
+    else:
+        logger.warning("There are multiple permissions with codename {0}, picking the most recent one".format(codename))
+        logger.warning("You probably need to cleanup the permissions for your project.")
+        return matching_perms[-1]
 
 
 def get_or_create_group(name):
@@ -36,9 +43,9 @@ def get_or_create_group(name):
 
 
 def setup_predefined_groups():
-    for group_name, perm_codename in app_settings.PREDEFINED_GROUPS.items():
+    for group_name, perm_codenames in app_settings.PREDEFINED_GROUPS.items():
         group = get_or_create_group(group_name)
-        for perm_codename in perm_codename:
+        for perm_codename in perm_codenames:
             perm = get_or_create_permission(perm_codename)
             if perm not in group.permissions.all():
                 group.permissions.add(perm)
@@ -46,7 +53,11 @@ def setup_predefined_groups():
 
 
 class Command(BaseCommand):
-    help = "Set up groups and permissions (both predefined and compatibility). Runs automatically after migrations."
+    help = """
+    Set up groups and permissions (both predefined and compatibility).
+    Runs automatically after migrations.
+    If running it manually (better don't), ensure that all referenced permissions are created in prior.
+    """
     requires_migrations_checks = True
     requires_system_checks = True
 
-- 
GitLab