Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions demo/demoapp/gtpermissions.py
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',
},

],
},


]


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change


#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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# Test creation of permissions related

3 changes: 2 additions & 1 deletion demo/demoapp/templates/ABCDE.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
{% block pre_head %}
{% define_urlname_action 'abcde-add'%}
{% define_urlname_action 'abcde-edit'%}
{% define_urlname_action 'abcde-delete'%}
{% define_urlname_action 'abcde-list'%}
{% endblock%}

Expand Down Expand Up @@ -50,4 +51,4 @@ <h2>ABCDE</h2>



{% endblock %}
{% endblock %}
5 changes: 4 additions & 1 deletion demo/demoapp/urls.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from django.urls import path, include
from markitup.views import apply_filter
from rest_framework.routers import DefaultRouter

from demoapp.cruds import Personclass, Countryclass, MenuItemclass
from demoapp.views import create_notification_view, bt_modal_display

from .autocomplete import views as autocompleteviews
from .calendar.views import calendar_view
from .chartjs import chart_js_view
Expand All @@ -24,6 +24,7 @@
from .views import knobView, YesNoInputView
from .wysiwyg import views as tinymce


pclss = Personclass()
countryclss = Countryclass()
menuclss = MenuItemclass()
Expand Down Expand Up @@ -97,6 +98,8 @@
path('chunkedupload/<int:pk>',
chunckedupload.Updatechunkedupload.as_view(),
name='chunkeduploaditem-edit'),


path('calendar_view', calendar_view, name="calendar_view"),
path('gigapixel_view', gigapixel_view, name="gigapixel_view"),
path('mapbased_view', mapbased_view, name="mapbased_view"),
Expand Down
11 changes: 10 additions & 1 deletion demo/demoapp/views.py
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', '')
Expand Down Expand Up @@ -54,3 +57,9 @@ def bt_modal_display(request):
'abcdeform': ABCDEModalGroupForm()
}
return render(request, 'btmodals.html', context=context)






Comment on lines +61 to +65
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

6 changes: 5 additions & 1 deletion djgentelella/admin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.contrib import admin

from djgentelella.models import MenuItem, Help, GentelellaSettings, Notification, \
ChunkedUpload
ChunkedUpload, PermissionRelated
from djgentelella.models import PermissionsCategoryManagement
from djgentelella.utils import clean_cache

Expand Down Expand Up @@ -33,9 +33,13 @@ class ChunkedUploadAdmin(admin.ModelAdmin):
list_filter = ('status',)


class PermissionRelatedAdmin(admin.ModelAdmin):
filter_horizontal = ['related_permissions']

admin.site.register(ChunkedUpload, ChunkedUploadAdmin)
admin.site.register(MenuItem, MenuAdmin)
admin.site.register(Help)
admin.site.register(PermissionRelated, PermissionRelatedAdmin)
admin.site.register(PermissionsCategoryManagement)
admin.site.register(GentelellaSettings, GentelellaSettingsAdmin)
admin.site.register(Notification, NotificationAdmin)
12 changes: 12 additions & 0 deletions djgentelella/apps.py
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)
70 changes: 70 additions & 0 deletions djgentelella/management/commands/show_permissions.py
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
except ModuleNotFoundError as e:
pass
except ModuleNotFoundError as e:
pass

before the pass report it to the logger using logger.exception

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)
23 changes: 23 additions & 0 deletions djgentelella/migrations/0013_permissionrelated.py
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')),
],
),
]
14 changes: 14 additions & 0 deletions djgentelella/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,17 @@ class ChunkedUpload(AbstractChunkedUpload):
null=DEFAULT_MODEL_USER_FIELD_NULL,
blank=DEFAULT_MODEL_USER_FIELD_BLANK
)



class PermissionRelated(models.Model):
main_permission = models.ForeignKey(Permission, on_delete=models.CASCADE)
related_permissions = models.ManyToManyField(Permission,
related_name='permission_dep')

def __str__(self):
return "perm: %d -- %s:%s %s " % (self.main_permission.pk,
self.main_permission._meta.app_label,
self.main_permission.codename,
self.main_permission.name
)
57 changes: 57 additions & 0 deletions djgentelella/permission_management/serializers.py
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__'
13 changes: 13 additions & 0 deletions djgentelella/permission_management/viewsets.py
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)
Loading