Files
digest_app/module_iam/views.py

602 lines
23 KiB
Python
Raw Permalink Normal View History

import logging
from datetime import datetime
from typing import Any
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db import transaction
from django.db.models import Q
from django.db.models.base import Model as Model
from django.db.models.query import QuerySet
from django.http import JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse_lazy
from django.views import generic
from django_datatables_view.base_datatable_view import BaseDatatableView
2024-04-02 19:23:52 +05:30
from module_iam import iam_constant, permission
from module_project import constants
from module_project.mixins import ActionMixin
from module_project.utils import JsonResponseUtil
2024-04-02 19:23:52 +05:30
from .forms import (CustomAuthenticationForm, IAmPrincipalForm, IAmPrincipalResourceLinkForm,
IAmPrincipalGroupLinkForm, IAmPrincipalGroupRoleLinkForm,
IAmPrincipalRoleAppResourceActionLinkForm, ProfileEditForm)
from .models import (IAmAppResourceActionLink, IAmPrincipal, IAmPrincipalGroup,
IAmPrincipalType, IAmRole)
logger = logging.getLogger(__name__)
2024-02-26 13:28:32 +05:30
# Create your views here.
2024-04-02 19:23:52 +05:30
class DashboardView(LoginRequiredMixin, generic.TemplateView):
page_name = iam_constant.RESOURCE_MANAGE_DASHBOARD
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_MANAGE_DASHBOARD
template_name = "base_structure/layout/dashboard.html"
def get_user_count(self):
obj = IAmPrincipal.objects.all()
# Count active users
active_user_count = obj.filter(is_active=True).count()
# Count total users
total_user_count = obj.count()
return active_user_count, total_user_count
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
active_user_count, total_user_count = self.get_user_count()
context["active_user_count"] = active_user_count
context["total_user_count"] = total_user_count
context["page_name"] = self.page_name
return context
2024-04-02 19:23:52 +05:30
class PrincipalCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_IAM_PRINCIPAL
model = IAmPrincipal
form_class = IAmPrincipalForm
template_name = "module_iam/iam_principal_add.html"
success_url = reverse_lazy("module_iam:principal_group_link")
success_message = "Saved Successfully"
error_message = "An error occurred while saving the data."
def get_object(self):
pk = self.kwargs.get("pk")
return get_object_or_404(self.model, pk=pk) if pk else None
def get_context_data(self, **kwargs):
context = {
"page_name": self.page_name,
"operation": "Edit" if self.object else "Add",
}
context.update(kwargs) # Include any additional context data passed to the view
return context
def get(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.form_class(instance=self.object)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
@transaction.atomic
def post(self, request, *args, **kwargs):
print(request.POST)
self.object = self.get_object()
form = self.form_class(request.POST, instance=self.object)
try:
if form.is_valid():
principal = form.save(commit=False)
# Check if it's a new object (create action) or an existing one (update action)
if not principal.pk: # pk is None for new objects
principal.created_by = request.user
principal.modified_by = request.user
principal.modified_on = datetime.now()
# Save the object
principal.save()
messages.success(request, "Form submitted successfully")
return redirect(self.success_url)
except Exception as e:
self.error_message = constants.ERROR_OCCURR.format(str(e))
print(self.error_message)
messages.error(request, self.error_message)
context = self.get_context_data(form=form)
return render(request, template_name=self.template_name, context=context)
class PrincipalArchiveListJsonView(BaseDatatableView):
model = IAmPrincipal
columns = ["id", "first_name", "email", "is_active"]
order_columns = ["id", "first_name", "email", "is_active"]
def get_initial_queryset(self):
deleted_flag = self.request.GET.get("deleted_flag", False)
return self.model.objects.filter(
deleted=deleted_flag,
principal_type__name__in=(
iam_constant.PRINCIPAL_TYPE_ADMIN,
iam_constant.PRINCIPAL_TYPE_SUBADMIN,
),
)
def render_column(self, row, column):
if column == "principal_type_name":
return row.principal_type.name if row.principal_type else None
return super().render_column(row, column)
def filter_queryset(self, qs):
search_value = self.request.GET.get("search[value]", None)
if search_value:
qs = qs.filter(
Q(id__icontains=search_value)
| Q(first_name__icontains=search_value)
| Q(email__icontains=search_value)
)
return qs
2024-04-02 19:23:52 +05:30
class PrincipalResourcePermissionEditView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL
resource = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
2024-04-01 11:31:16 +05:30
model = IAmPrincipal
template_name = "module_iam/iam_principal_resource_permission_edit.html"
form_class = IAmPrincipalResourceLinkForm
success_url = reverse_lazy("module_iam:principal_group_link")
success_message = "Record Updated Successfully"
error_message = "An error occurred while saving the data"
def get_object(self):
pk = self.kwargs.get("pk")
return get_object_or_404(self.model, pk=pk) if pk else None
def get_context_data(self, **kwargs):
context = {
"page_name": self.page_name,
"operation": "Edit",
}
context.update(kwargs) # Include any additional context data passed to the view
return context
def get(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.form_class(instance=self.object)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.form_class(request.POST, instance=self.object)
if not form.is_valid():
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
form.save()
messages.success(request, self.success_message)
return redirect(self.success_url)
2024-04-02 19:23:52 +05:30
class PrincipalGroupLinkView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView):
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
model = IAmPrincipal
template_name = "module_iam/iam_principal_group_link.html"
def get_context_data(self, **kwargs) -> dict[str, Any]:
context = super().get_context_data(**kwargs)
context["page_name"] = self.page_name
return context
class PrincipalArchiveView(PrincipalGroupLinkView):
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_IAM_PRINCIPAL
action = None
template_name = "module_iam/iam_principal_archive.html"
class PrincipalGroupLinkAdminListJsonView(BaseDatatableView):
model = IAmPrincipal
columns = ["id", "first_name", "email", "is_active"]
order_columns = ["id", "first_name", "email", "is_active"]
def get_initial_queryset(self):
deleted_flag = self.request.GET.get("deleted_flag", False)
return self.model.objects.filter(
deleted=deleted_flag, principal_type__name=iam_constant.PRINCIPAL_TYPE_ADMIN
)
def render_column(self, row, column):
if column == "principal_type_name":
return row.principal_type.name if row.principal_type else None
return super().render_column(row, column)
def filter_queryset(self, qs):
search_value = self.request.GET.get("search[value]", None)
if search_value:
qs = qs.filter(
Q(id__icontains=search_value)
| Q(first_name__icontains=search_value)
| Q(email__icontains=search_value)
)
return qs
2024-04-02 19:23:52 +05:30
class PrincipalGroupLinkSubAdminListJsonView(permission.ResourcePermissionRequiredMixin, BaseDatatableView):
model = IAmPrincipal
columns = ["id", "first_name", "email", "is_active"]
order_columns = ["id", "first_name", "email", "is_active"]
def get_initial_queryset(self):
deleted_flag = self.request.GET.get("deleted_flag", False)
return self.model.objects.filter(
deleted=deleted_flag,
principal_type__name=iam_constant.PRINCIPAL_TYPE_SUBADMIN,
)
def render_column(self, row, column):
if column == "principal_type_name":
return row.principal_type.name if row.principal_type else None
2024-04-01 11:31:16 +05:30
if column == "permission":
return [{"name": resource.name} for resource in row.principal_resource.all()]
return super().render_column(row, column)
def filter_queryset(self, qs):
search_value = self.request.GET.get("search[value]", None)
if search_value:
qs = qs.filter(
Q(id__icontains=search_value)
| Q(first_name__icontains=search_value)
| Q(email__icontains=search_value)
)
return qs
2024-04-02 19:23:52 +05:30
class PrincipalGroupLinkEditView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
page_name = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_IAM_PRINCIPAL_GROUP
model = IAmPrincipal
template_name = "module_iam/iam_principal_group_link_edit.html"
form_class = IAmPrincipalGroupLinkForm
success_url = reverse_lazy("module_iam:principal_group_link")
success_message = "Record Updated Successfully"
error_message = "An error occurred while saving the data"
def get_object(self):
pk = self.kwargs.get("pk")
return get_object_or_404(self.model, pk=pk) if pk else None
def get_context_data(self, **kwargs):
context = {
"page_name": self.page_name,
"operation": "Edit",
}
context.update(kwargs) # Include any additional context data passed to the view
return context
def get(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.form_class(instance=self.object)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.form_class(request.POST, instance=self.object)
if not form.is_valid():
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
form.save()
messages.success(request, self.success_message)
return redirect(self.success_url)
class PrincipalGroupLinkActionView(generic.View):
model = IAmPrincipal
def post(self, request, *args, **kwargs):
if self.model is None:
raise NotImplementedError(
"Subclasses of BaseActionView must define a 'model' attribute."
)
action = request.POST.get("action") # 'archive', 'active', or 'unarchive'
ids = request.POST.getlist("ids[]") # List of IDs to perform action on
active = request.POST.get("active")
print(f"arhive action {action} and id is {ids} and active data is {active}")
if action == "archive":
# Update 'deleted' field to True for the selected users
self.model.objects.filter(id__in=ids).update(deleted=True, is_active=False)
message = "Record archived successfully."
elif action == "active":
# Update 'active' field to True for the selected users
self.model.objects.filter(id__in=ids).update(is_active=active.capitalize())
message = "Record updated successfully."
elif action == "unarchive":
# Update 'deleted' field to False for the selected users
self.model.objects.filter(id__in=ids).update(deleted=False)
message = "Record unarchived successfully."
else:
return JsonResponseUtil.error(message="Invalid Action")
return JsonResponseUtil.success(message=message)
2024-04-02 19:23:52 +05:30
class PrincipalGroupView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView):
page_name = iam_constant.RESOURCE_IAM_GROUP
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_IAM_GROUP
model = IAmPrincipalGroup
template_name = "module_iam/iam_group.html"
def get_context_data(self, **kwargs) -> dict[str, Any]:
context = super().get_context_data(**kwargs)
context["page_name"] = self.page_name
return context
class PrincipalGroupListJsonView(BaseDatatableView):
model = IAmPrincipalGroup
columns = ["id", "name", "active"]
order_columns = ["id", "name", "active"]
def get_initial_queryset(self):
deleted_flag = self.request.GET.get("deleted_flag", False)
return self.model.objects.filter(deleted=deleted_flag)
def render_column(self, row, column):
if column == "roles":
return [{"name": role.name} for role in row.role.all()]
return super().render_column(row, column)
def filter_queryset(self, qs):
search_value = self.request.GET.get("search[value]", None)
if search_value:
qs = qs.filter(
Q(id__icontains=search_value) | Q(name__icontains=search_value)
)
return qs
2024-04-02 19:23:52 +05:30
class PrincipalGroupCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
page_name = iam_constant.RESOURCE_IAM_GROUP
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_IAM_GROUP
page_title = "Principal Group"
model = IAmPrincipalGroup
template_name = "module_iam/iam_group_add.html"
form_class = IAmPrincipalGroupRoleLinkForm
success_url = reverse_lazy("module_iam:principal_group")
error_message = "An error occurred while saving the data."
def get_success_message(self):
self.success_message = (
constants.RECORD_CREATED if not self.object else constants.RECORD_UPDATED
)
return self.success_message
def get_object(self):
pk = self.kwargs.get("pk")
return get_object_or_404(self.model, pk=pk) if pk else None
def get_context_data(self, **kwargs):
context = {
"page_name": self.page_name,
"operation": "Add" if not self.object else "Edit",
}
context.update(kwargs) # Include any additional context data passed to the view
return context
def get(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.form_class(instance=self.object)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.form_class(request.POST, instance=self.object)
if not form.is_valid():
print(form.errors)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
form.save()
messages.success(self.request, self.get_success_message())
return redirect(self.success_url)
class PrincipalGroupActionView(ActionMixin):
model = IAmPrincipalGroup
class PrincipalGroupArchiveView(PrincipalGroupView):
template_name = "module_iam/iam_group_archive_list.html"
2024-04-02 19:23:52 +05:30
class AppRoleView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.TemplateView):
page_name = iam_constant.RESOURCE_IAM_ROLE
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_IAM_ROLE
model = IAmRole
template_name = "module_iam/iam_role.html"
def get_context_data(self, **kwargs) -> dict[str, Any]:
context = super().get_context_data(**kwargs)
context["page_name"] = self.page_name
return context
class AppRoleListJsonView(BaseDatatableView):
model = IAmRole
columns = ["id", "name", "active", "resources"]
order_columns = ["id", "name"]
def get_initial_queryset(self):
deleted_flag = self.request.GET.get("deleted_flag", False)
return (
super(AppRoleListJsonView, self)
.get_initial_queryset()
.prefetch_related(
"app_resource_action",
"app_resource_action__app_resource",
"app_resource_action__app_action",
)
.filter(deleted=deleted_flag)
)
def render_column(self, row, column):
if column == "resources":
resources = {}
# Loop through all the app_resource_action links for the current ro
for link in row.app_resource_action.all():
resource = link.app_resource.name
action = link.app_action.name
# If the resource is already in the dictionary, append the action to the list of actions
if resource in resources:
resources[resource].append(action)
# Otherwise, add the resource to the dictionary with a list containing the action
else:
resources[resource] = [action]
return resources
return super().render_column(row, column)
def filter_queryset(self, qs):
search_value = self.request.GET.get("search[value]", None)
if search_value:
qs = qs.filter(
Q(id__icontains=search_value)
| Q(name__icontains=search_value)
| Q(app_resource_action__app_resource__name__icontains=search_value)
| Q(app_resource_action__app_action__name__icontains=search_value)
)
return qs
2024-04-02 19:23:52 +05:30
class AppRoleCreateOrUpdateView(permission.ResourcePermissionRequiredMixin, LoginRequiredMixin, generic.View):
page_name = iam_constant.RESOURCE_IAM_ROLE
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_IAM_ROLE
model = IAmRole
template_name = "module_iam/iam_role_add.html"
form_class = IAmPrincipalRoleAppResourceActionLinkForm
success_url = reverse_lazy("module_iam:role")
success_message = "Saved Successfully"
error_message = "An error occurred while saving the data."
def get_success_message(self):
self.success_message = (
f"Record {'Created' if not self.object else 'Updated'} Successfully"
)
return self.success_message
def get_object(self):
pk = self.kwargs.get("pk")
return get_object_or_404(self.model, pk=pk) if pk else None
def get_context_data(self, **kwargs):
context = {
"page_name": self.page_name,
"operation": "Add" if not self.object else "Edit",
"app_resource_action": IAmAppResourceActionLink.objects.generate_app_resource_action_data(),
}
context.update(kwargs) # Include any additional context data passed to the view
return context
def get(self, request, *args, **kwargs):
try:
self.object = self.get_object()
form = self.form_class(instance=self.object)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
except Exception as e:
messages.error(request, str(e))
return redirect(self.success_url)
def post(self, request, *args, **kwargs):
try:
self.object = self.get_object()
form = self.form_class(request.POST, instance=self.object)
if not form.is_valid():
print(form.errors)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
form.save()
messages.success(self.request, self.get_success_message())
return redirect(self.success_url)
except Exception as e:
messages.error(self.request, str(e))
return redirect(self.success_url)
class AppRoleActionView(LoginRequiredMixin, ActionMixin):
model = IAmRole
class AppRoleArchiveView(AppRoleView):
template_name = "module_iam/iam_role_archive.html"
2024-05-15 11:11:27 +05:30
class PrincipalProfileView( LoginRequiredMixin, generic.TemplateView):
page_name = iam_constant.RESOURCE_MANAGE_DASHBOARD
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_MANAGE_DASHBOARD
model = IAmPrincipal
template_name = "module_iam/profile_details.html"
def get_object(self, queryset=None):
user = self.request.user.id
return get_object_or_404(
self.model.objects.select_related("principal_type", "principal_source"),
pk=user,
)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["page_name"] = self.page_name
context["data_obj"] = self.get_object()
return context
2024-05-15 11:11:27 +05:30
class PrincipalProfileEditView(LoginRequiredMixin, generic.View):
page_name = iam_constant.RESOURCE_MANAGE_DASHBOARD
2024-04-02 19:23:52 +05:30
resource = iam_constant.RESOURCE_MANAGE_DASHBOARD
model = IAmPrincipal
template_name = "module_iam/profile_details_edit.html"
form_class = ProfileEditForm
success_url = reverse_lazy("module_iam:profile_details")
success_message = "Saved Successfully"
error_message = "An error occurred while saving the data."
def get_success_message(self):
self.success_message = (
f"Record {'Created' if not self.object else 'Updated'} Successfully"
)
return self.success_message
def get_object(self):
return self.request.user
def get_context_data(self, **kwargs):
context = {
# "page_name": self.page_name,
"operation": "Edit",
"page_name": self.page_name,
}
context.update(kwargs) # Include any additional context data passed to the view
return context
def get(self, request, *args, **kwargs):
# try:
self.object = self.get_object()
form = self.form_class(instance=self.object)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.form_class(request.POST, request.FILES, instance=self.object)
if not form.is_valid():
print(form.errors)
context = self.get_context_data(form=form)
return render(request, self.template_name, context=context)
form.save()
messages.success(self.request, self.get_success_message())
return redirect(self.success_url)