From bbe9a17210159d5782ff2c9dafda4238e193f460 Mon Sep 17 00:00:00 2001
From: beckerfy <fynn.becker@hs-hannover.de>
Date: Mon, 22 Jan 2018 11:46:26 +0100
Subject: [PATCH] Add local groups setup

---
 ssoauth/app_settings/defaults.py | 15 +++++++++++++++
 ssoauth/apps.py                  | 11 +++++++----
 ssoauth/setup_groups.py          | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 54 insertions(+), 4 deletions(-)
 create mode 100644 ssoauth/setup_groups.py

diff --git a/ssoauth/app_settings/defaults.py b/ssoauth/app_settings/defaults.py
index 627512b..4629eec 100644
--- a/ssoauth/app_settings/defaults.py
+++ b/ssoauth/app_settings/defaults.py
@@ -35,6 +35,21 @@ SP_SLS_X_FRAME_OPTIONS = None  # in case you encounter problems with SLS view no
 GROUPS_SAML_ATTRIBUTE = "IDMGroups"  # this SAML attribute is expected to contain list of groups for a user
 GROUP_RESOLVER = "ssoauth.auth_utils.groups_from_saml2_dn_list"  # in case you want to override how groups are resolved for users
 
+GROUPS = getattr(django_settings, "LOCAL_GROUPS", {
+    # Predefined groups and the corresponding permissions are here.
+    # Both groups and permissions are created/updated automatically after applying migrations.
+    # First, permissions are created:
+    #   - django.contrib.auth is responsible for handling vanilla permissions (mostly model permissions).
+    #   - All other explicitly assigned to groups permissions are automatically created.
+    # Second, groups are created and/or updated
+    #
+    # !IMPORTANT! Group naming:
+    #   - Check the current conventions and/or ask somebody who knows better.
+    #   - At the moment of rewriting this functionality:
+    #     - Give your local groups the same name as the AuthGroup they will be mapped to, e.g. your local group
+    #       for students will be named IDM_Studierende
+    #     - While there is no naming convention for unmapped groups, be kind and keep it sane
+})
 """
 Settings you might want to change on development (don't change them for production):
 """
diff --git a/ssoauth/apps.py b/ssoauth/apps.py
index 29d6e6a..1452d99 100644
--- a/ssoauth/apps.py
+++ b/ssoauth/apps.py
@@ -1,11 +1,12 @@
 from django.apps import AppConfig
+from django.contrib.auth.management import create_permissions
 from django.core import management
 from django.db.models.signals import post_migrate
-from django import conf
-import sys
+
+from . import app_settings
 from . import logger
 from . import sso_utils
-from . import app_settings
+from .setup_groups import setup_groups
 
 
 class SSOAuthConfig(AppConfig):
@@ -28,4 +29,6 @@ class SSOAuthConfig(AppConfig):
     @staticmethod
     def post_migrate_callback(*args, **kwargs):
         management.call_command("create_compat_groups")
-
+        create_permissions(*args, **kwargs)  # calling create_permissions() before using the permissions
+        logger.debug("Setting up custom permissions and groups.")
+        setup_groups()
diff --git a/ssoauth/setup_groups.py b/ssoauth/setup_groups.py
new file mode 100644
index 0000000..12bc3a5
--- /dev/null
+++ b/ssoauth/setup_groups.py
@@ -0,0 +1,32 @@
+from django.apps import apps
+from django.contrib.auth import get_user_model
+
+from . import app_settings
+from . import logger
+
+
+def setup_groups():
+    """
+    Creates groups and permissions as specified in your project settings.
+    """
+    # grab the required models
+    User = get_user_model()
+    Group = apps.get_model("auth", "Group")
+    ContentType = apps.get_model("contenttypes", "ContentType")
+    Permission = apps.get_model("auth", "Permission")
+
+    for group_name, permission_names in app_settings.GROUPS.items():
+        group, created = Group.objects.get_or_create(name=group_name)
+        if created:
+            logger.info("Created group \"{}\"".format(group_name))
+        for perm_name in permission_names:
+            perm, created = Permission.objects.get_or_create(
+                codename=perm_name,
+                name=perm_name,
+                content_type_id=ContentType.objects.get_for_model(User).id
+            )
+            if created:
+                logger.info("Created permission \"{}\"".format(perm_name))
+            if perm not in group.permissions.all():
+                group.permissions.add(perm)
+                logger.info("Added permission \"{}\" to group \"{}\"".format(perm_name, group_name))
-- 
GitLab