From 9e66760fae631eab603b9af339845bb55ad3ac2d Mon Sep 17 00:00:00 2001 From: bobbyvish Date: Tue, 2 Apr 2024 19:23:52 +0530 Subject: [PATCH] fix: iamprincipal --- module_activity/views.py | 21 +++-- module_auth/views.py | 19 ++-- module_cms/views.py | 36 ++++---- ...xt_processors.py => context_processors.py} | 13 +++ module_iam/permission.py | 86 +++++++++++++++++++ .../templatetags/resource_permission.py | 27 ++++++ module_iam/views.py | 45 ++++++---- module_notification/views.py | 10 +-- module_project/settings/base.py | 4 +- module_support/views.py | 13 ++- .../base_structure/elements/sidebar.html | 26 ++++-- templates/module_auth/user_view.html | 4 +- .../module_iam/iam_principal_group_link.html | 10 +-- 13 files changed, 234 insertions(+), 80 deletions(-) rename module_iam/{iam_context_processors.py => context_processors.py} (86%) create mode 100644 module_iam/permission.py create mode 100644 module_iam/templatetags/resource_permission.py diff --git a/module_activity/views.py b/module_activity/views.py index 0a276da..448b939 100644 --- a/module_activity/views.py +++ b/module_activity/views.py @@ -13,7 +13,7 @@ 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_iam.models import IAmPrincipal from module_project import constants, date_utils from module_project.utils import JsonResponseUtil @@ -29,7 +29,7 @@ logger = logging.getLogger(__name__) class BaseView(generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_USER - resource = None + resource = iam_constant.RESOURCE_MANAGE_USER action = None template_name = None model = None @@ -42,8 +42,9 @@ class BaseView(generic.TemplateView): return context -class BaseCreateOrUpdateView(LoginRequiredMixin, generic.View): +class BaseCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View): page_name = iam_constant.RESOURCE_MANAGE_USER + resource = iam_constant.RESOURCE_MANAGE_USER page_title = None model = None template_name = "module_activity/base_add.html" @@ -156,7 +157,7 @@ class BaseArchiveView(generic.TemplateView): return data -class PopulateFoodIngredientView(generic.View): +class PopulateFoodIngredientView(permission.ResourcePermissionRequiredMixin, generic.View): # Set the page_name and resource page_name = iam_constant.RESOURCE_MANAGE_DASHBOARD resource = iam_constant.RESOURCE_MANAGE_DASHBOARD @@ -481,8 +482,9 @@ class UserActivityRecordView(generic.View): return JsonResponseUtil.error(message="Something went wrong", errors=str(e)) -class MealDetialView(generic.TemplateView): +class MealDetialView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_USER + resource = iam_constant.RESOURCE_MANAGE_USER template_name = "module_activity/meal_detail.html" model = MealRecord @@ -503,8 +505,9 @@ class MealDetialView(generic.TemplateView): return context -class MedicationDetailView(generic.TemplateView): +class MedicationDetailView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_USER + resource = iam_constant.RESOURCE_MANAGE_USER template_name = "module_activity/medication_detail.html" model = Medication @@ -520,8 +523,9 @@ class MedicationDetailView(generic.TemplateView): return context -class BowelDetailView(generic.TemplateView): +class BowelDetailView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_USER + resource = iam_constant.RESOURCE_MANAGE_USER template_name = "module_activity/bowel_detail.html" model = Bowel @@ -538,8 +542,9 @@ class BowelDetailView(generic.TemplateView): return context -class MealSymptomDetailView(generic.TemplateView): +class MealSymptomDetailView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_USER + resource = iam_constant.RESOURCE_MANAGE_USER template_name = "module_activity/meal_symptom_details.html" model = MealSymptomRecord diff --git a/module_auth/views.py b/module_auth/views.py index 5c5493f..daf902c 100644 --- a/module_auth/views.py +++ b/module_auth/views.py @@ -19,7 +19,7 @@ from django_datatables_view.base_datatable_view import BaseDatatableView from module_activity.models import (Bowel, ChronicCondition, Intolerance, MealRecord, MealSymptomRecord, Medication, PastTreatment, PrincipalHealthData, Symptoms) -from module_iam import iam_constant +from module_iam import iam_constant, permission from module_iam.models import IAmPrincipal, IAmPrincipalType from module_project import constants from module_project.mixins import ActionMixin @@ -78,22 +78,22 @@ class CustomPasswordResetDoneView(PasswordResetDoneView): template_name = "module_auth/password_reset_done.html" -class UserDashView(LoginRequiredMixin, generic.TemplateView): +class UserDashView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_USER - resource = None + resource = iam_constant.RESOURCE_MANAGE_USER action = None template_name = "module_auth/users_list.html" model = IAmPrincipal context_objext_name = "obj" - def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context["page_name"] = self.page_name return context -class UserCreateOrUpdateView(LoginRequiredMixin, generic.View): +class UserCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View): page_name = iam_constant.RESOURCE_MANAGE_USER + resource = iam_constant.RESOURCE_MANAGE_USER model = IAmPrincipal form_class = UserForm template_name = "module_auth/user_add.html" @@ -220,9 +220,9 @@ class UserActionView(ActionMixin): return JsonResponseUtil.success(message=message) -class UserRecordView(LoginRequiredMixin, generic.View): +class UserRecordView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View): page_name = iam_constant.RESOURCE_MANAGE_USER - resource = None + resource = iam_constant.RESOURCE_MANAGE_USER action = None model = IAmPrincipal template_name = "module_auth/user_view.html" @@ -250,7 +250,6 @@ class UserRecordView(LoginRequiredMixin, generic.View): principal=id ).order_by('-id')[:5] - def get(self, request, id): # Retrieve the IAmPrincipal instance principal_instance = get_object_or_404(IAmPrincipal, id=id) @@ -304,9 +303,9 @@ class UserRecordView(LoginRequiredMixin, generic.View): return render(request, self.template_name, context=context) -class UserArchiveList(LoginRequiredMixin, generic.TemplateView): +class UserArchiveList(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_USER - resource = None + resource = iam_constant.RESOURCE_MANAGE_USER action = None template_name = "module_auth/users_archive_list.html" model = IAmPrincipal diff --git a/module_cms/views.py b/module_cms/views.py index 5330386..5020572 100644 --- a/module_cms/views.py +++ b/module_cms/views.py @@ -8,7 +8,7 @@ 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_iam.models import IAmPrincipal from module_project import constants from module_project.mixins import ActionMixin, DatatablesMixin @@ -20,9 +20,9 @@ from .models import Faqs, Organization logger = logging.getLogger(__name__) -class FaqView(LoginRequiredMixin, generic.TemplateView): +class FaqView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_FAQS - resource = None + resource = iam_constant.RESOURCE_MANAGE_FAQS action = None template_name = "module_cms/faq.html" model = Faqs @@ -71,7 +71,7 @@ class FaqListJson(BaseDatatableView): return qs -class FaqCreateOrUpdateView(LoginRequiredMixin, generic.View): +class FaqCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View): # Set the page_name and resource page_name = iam_constant.RESOURCE_MANAGE_FAQS resource = iam_constant.RESOURCE_MANAGE_FAQS @@ -139,9 +139,9 @@ class FaqActionView(ActionMixin): model = Faqs -class FaqArchiveView(LoginRequiredMixin, generic.TemplateView): +class FaqArchiveView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_FAQS - resource = None + resource = iam_constant.RESOURCE_MANAGE_FAQS action = None template_name = "module_cms/faq_archive.html" model = Faqs @@ -151,8 +151,9 @@ class FaqArchiveView(LoginRequiredMixin, generic.TemplateView): context["page_name"] = self.page_name return context -class AboutUsView(LoginRequiredMixin, generic.DetailView): +class AboutUsView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.DetailView): page_name = iam_constant.RESOURCE_MANAGE_CMS + resource = iam_constant.RESOURCE_MANAGE_CMS template_name = "module_cms/about_us_view.html" model = Organization context_object_name = "organization" @@ -166,11 +167,10 @@ class AboutUsView(LoginRequiredMixin, generic.DetailView): return context -class AboutUsCreateOrUpdateView(LoginRequiredMixin, generic.View): +class AboutUsCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View): # Set the page_name and resource page_name = iam_constant.RESOURCE_MANAGE_CMS - resource = None - + resource = iam_constant.RESOURCE_MANAGE_CMS # Initialize the action as ACTION_CREATE (can change based on logic) action = None # Default action @@ -229,9 +229,9 @@ class AboutUsCreateOrUpdateView(LoginRequiredMixin, generic.View): return redirect(self.success_url) -class TermsConditionView(LoginRequiredMixin, generic.DetailView): +class TermsConditionView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.DetailView): page_name = iam_constant.RESOURCE_MANAGE_T_C - resource = None + resource = iam_constant.RESOURCE_MANAGE_T_C action = None template_name = "module_cms/terms_and_condition_view.html" model = Organization @@ -246,10 +246,10 @@ class TermsConditionView(LoginRequiredMixin, generic.DetailView): return context -class TermsConditionCreateOrUpdateView(LoginRequiredMixin, generic.View): +class TermsConditionCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View): # Set the page_name and resource page_name = iam_constant.RESOURCE_MANAGE_T_C - resource = None + resource = iam_constant.RESOURCE_MANAGE_T_C # Initialize the action as ACTION_CREATE (can change based on logic) action = None # Default action @@ -309,9 +309,9 @@ class TermsConditionCreateOrUpdateView(LoginRequiredMixin, generic.View): return redirect(self.success_url) -class PrivacyPolicyView(LoginRequiredMixin, generic.DetailView): +class PrivacyPolicyView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.DetailView): page_name = iam_constant.RESOURCE_MANAGE_PRIVACYPOLICY - resource = None + resource = iam_constant.RESOURCE_MANAGE_PRIVACYPOLICY action = None template_name = "module_cms/privacy_policy_view.html" model = Organization @@ -326,10 +326,10 @@ class PrivacyPolicyView(LoginRequiredMixin, generic.DetailView): return context -class PrivacyPolicyCreateOrUpdateView(LoginRequiredMixin, generic.View): +class PrivacyPolicyCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View): # Set the page_name and resource page_name = iam_constant.RESOURCE_MANAGE_PRIVACYPOLICY - resource = None + resource = iam_constant.RESOURCE_MANAGE_PRIVACYPOLICY # Initialize the action as ACTION_CREATE (can change based on logic) action = None # Default action diff --git a/module_iam/iam_context_processors.py b/module_iam/context_processors.py similarity index 86% rename from module_iam/iam_context_processors.py rename to module_iam/context_processors.py index b531f9e..604f2a0 100644 --- a/module_iam/iam_context_processors.py +++ b/module_iam/context_processors.py @@ -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, } \ No newline at end of file diff --git a/module_iam/permission.py b/module_iam/permission.py new file mode 100644 index 0000000..e15474b --- /dev/null +++ b/module_iam/permission.py @@ -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 diff --git a/module_iam/templatetags/resource_permission.py b/module_iam/templatetags/resource_permission.py new file mode 100644 index 0000000..92bf4e6 --- /dev/null +++ b/module_iam/templatetags/resource_permission.py @@ -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" %} + + {% else %} + + {% endif %} + """ + # resource, action = resource_action.split(".") + return ResourcePermissionRequiredMixin().has_resource_permission(user, resource) diff --git a/module_iam/views.py b/module_iam/views.py index 6606f18..4790c2b 100644 --- a/module_iam/views.py +++ b/module_iam/views.py @@ -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 diff --git a/module_notification/views.py b/module_notification/views.py index b87b095..737dabc 100644 --- a/module_notification/views.py +++ b/module_notification/views.py @@ -12,7 +12,7 @@ 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_iam.iam_constant import PRINCIPAL_TYPE_USER from module_iam.models import IAmPrincipal from module_project import constants, date_utils @@ -25,7 +25,7 @@ from .models import PushNotification # Create your views here. -class NotificationView(LoginRequiredMixin, generic.TemplateView): +class NotificationView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_NOTIFICATION resource = iam_constant.RESOURCE_MANAGE_NOTIFICATION template_name = "module_notification/notification.html" @@ -77,7 +77,7 @@ class NotificationListJsonView(BaseDatatableView): return qs -class NotificationCreateOrUpdateView(LoginRequiredMixin, generic.View): +class NotificationCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View): # Set the page_name and resource page_name = iam_constant.RESOURCE_MANAGE_NOTIFICATION resource = iam_constant.RESOURCE_MANAGE_NOTIFICATION @@ -145,9 +145,9 @@ class NotificationCreateOrUpdateView(LoginRequiredMixin, generic.View): class NotificationActionView(ActionMixin): model = PushNotification -class NotificationArchiveView(LoginRequiredMixin, generic.TemplateView): +class NotificationArchiveView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_NOTIFICATION - resource = None + resource = iam_constant.RESOURCE_MANAGE_NOTIFICATION action = None template_name = "module_notification/notification_archive.html" model = PushNotification diff --git a/module_project/settings/base.py b/module_project/settings/base.py index 55251cc..daf382b 100644 --- a/module_project/settings/base.py +++ b/module_project/settings/base.py @@ -89,7 +89,7 @@ TEMPLATES = [ 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ - 'module_iam.iam_context_processors.iam_constants_context', + 'module_iam.context_processors.iam_constants_context', 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', @@ -285,7 +285,7 @@ SIMPLE_JWT = { } CRONJOBS = [ - ('* * * * *', 'manage_notification.cron_job.notification_for_meal_and_medication'), + ('0 18 * * *', 'manage_notification.cron_job.notification_for_meal_and_medication'), ] # Additional configuration for cron jobs diff --git a/module_support/views.py b/module_support/views.py index b60ee4b..79468ce 100644 --- a/module_support/views.py +++ b/module_support/views.py @@ -7,7 +7,7 @@ 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_iam.models import IAmPrincipal from module_project import constants from module_project.mixins import ActionMixin, DatatablesMixin @@ -19,9 +19,9 @@ from .models import ContactUs, Feedback # Create your views here. -class ContactUsView(LoginRequiredMixin, generic.TemplateView): +class ContactUsView(LoginRequiredMixin, permission.ResourcePermissionRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_CONTACT_US - resource = None + resource = iam_constant.RESOURCE_MANAGE_CONTACT_US action = None template_name = "module_support/contact_us.html" model = ContactUs @@ -84,9 +84,9 @@ class ContactUsListJson(BaseDatatableView): class ContactUsActionView(ActionMixin): model = ContactUs -class ContactUsArchiveView(LoginRequiredMixin, generic.TemplateView): +class ContactUsArchiveView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_CONTACT_US - resource = None + resource = iam_constant.RESOURCE_MANAGE_CONTACT_US action = None template_name = "module_support/contactus_archive_list.html" model = ContactUs @@ -128,8 +128,7 @@ class ContactUsReplyView(LoginRequiredMixin, generic.View): return JsonResponseUtil.error(message=constants.FAILURE, errors="Missing 'id' or 'message' in the request") - -class FeedbackView(LoginRequiredMixin, generic.TemplateView): +class FeedbackView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView): page_name = iam_constant.RESOURCE_MANAGE_FEEDBACK resource = iam_constant.RESOURCE_MANAGE_FEEDBACK action = None diff --git a/templates/base_structure/elements/sidebar.html b/templates/base_structure/elements/sidebar.html index 0210168..703f0fa 100644 --- a/templates/base_structure/elements/sidebar.html +++ b/templates/base_structure/elements/sidebar.html @@ -1,5 +1,6 @@ {% load static%} + {% load resource_permission %}
+ {% endif %} + {% if user|has_resource_permission:iam_constants_context.RESOURCE_MANAGE_USER %} + {% endif %} + {% if user|has_resource_permission:iam_constants_context.RESOURCE_MANAGE_FAQS or user|has_resource_permission:iam_constants_context.RESOURCE_MANAGE_T_C or user|has_resource_permission:iam_constants_context.RESOURCE_MANAGE_PRIVACYPOLICY %} - + {% endif %} + {% if user|has_resource_permission:iam_constants_context.RESOURCE_MANAGE_CONTACT_US or user|has_resource_permission:iam_constants_context.RESOURCE_MANAGE_FEEDBACK %} + {% endif %} @@ -135,6 +149,7 @@ --> + {% if user|has_resource_permission:iam_constants_context.RESOURCE_MANAGE_NOTIFICATION %} + {% endif %} diff --git a/templates/module_auth/user_view.html b/templates/module_auth/user_view.html index 99450fe..d9a4718 100644 --- a/templates/module_auth/user_view.html +++ b/templates/module_auth/user_view.html @@ -81,9 +81,9 @@

Height:

-

{{obj.health_data_principal.weight}} kg

+

{{obj.health_data_principal.weight}} {{obj.health_data_principal.weight_unit}}

{{obj.health_data_principal.ethenicity}}

-

{{obj.health_data_principal.height}} cm

+

{{obj.health_data_principal.height}} {{obj.health_data_principal.height_unit}}

diff --git a/templates/module_iam/iam_principal_group_link.html b/templates/module_iam/iam_principal_group_link.html index c4b2613..d07f21a 100644 --- a/templates/module_iam/iam_principal_group_link.html +++ b/templates/module_iam/iam_principal_group_link.html @@ -196,10 +196,10 @@ $(document).ready(function() { }; dataTableInstance = initializeDataTable(table1Settings); - activeSwitchEventListener(dataTableInstance); + activeSwitchEventListener(dataTableInstance, table1Settings); dataTable2Instance = initialize2DataTable(table2Settings); - activeSwitchEventListener(dataTable2Instance); + activeSwitchEventListener(dataTable2Instance, table2Settings); }); // Function to initialize DataTable @@ -490,15 +490,15 @@ function archiveAction(e, dt, node, config, tableSettings) { // Function to add event listener for switch -function activeSwitchEventListener(tableInstance) { +function activeSwitchEventListener(tableInstance, tableSettings) { // Add event listener for switch change event tableInstance.on('change', '.switch-input', function() { var rowId = $(this).closest('tr').find('.switch-input').data('id'); var isActive = $(this).prop('checked'); - console.log(rowId, isActive) + console.log("calling this data", rowId, isActive) // Perform active toggle action for the current user $.ajax({ - url: actionUrl, // Replace with your active toggle endpoint + url: tableSettings.actionUrl, // Replace with your active toggle endpoint type: 'POST', data: { action: "active",