-
-
Notifications
You must be signed in to change notification settings - Fork 28
Implementation related permissions and self-selection, planning and design #65 #68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
ca09d83
f389b31
c9fdc53
58316ae
410fdf2
e1c21ec
d88964d
e867644
f1309ef
1497041
66b7060
be63a42
dbd2d23
1f4fcb6
f751c5c
2abb48b
42fd57c
b4538b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,89 @@ | ||||||||||
| #Related permissions | ||||||||||
| from unittest import TestCase | ||||||||||
|
|
||||||||||
| permissions_to_create = [ | ||||||||||
| { | ||||||||||
| 'app_label': 'demoapp', | ||||||||||
| 'main_permission_natural_name': 'Can change abcde', | ||||||||||
| 'main_permission_codename': 'change_abcde', | ||||||||||
| 'related_permissions': [ | ||||||||||
| { | ||||||||||
| 'app_label': 'auth', | ||||||||||
| 'name': 'Can add user', | ||||||||||
| 'codename': 'add_user', | ||||||||||
| }, | ||||||||||
|
|
||||||||||
| ], | ||||||||||
| }, | ||||||||||
| { | ||||||||||
| 'app_label': 'demoapp', | ||||||||||
| 'main_permission_natural_name': 'Can add abcde', | ||||||||||
| 'main_permission_codename': 'add_abcde', | ||||||||||
| 'related_permissions': [ | ||||||||||
| { | ||||||||||
| 'app_label': 'sessions', | ||||||||||
| 'name': 'Can add session', | ||||||||||
| 'codename': 'add_session', | ||||||||||
| }, | ||||||||||
|
|
||||||||||
| ], | ||||||||||
| }, | ||||||||||
|
|
||||||||||
|
|
||||||||||
| ] | ||||||||||
|
|
||||||||||
|
|
||||||||||
|
|
||||||||||
| #delete permissions | ||||||||||
| def remove_related_permission(app_label, main_permission_codename, | ||||||||||
| related_permission_codename): | ||||||||||
| global permissions_to_create | ||||||||||
| for permission in permissions_to_create: | ||||||||||
| if ( | ||||||||||
| permission['app_label'] == app_label | ||||||||||
| and permission['main_permission_codename'] == main_permission_codename | ||||||||||
| ): | ||||||||||
| related_permissions = permission.get('related_permissions', []) | ||||||||||
| updated_related_permissions = [ | ||||||||||
| rel_perm | ||||||||||
| for rel_perm in related_permissions | ||||||||||
| if rel_perm['codename'] != related_permission_codename | ||||||||||
| ] | ||||||||||
| permission['related_permissions'] = updated_related_permissions | ||||||||||
| return True | ||||||||||
|
|
||||||||||
| # return false if not found nothing. | ||||||||||
| return False | ||||||||||
|
|
||||||||||
|
|
||||||||||
| #update permissions | ||||||||||
| def update_related_permission(app_label, main_permission_codename, related_permission_codename, new_name, new_codename): | ||||||||||
| for permission in permissions_to_create: | ||||||||||
| if ( | ||||||||||
| permission['app_label'] == app_label | ||||||||||
| and permission['main_permission_codename'] == main_permission_codename | ||||||||||
| and 'related_permissions' in permission | ||||||||||
| ): | ||||||||||
| related_permissions = permission['related_permissions'] | ||||||||||
| for rel_perm in related_permissions: | ||||||||||
| if rel_perm['codename'] == related_permission_codename: | ||||||||||
| rel_perm['name'] = new_name | ||||||||||
| rel_perm['codename'] = new_codename | ||||||||||
| return True | ||||||||||
|
|
||||||||||
| return False | ||||||||||
|
|
||||||||||
| def add_related_permission(main_permission_codename, related_permissions): | ||||||||||
| for permission in permissions_to_create: | ||||||||||
| if ( | ||||||||||
| permission['main_permission_codename'] == main_permission_codename | ||||||||||
| and 'related_permissions' in permission | ||||||||||
| ): | ||||||||||
| permission['related_permissions'].append(related_permissions) | ||||||||||
| return True | ||||||||||
| return False | ||||||||||
|
|
||||||||||
|
|
||||||||||
|
|
||||||||||
|
|
||||||||||
| # Test creation of permissions related | ||||||||||
|
Comment on lines
+86
to
+89
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -1,15 +1,18 @@ | ||||
| from django.contrib import messages | ||||
| from django.contrib.auth.decorators import login_required | ||||
| from django.contrib.auth.models import Permission | ||||
| from django.shortcuts import render, redirect | ||||
| from django.urls import reverse_lazy | ||||
| from django.views.generic import CreateView | ||||
|
|
||||
| from rest_framework import generics | ||||
| from rest_framework.permissions import IsAuthenticated | ||||
| from djgentelella.notification import create_notification | ||||
| from .autocomplete.forms import ABCDEModalGroupForm | ||||
| from .forms import FooModelForm, YesNoInputAddForm, PersonModalForm | ||||
| from .models import YesNoInput | ||||
|
|
||||
|
|
||||
|
|
||||
| @login_required | ||||
| def create_notification_view(request): | ||||
| email = request.GET.get('email', '') | ||||
|
|
@@ -54,3 +57,9 @@ def bt_modal_display(request): | |||
| 'abcdeform': ABCDEModalGroupForm() | ||||
| } | ||||
| return render(request, 'btmodals.html', context=context) | ||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
Comment on lines
+61
to
+65
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,18 @@ | ||
| from django.apps import AppConfig | ||
| from django.apps import AppConfig | ||
|
|
||
| from django.db.models.signals import post_migrate | ||
|
|
||
| def my_callback(sender, **kwargs): | ||
|
|
||
|
|
||
| from django.core import management | ||
| management.call_command('show_permissions') | ||
|
|
||
|
|
||
| class DjgentelellaConfig(AppConfig): | ||
| default_auto_field = 'django.db.models.AutoField' | ||
| name = 'djgentelella' | ||
|
|
||
| def ready(self): | ||
| post_migrate.connect(my_callback, sender=self) |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,70 @@ | ||||||||||
| from django.conf import settings | ||||||||||
| from django.core.management.base import BaseCommand | ||||||||||
| from django.contrib.auth.models import Permission | ||||||||||
| from django.dispatch.dispatcher import logger | ||||||||||
|
|
||||||||||
| from djgentelella.models import PermissionRelated | ||||||||||
|
|
||||||||||
|
|
||||||||||
|
|
||||||||||
| class Command(BaseCommand): | ||||||||||
| help = 'Create related permissions in the database' | ||||||||||
| permissions_to_create = [] | ||||||||||
|
|
||||||||||
| def import_module_app_gt(self, app, name): | ||||||||||
| try: | ||||||||||
| variable = __import__(app + '.' + name) | ||||||||||
| return variable.gtpermissions.permissions_to_create | ||||||||||
| except ModuleNotFoundError as e: | ||||||||||
| pass | ||||||||||
|
Comment on lines
+18
to
+19
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
before the pass report it to the logger using |
||||||||||
| except AttributeError as e: | ||||||||||
| logger.exception("Attribute error") | ||||||||||
| return [] | ||||||||||
|
|
||||||||||
| def fill_permission_to_create(self): | ||||||||||
| for app in settings.INSTALLED_APPS: | ||||||||||
| self.permissions_to_create += self.import_module_app_gt(app, 'gtpermissions') | ||||||||||
|
|
||||||||||
| def create_related_permissions(self, perm_data): | ||||||||||
| app_label = perm_data['app_label'] | ||||||||||
| main_permission_natural_name = perm_data['main_permission_natural_name'] | ||||||||||
| main_permission_codename = perm_data['main_permission_codename'] | ||||||||||
| related_permissions_data = perm_data['related_permissions'] | ||||||||||
|
|
||||||||||
| main_permission = Permission.objects.filter( | ||||||||||
| content_type__app_label=app_label, | ||||||||||
| name=main_permission_natural_name, | ||||||||||
| codename=main_permission_codename | ||||||||||
| ).first() | ||||||||||
|
|
||||||||||
| if not main_permission: | ||||||||||
| self.stdout.write(self.style.WARNING( | ||||||||||
| f"Main permission '{app_label}.{main_permission_natural_name}' not found.")) | ||||||||||
| return | ||||||||||
|
|
||||||||||
| related_permissions = [] | ||||||||||
| for related_perm_data in related_permissions_data: | ||||||||||
| app_label_related = related_perm_data['app_label'] | ||||||||||
| name_related = related_perm_data['name'] | ||||||||||
| codename_related = related_perm_data['codename'] | ||||||||||
|
|
||||||||||
| related_permission = Permission.objects.filter( | ||||||||||
| content_type__app_label=app_label_related, | ||||||||||
| name=name_related, | ||||||||||
| codename=codename_related | ||||||||||
| ).first() | ||||||||||
| if related_permission: | ||||||||||
| related_permissions.append(related_permission) | ||||||||||
|
|
||||||||||
| permission_related, _ = PermissionRelated.objects.get_or_create( | ||||||||||
| main_permission=main_permission) | ||||||||||
| permission_related.related_permissions.set(related_permissions) | ||||||||||
|
|
||||||||||
| self.stdout.write(self.style.SUCCESS( | ||||||||||
| f"Updated related permissions for '{app_label}.{main_permission_natural_name}'")) | ||||||||||
|
|
||||||||||
| def handle(self, *args, **options): | ||||||||||
| self.fill_permission_to_create() | ||||||||||
|
|
||||||||||
| for perm_data in self.permissions_to_create: | ||||||||||
| self.create_related_permissions(perm_data) | ||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Generated by Django 4.2.4 on 2023-09-11 21:10 | ||
|
|
||
| from django.db import migrations, models | ||
| import django.db.models.deletion | ||
|
|
||
|
|
||
| class Migration(migrations.Migration): | ||
|
|
||
| dependencies = [ | ||
| ('auth', '0013_custompermission'), | ||
| ('djgentelella', '00012_defaultusecompessstatic'), | ||
| ] | ||
|
|
||
| operations = [ | ||
| migrations.CreateModel( | ||
| name='PermissionRelated', | ||
| fields=[ | ||
| ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
| ('main_permission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.permission')), | ||
| ('related_permissions', models.ManyToManyField(related_name='permission_dep', to='auth.permission')), | ||
| ], | ||
| ), | ||
| ] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| from unittest import TestCase | ||
|
|
||
| from django.contrib.auth.models import Permission | ||
| from rest_framework import serializers | ||
|
|
||
| from djgentelella.models import PermissionRelated | ||
|
|
||
|
|
||
|
|
||
| class PermissionSerializer(serializers.ModelSerializer): | ||
| class Meta: | ||
| model = Permission | ||
| fields = ['id', 'codename', 'name'] | ||
|
|
||
|
|
||
| class PermissionRelatedSerializer(serializers.ModelSerializer): | ||
| related_permissions = serializers.SerializerMethodField() | ||
|
|
||
|
|
||
| def remove_permisssion(self): | ||
| user = self.context['view'].request.user | ||
| user_perms = list(user.user_permissions.all().values_list('id', flat=True)) | ||
| group_perms = list(user.groups.all().values_list('permissions', flat=True)) | ||
| cache_perms = list() | ||
| if hasattr(user, '_perm_cache'): | ||
| cache_perms = list(user._perm_cache) | ||
|
|
||
| all_perms = set(user_perms + group_perms + cache_perms) | ||
| self.list_of_perms = list( | ||
| set(self.list_of_perms) - all_perms | ||
| ) | ||
|
|
||
| def find_permission_related(self, listofid, recursion=0, max_recursion=10): | ||
| if max_recursion == recursion: | ||
| return | ||
|
|
||
| rel_perms = set(PermissionRelated.objects.filter( | ||
| main_permission__in=listofid | ||
| ).values_list( | ||
| 'related_permissions', flat=True)) | ||
| rel_perms = rel_perms - set(self.list_of_perms) | ||
| if rel_perms: | ||
| self.list_of_perms += list(rel_perms) | ||
| self.find_permission_related(rel_perms, recursion=recursion + 1) | ||
|
|
||
| def get_related_permissions(self, obj): | ||
| self.list_of_perms = list( | ||
| obj.related_permissions.all().values_list('id', flat=True)) | ||
|
|
||
| self.find_permission_related(self.list_of_perms) | ||
| # self.remove_permisssion() | ||
| list_of_perms = Permission.objects.filter(pk__in=self.list_of_perms) | ||
| return PermissionSerializer(list_of_perms, many=True).data | ||
|
|
||
| class Meta: | ||
| model = PermissionRelated | ||
| fields = '__all__' |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| from django.shortcuts import get_object_or_404 | ||
| from rest_framework import generics | ||
| from djgentelella.models import PermissionRelated | ||
| from djgentelella.permission_management.serializers import PermissionRelatedSerializer | ||
|
|
||
|
|
||
| class PermissionRelatedDetailView(generics.RetrieveAPIView): | ||
| queryset = PermissionRelated.objects.all() | ||
| serializer_class = PermissionRelatedSerializer | ||
|
|
||
| def get_object(self): | ||
| permission_id = self.kwargs['permission_id'] | ||
| return get_object_or_404(PermissionRelated, main_permission_id=permission_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.