fix: iamprincipal
This commit is contained in:
@@ -27,6 +27,8 @@ from .iam_constant import (
|
||||
RESOURCE_IAM_ROLE,
|
||||
)
|
||||
|
||||
from .models import IAmPrincipal
|
||||
|
||||
def iam_constants_context(request):
|
||||
return {
|
||||
'iam_constants_context': {
|
||||
@@ -57,4 +59,15 @@ def iam_constants_context(request):
|
||||
'RESOURCE_IAM_GROUP': RESOURCE_IAM_GROUP,
|
||||
'RESOURCE_IAM_ROLE': RESOURCE_IAM_ROLE,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def resource_permissions(request):
|
||||
if request.user.is_authenticated:
|
||||
resource_permissions = IAmPrincipal.objects.filter(id=request.user.id).values_list('principal_resource__name', flat=True)
|
||||
else:
|
||||
resource_permissions = []
|
||||
|
||||
return {
|
||||
'resource_permissions': resource_permissions,
|
||||
}
|
||||
86
module_iam/permission.py
Normal file
86
module_iam/permission.py
Normal file
@@ -0,0 +1,86 @@
|
||||
from functools import wraps
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from . import models
|
||||
from django.db.models import Q
|
||||
# import logging
|
||||
|
||||
# logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# class CustomPermissionRequiredMixin:
|
||||
# resource = None
|
||||
# action = None
|
||||
|
||||
# def has_custom_permission(self, user, resource, action):
|
||||
# if not self.resource or not self.action:
|
||||
# raise AttributeError("Resource and action attributes must be defined in the view")
|
||||
|
||||
# # if not request.user.is_authenticated:
|
||||
# # return self.handle_no_permission()
|
||||
|
||||
# if user.is_superuser: # will chagne to principal type for admin
|
||||
# return True
|
||||
|
||||
# permission_query = Q(
|
||||
# principal_group__role__app_resource_action__app_resource__name=resource,
|
||||
# principal_group__role__app_resource_action__app_action__name=action
|
||||
# )
|
||||
# return models.IAmPrincipal.objects.filter(permission_query, id=user.id).exists()
|
||||
|
||||
# def dispatch(self, request, *args, **kwargs):
|
||||
# if not self.has_custom_permission(request.user, self.resource, self.action):
|
||||
# # logger.warning(f"Permission denied for user {request.user} accessing {self.resource}:{self.action}")
|
||||
# raise PermissionDenied("You do not have permission to access this resource.")
|
||||
# return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
# @classmethod
|
||||
# def as_decorator(cls, resource, action):
|
||||
# def decorator(view_func):
|
||||
# @wraps(view_func)
|
||||
# def _wrapped_view(request, *args, **kwargs):
|
||||
# instance = cls()
|
||||
# instance.resource = resource
|
||||
# instance.action = action
|
||||
# if not instance.has_custom_permission(request.user, instance.resource, instance.action):
|
||||
# raise PermissionDenied("You do not have permission to access this resource.")
|
||||
# return view_func(request, *args, **kwargs)
|
||||
# return _wrapped_view
|
||||
# return decorator
|
||||
|
||||
|
||||
class ResourcePermissionRequiredMixin:
|
||||
resource = None
|
||||
|
||||
def has_resource_permission(self, user, resource):
|
||||
# if not self.resource or resource:
|
||||
# raise AttributeError("Resource attributes must be defined in the view")
|
||||
|
||||
# if not request.user.is_authenticated:
|
||||
# return self.handle_no_permission()
|
||||
|
||||
if user.is_superuser: # will chagne to principal type for admin
|
||||
return True
|
||||
|
||||
permission_query = Q(
|
||||
principal_resource__name=resource,
|
||||
)
|
||||
return models.IAmPrincipal.objects.filter(permission_query, id=user.id).exists()
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
if not self.has_resource_permission(request.user, self.resource):
|
||||
# logger.warning(f"Permission denied for user {request.user} accessing {self.resource}:{self.action}")
|
||||
raise PermissionDenied("You do not have permission to access this resource.")
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
@classmethod
|
||||
def as_decorator(cls, resource):
|
||||
def decorator(view_func):
|
||||
@wraps(view_func)
|
||||
def _wrapped_view(request, *args, **kwargs):
|
||||
instance = cls()
|
||||
instance.resource = resource
|
||||
if not instance.has_resource_permission(request.user, instance.resource):
|
||||
raise PermissionDenied("You do not have permission to access this resource.")
|
||||
return view_func(request, *args, **kwargs)
|
||||
return _wrapped_view
|
||||
return decorator
|
||||
27
module_iam/templatetags/resource_permission.py
Normal file
27
module_iam/templatetags/resource_permission.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from django import template
|
||||
from module_iam.permission import ResourcePermissionRequiredMixin
|
||||
|
||||
register = template.Library()
|
||||
|
||||
|
||||
@register.filter(name='has_resource_permission')
|
||||
def has_resource_permission(user, resource):
|
||||
"""
|
||||
Check if a user has a specific resource and action permission.
|
||||
|
||||
Args:
|
||||
user (User): The user to check for permission.
|
||||
resource_action (str): The resource and action string (e.g., "resource_name.action_name").
|
||||
|
||||
Returns:
|
||||
bool: True if the user has the specified permission, False otherwise.
|
||||
|
||||
Example usage in a template:
|
||||
{% if user|has_resource_permission:"article" %}
|
||||
<!-- Render content for users with permission -->
|
||||
{% else %}
|
||||
<!-- Render content for users without permission -->
|
||||
{% endif %}
|
||||
"""
|
||||
# resource, action = resource_action.split(".")
|
||||
return ResourcePermissionRequiredMixin().has_resource_permission(user, resource)
|
||||
@@ -14,12 +14,12 @@ from django.urls import reverse_lazy
|
||||
from django.views import generic
|
||||
from django_datatables_view.base_datatable_view import BaseDatatableView
|
||||
|
||||
from module_iam import iam_constant
|
||||
from module_iam import iam_constant, permission
|
||||
from module_project import constants
|
||||
from module_project.mixins import ActionMixin, DatatablesMixin
|
||||
from module_project.utils import JsonResponseUtil
|
||||
|
||||
from .forms import (CustomAuthenticationForm, IAmPrincipalForm,IAmPrincipalResourceLinkForm,
|
||||
from .forms import (CustomAuthenticationForm, IAmPrincipalForm, IAmPrincipalResourceLinkForm,
|
||||
IAmPrincipalGroupLinkForm, IAmPrincipalGroupRoleLinkForm,
|
||||
IAmPrincipalRoleAppResourceActionLinkForm, ProfileEditForm)
|
||||
from .models import (IAmAppResourceActionLink, IAmPrincipal, IAmPrincipalGroup,
|
||||
@@ -30,8 +30,9 @@ logger = logging.getLogger(__name__)
|
||||
# Create your views here.
|
||||
|
||||
|
||||
class DashboardView(generic.TemplateView):
|
||||
class DashboardView(LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = iam_constant.RESOURCE_MANAGE_DASHBOARD
|
||||
resource = iam_constant.RESOURCE_MANAGE_DASHBOARD
|
||||
template_name = "base_structure/layout/dashboard.html"
|
||||
|
||||
def get_user_count(self):
|
||||
@@ -51,8 +52,9 @@ class DashboardView(generic.TemplateView):
|
||||
return context
|
||||
|
||||
|
||||
class PrincipalCreateOrUpdateView(LoginRequiredMixin, generic.View):
|
||||
class PrincipalCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
|
||||
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL
|
||||
resource = iam_constant.RESOURCE_IAM_PRINCIPAL
|
||||
model = IAmPrincipal
|
||||
form_class = IAmPrincipalForm
|
||||
template_name = "module_iam/iam_principal_add.html"
|
||||
@@ -137,10 +139,9 @@ class PrincipalArchiveListJsonView(BaseDatatableView):
|
||||
)
|
||||
return qs
|
||||
|
||||
|
||||
|
||||
class PrincipalResourcePermissionEditView(LoginRequiredMixin, generic.View):
|
||||
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
|
||||
class PrincipalResourcePermissionEditView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
|
||||
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL
|
||||
resource = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
|
||||
model = IAmPrincipal
|
||||
template_name = "module_iam/iam_principal_resource_permission_edit.html"
|
||||
form_class = IAmPrincipalResourceLinkForm
|
||||
@@ -177,8 +178,9 @@ class PrincipalResourcePermissionEditView(LoginRequiredMixin, generic.View):
|
||||
return redirect(self.success_url)
|
||||
|
||||
|
||||
class PrincipalGroupLinkView(LoginRequiredMixin, generic.TemplateView):
|
||||
class PrincipalGroupLinkView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
|
||||
resource = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
|
||||
model = IAmPrincipal
|
||||
template_name = "module_iam/iam_principal_group_link.html"
|
||||
|
||||
@@ -189,7 +191,7 @@ class PrincipalGroupLinkView(LoginRequiredMixin, generic.TemplateView):
|
||||
|
||||
class PrincipalArchiveView(PrincipalGroupLinkView):
|
||||
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL
|
||||
resource = None
|
||||
resource = iam_constant.RESOURCE_IAM_PRINCIPAL
|
||||
action = None
|
||||
template_name = "module_iam/iam_principal_archive.html"
|
||||
|
||||
@@ -221,7 +223,7 @@ class PrincipalGroupLinkAdminListJsonView(BaseDatatableView):
|
||||
return qs
|
||||
|
||||
|
||||
class PrincipalGroupLinkSubAdminListJsonView(BaseDatatableView):
|
||||
class PrincipalGroupLinkSubAdminListJsonView(permission.ResourcePermissionRequiredMixin, BaseDatatableView):
|
||||
model = IAmPrincipal
|
||||
columns = ["id", "first_name", "email", "is_active"]
|
||||
order_columns = ["id", "first_name", "email", "is_active"]
|
||||
@@ -251,8 +253,9 @@ class PrincipalGroupLinkSubAdminListJsonView(BaseDatatableView):
|
||||
return qs
|
||||
|
||||
|
||||
class PrincipalGroupLinkEditView(LoginRequiredMixin, generic.View):
|
||||
class PrincipalGroupLinkEditView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
|
||||
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
|
||||
resource = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
|
||||
model = IAmPrincipal
|
||||
template_name = "module_iam/iam_principal_group_link_edit.html"
|
||||
form_class = IAmPrincipalGroupLinkForm
|
||||
@@ -321,8 +324,9 @@ class PrincipalGroupLinkActionView(generic.View):
|
||||
return JsonResponseUtil.success(message=message)
|
||||
|
||||
|
||||
class PrincipalGroupView(LoginRequiredMixin, generic.TemplateView):
|
||||
class PrincipalGroupView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = iam_constant.RESOURCE_IAM_GROUP
|
||||
resource = iam_constant.RESOURCE_IAM_GROUP
|
||||
model = IAmPrincipalGroup
|
||||
template_name = "module_iam/iam_group.html"
|
||||
|
||||
@@ -355,8 +359,9 @@ class PrincipalGroupListJsonView(BaseDatatableView):
|
||||
return qs
|
||||
|
||||
|
||||
class PrincipalGroupCreateOrUpdateView(LoginRequiredMixin, generic.View):
|
||||
class PrincipalGroupCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
|
||||
page_name = iam_constant.RESOURCE_IAM_GROUP
|
||||
resource = iam_constant.RESOURCE_IAM_GROUP
|
||||
page_title = "Principal Group"
|
||||
model = IAmPrincipalGroup
|
||||
template_name = "module_iam/iam_group_add.html"
|
||||
@@ -407,8 +412,9 @@ class PrincipalGroupActionView(ActionMixin):
|
||||
class PrincipalGroupArchiveView(PrincipalGroupView):
|
||||
template_name = "module_iam/iam_group_archive_list.html"
|
||||
|
||||
class AppRoleView(LoginRequiredMixin, generic.TemplateView):
|
||||
class AppRoleView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = iam_constant.RESOURCE_IAM_ROLE
|
||||
resource = iam_constant.RESOURCE_IAM_ROLE
|
||||
model = IAmRole
|
||||
template_name = "module_iam/iam_role.html"
|
||||
|
||||
@@ -464,8 +470,9 @@ class AppRoleListJsonView(BaseDatatableView):
|
||||
return qs
|
||||
|
||||
|
||||
class AppRoleCreateOrUpdateView(LoginRequiredMixin, generic.View):
|
||||
class AppRoleCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
|
||||
page_name = iam_constant.RESOURCE_IAM_ROLE
|
||||
resource = iam_constant.RESOURCE_IAM_ROLE
|
||||
model = IAmRole
|
||||
template_name = "module_iam/iam_role_add.html"
|
||||
form_class = IAmPrincipalRoleAppResourceActionLinkForm
|
||||
@@ -526,8 +533,9 @@ class AppRoleArchiveView(AppRoleView):
|
||||
template_name = "module_iam/iam_role_archive.html"
|
||||
|
||||
|
||||
class PrincipalProfileView(LoginRequiredMixin, generic.TemplateView):
|
||||
class PrincipalProfileView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView):
|
||||
page_name = iam_constant.RESOURCE_MANAGE_DASHBOARD
|
||||
resource = iam_constant.RESOURCE_MANAGE_DASHBOARD
|
||||
model = IAmPrincipal
|
||||
template_name = "module_iam/profile_details.html"
|
||||
|
||||
@@ -545,8 +553,9 @@ class PrincipalProfileView(LoginRequiredMixin, generic.TemplateView):
|
||||
return context
|
||||
|
||||
|
||||
class PrincipalProfileEditView(generic.View):
|
||||
class PrincipalProfileEditView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
|
||||
page_name = iam_constant.RESOURCE_MANAGE_DASHBOARD
|
||||
resource = iam_constant.RESOURCE_MANAGE_DASHBOARD
|
||||
model = IAmPrincipal
|
||||
template_name = "module_iam/profile_details_edit.html"
|
||||
form_class = ProfileEditForm
|
||||
|
||||
Reference in New Issue
Block a user