mirror of https://github.com/snachodog/mybuddy.git
Refactor read only group creation as post migrate operation
This commit is contained in:
parent
996d81966c
commit
10a58e61b5
|
@ -2,10 +2,18 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db.models.signals import post_migrate
|
||||||
|
|
||||||
from babybuddy import VERSION
|
from babybuddy import VERSION
|
||||||
|
|
||||||
|
|
||||||
|
def create_read_only_group(sender, **kwargs):
|
||||||
|
from django.contrib.auth.models import Group
|
||||||
|
|
||||||
|
Group.objects.get_or_create(name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"])
|
||||||
|
|
||||||
|
|
||||||
class BabyBuddyConfig(AppConfig):
|
class BabyBuddyConfig(AppConfig):
|
||||||
name = "babybuddy"
|
name = "babybuddy"
|
||||||
verbose_name = "Baby Buddy"
|
verbose_name = "Baby Buddy"
|
||||||
|
@ -16,3 +24,4 @@ class BabyBuddyConfig(AppConfig):
|
||||||
if os.path.isfile(".git/refs/heads/master"):
|
if os.path.isfile(".git/refs/heads/master"):
|
||||||
commit = open(".git/refs/heads/master").read()
|
commit = open(".git/refs/heads/master").read()
|
||||||
self.version_string += " ({})".format(commit[0:7])
|
self.version_string += " ({})".format(commit[0:7])
|
||||||
|
post_migrate.connect(create_read_only_group, sender=self)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.forms import PasswordChangeForm, UserCreationForm
|
from django.contrib.auth.forms import PasswordChangeForm, UserCreationForm
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
|
@ -31,7 +32,11 @@ class BabyBuddyUserForm(forms.ModelForm):
|
||||||
user = kwargs["instance"]
|
user = kwargs["instance"]
|
||||||
if user:
|
if user:
|
||||||
kwargs["initial"].update(
|
kwargs["initial"].update(
|
||||||
{"is_read_only": user.groups.filter(name="read_only").exists()}
|
{
|
||||||
|
"is_read_only": user.groups.filter(
|
||||||
|
name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"]
|
||||||
|
).exists()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
super(BabyBuddyUserForm, self).__init__(*args, **kwargs)
|
super(BabyBuddyUserForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -44,7 +49,9 @@ class BabyBuddyUserForm(forms.ModelForm):
|
||||||
user.is_superuser = True
|
user.is_superuser = True
|
||||||
if commit:
|
if commit:
|
||||||
user.save()
|
user.save()
|
||||||
readonly_group = Group.objects.get(name="read_only")
|
readonly_group = Group.objects.get(
|
||||||
|
name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"]
|
||||||
|
)
|
||||||
if is_read_only:
|
if is_read_only:
|
||||||
user.groups.add(readonly_group.id)
|
user.groups.add(readonly_group.id)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -11,6 +11,7 @@ Example usage:
|
||||||
import sys
|
import sys
|
||||||
import getpass
|
import getpass
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model, models
|
from django.contrib.auth import get_user_model, models
|
||||||
from django.contrib.auth.password_validation import validate_password
|
from django.contrib.auth.password_validation import validate_password
|
||||||
from django.core import exceptions
|
from django.core import exceptions
|
||||||
|
@ -119,7 +120,9 @@ class Command(BaseCommand):
|
||||||
if is_read_only:
|
if is_read_only:
|
||||||
user.is_superuser = False
|
user.is_superuser = False
|
||||||
user.save()
|
user.save()
|
||||||
group = models.Group.objects.get(name="read_only")
|
group = models.Group.objects.get(
|
||||||
|
name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"]
|
||||||
|
)
|
||||||
user.groups.add(group)
|
user.groups.add(group)
|
||||||
else:
|
else:
|
||||||
user.is_superuser = True
|
user.is_superuser = True
|
||||||
|
|
|
@ -1,72 +1,6 @@
|
||||||
# Generated by Django 4.1.2 on 2022-10-23 08:21
|
# Generated by Django 4.1.2 on 2022-10-23 08:21
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
from django.contrib.auth.models import Group, Permission
|
|
||||||
import logging
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
# MODELS = [model.__name__ for model in apps.get_models()]
|
|
||||||
MODELS = [
|
|
||||||
"Tag",
|
|
||||||
"tagged",
|
|
||||||
"BMI",
|
|
||||||
"Child",
|
|
||||||
"Diaper Change",
|
|
||||||
"Feeding",
|
|
||||||
"Head Circumference",
|
|
||||||
"Height",
|
|
||||||
"Note",
|
|
||||||
"Pumping",
|
|
||||||
"Sleep",
|
|
||||||
"Temperature",
|
|
||||||
"Timer",
|
|
||||||
"Tummy Time",
|
|
||||||
"Weight",
|
|
||||||
"user",
|
|
||||||
]
|
|
||||||
PERMISSIONS = ["add", "change", "delete", "view"]
|
|
||||||
|
|
||||||
|
|
||||||
def add_group_permissions(apps, schema_editor):
|
|
||||||
group, created = Group.objects.get_or_create(name="read_only")
|
|
||||||
perm = []
|
|
||||||
for model in MODELS:
|
|
||||||
name = f"Can view {model}"
|
|
||||||
logging.info(f"Creating {name}...")
|
|
||||||
|
|
||||||
try:
|
|
||||||
perm.append(Permission.objects.get(name=name))
|
|
||||||
except Permission.DoesNotExist:
|
|
||||||
logging.warning(f"Permission not found with name {name}.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
group.permissions.add(*perm)
|
|
||||||
|
|
||||||
group, created = Group.objects.get_or_create(name="standard")
|
|
||||||
perm = []
|
|
||||||
for model in MODELS:
|
|
||||||
for permission in PERMISSIONS:
|
|
||||||
name = f"Can {permission} {model}"
|
|
||||||
logging.info(f"Creating {name}...")
|
|
||||||
|
|
||||||
try:
|
|
||||||
perm.append(Permission.objects.get(name=name))
|
|
||||||
except Permission.DoesNotExist:
|
|
||||||
logging.warning(f"Permission not found with name {name}.")
|
|
||||||
continue
|
|
||||||
|
|
||||||
group.permissions.add(*perm)
|
|
||||||
|
|
||||||
|
|
||||||
def revert_migration(apps, schema_editor):
|
|
||||||
Group.objects.filter(
|
|
||||||
name__in=[
|
|
||||||
"read_only",
|
|
||||||
"standard",
|
|
||||||
]
|
|
||||||
).delete()
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -74,4 +8,5 @@ class Migration(migrations.Migration):
|
||||||
("babybuddy", "0023_alter_settings_timezone"),
|
("babybuddy", "0023_alter_settings_timezone"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [migrations.RunPython(add_group_permissions, revert_migration)]
|
# Migration removed in favor of post migrate handling in core.apps.CoreConfig.
|
||||||
|
operations = []
|
||||||
|
|
|
@ -24,8 +24,8 @@ DEBUG = bool(strtobool(os.environ.get("DEBUG") or "False"))
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
"api",
|
"api",
|
||||||
"babybuddy",
|
"babybuddy.apps.BabyBuddyConfig",
|
||||||
"core",
|
"core.apps.CoreConfig",
|
||||||
"dashboard",
|
"dashboard",
|
||||||
"reports",
|
"reports",
|
||||||
"axes",
|
"axes",
|
||||||
|
@ -356,7 +356,8 @@ DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||||
# See README.md#configuration for details about these settings.
|
# See README.md#configuration for details about these settings.
|
||||||
|
|
||||||
BABY_BUDDY = {
|
BABY_BUDDY = {
|
||||||
"NAP_START_MIN": os.environ.get("NAP_START_MIN") or "06:00",
|
|
||||||
"NAP_START_MAX": os.environ.get("NAP_START_MAX") or "18:00",
|
|
||||||
"ALLOW_UPLOADS": bool(strtobool(os.environ.get("ALLOW_UPLOADS") or "True")),
|
"ALLOW_UPLOADS": bool(strtobool(os.environ.get("ALLOW_UPLOADS") or "True")),
|
||||||
|
"NAP_START_MAX": os.environ.get("NAP_START_MAX") or "18:00",
|
||||||
|
"NAP_START_MIN": os.environ.get("NAP_START_MIN") or "06:00",
|
||||||
|
"READ_ONLY_GROUP_NAME": "read_only",
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
from django import template
|
from django import template
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
from django.conf import settings
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import to_locale, get_language
|
from django.utils.translation import to_locale, get_language
|
||||||
|
|
||||||
|
@ -80,4 +81,4 @@ def user_is_locked(user):
|
||||||
|
|
||||||
@register.simple_tag()
|
@register.simple_tag()
|
||||||
def user_is_read_only(user):
|
def user_is_read_only(user):
|
||||||
return user.groups.filter(name="read_only").exists()
|
return user.groups.filter(name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"]).exists()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from django.test import TransactionTestCase
|
from django.test import TransactionTestCase
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ class CommandsTestCase(TransactionTestCase):
|
||||||
self.assertEqual(Child.objects.count(), 1)
|
self.assertEqual(Child.objects.count(), 1)
|
||||||
|
|
||||||
def test_createuser(self):
|
def test_createuser(self):
|
||||||
|
call_command("migrate", verbosity=0)
|
||||||
call_command(
|
call_command(
|
||||||
"createuser",
|
"createuser",
|
||||||
username="regularuser",
|
username="regularuser",
|
||||||
|
@ -66,4 +68,8 @@ class CommandsTestCase(TransactionTestCase):
|
||||||
self.assertIsInstance(user, get_user_model())
|
self.assertIsInstance(user, get_user_model())
|
||||||
self.assertFalse(user.is_superuser)
|
self.assertFalse(user.is_superuser)
|
||||||
self.assertFalse(user.is_staff)
|
self.assertFalse(user.is_staff)
|
||||||
self.assertTrue(user.groups.filter(name="read_only").exists())
|
self.assertTrue(
|
||||||
|
user.groups.filter(
|
||||||
|
name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"]
|
||||||
|
).exists()
|
||||||
|
)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.core.management import call_command
|
from django.core.management import call_command
|
||||||
from django.test import Client as HttpClient, override_settings, TestCase
|
from django.test import Client as HttpClient, override_settings, TestCase
|
||||||
|
@ -117,7 +118,11 @@ class FormsTestCase(TestCase):
|
||||||
self.assertIsInstance(user, get_user_model())
|
self.assertIsInstance(user, get_user_model())
|
||||||
self.assertTrue(user.is_superuser)
|
self.assertTrue(user.is_superuser)
|
||||||
self.assertFalse(user.is_staff)
|
self.assertFalse(user.is_staff)
|
||||||
self.assertFalse(user.groups.filter(name="read_only").exists())
|
self.assertFalse(
|
||||||
|
user.groups.filter(
|
||||||
|
name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"]
|
||||||
|
).exists()
|
||||||
|
)
|
||||||
|
|
||||||
def test_add_staff_user(self):
|
def test_add_staff_user(self):
|
||||||
self.user.is_staff = True
|
self.user.is_staff = True
|
||||||
|
@ -133,7 +138,11 @@ class FormsTestCase(TestCase):
|
||||||
self.assertIsInstance(user, get_user_model())
|
self.assertIsInstance(user, get_user_model())
|
||||||
self.assertTrue(user.is_superuser)
|
self.assertTrue(user.is_superuser)
|
||||||
self.assertTrue(user.is_staff)
|
self.assertTrue(user.is_staff)
|
||||||
self.assertFalse(user.groups.filter(name="read_only").exists())
|
self.assertFalse(
|
||||||
|
user.groups.filter(
|
||||||
|
name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"]
|
||||||
|
).exists()
|
||||||
|
)
|
||||||
|
|
||||||
def test_add_read_only_user(self):
|
def test_add_read_only_user(self):
|
||||||
self.user.is_staff = True
|
self.user.is_staff = True
|
||||||
|
@ -149,7 +158,11 @@ class FormsTestCase(TestCase):
|
||||||
self.assertIsInstance(user, get_user_model())
|
self.assertIsInstance(user, get_user_model())
|
||||||
self.assertFalse(user.is_superuser)
|
self.assertFalse(user.is_superuser)
|
||||||
self.assertFalse(user.is_staff)
|
self.assertFalse(user.is_staff)
|
||||||
self.assertTrue(user.groups.filter(name="read_only").exists())
|
self.assertTrue(
|
||||||
|
user.groups.filter(
|
||||||
|
name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"]
|
||||||
|
).exists()
|
||||||
|
)
|
||||||
|
|
||||||
def test_user_settings(self):
|
def test_user_settings(self):
|
||||||
self.c.login(**self.credentials)
|
self.c.login(**self.credentials)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
@ -26,6 +27,6 @@ class TemplateTagsTestCase(TestCase):
|
||||||
)
|
)
|
||||||
self.assertFalse(babybuddy.user_is_read_only(user))
|
self.assertFalse(babybuddy.user_is_read_only(user))
|
||||||
|
|
||||||
group = Group.objects.get(name="read_only")
|
group = Group.objects.get(name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"])
|
||||||
user.groups.add(group)
|
user.groups.add(group)
|
||||||
self.assertTrue(babybuddy.user_is_read_only(user))
|
self.assertTrue(babybuddy.user_is_read_only(user))
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from django.apps import AppConfig
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db.models.signals import post_migrate
|
||||||
|
|
||||||
|
|
||||||
|
def add_read_only_group_permissions(sender, **kwargs):
|
||||||
|
from django.apps import apps
|
||||||
|
from django.contrib.auth.models import Group, Permission
|
||||||
|
|
||||||
|
permissions = []
|
||||||
|
for model in apps.all_models["core"]:
|
||||||
|
try:
|
||||||
|
permissions.append(Permission.objects.get(codename=f"view_{model}"))
|
||||||
|
except Permission.DoesNotExist:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if len(permissions) > 0:
|
||||||
|
try:
|
||||||
|
group = Group.objects.get(name=settings.BABY_BUDDY["READ_ONLY_GROUP_NAME"])
|
||||||
|
group.permissions.add(*permissions)
|
||||||
|
except Group.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CoreConfig(AppConfig):
|
||||||
|
name = "core"
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
post_migrate.connect(add_read_only_group_permissions, sender=self)
|
Loading…
Reference in New Issue