audit logs

This commit is contained in:
Faheedkhan 2025-06-03 21:03:32 +03:00
parent f41aaf14f7
commit be037e7fa6
8 changed files with 232 additions and 11 deletions

View File

@ -809,6 +809,11 @@ path(
path('management/user_management/', views.user_management, name='user_management'),
path('management/<str:content_type>/<slug:slug>/activate_account/', views.activate_account, name='activate_account'),
path('management/<str:content_type>/<slug:slug>/permenant_delete_account/', views.permenant_delete_account, name='permenant_delete_account'),
path('management/audit_log_management/', views.audit_log_management, name='audit_log_management'),
path('management/audit_log_management/modellogs', views.ModelLogListView.as_view(), name='modellogs_list'),
path('management/audit_log_management/authlogs', views.RequestLogListView.as_view(), name='authlogs_list'),
path('management/audit_log_management/requestlogs', views. AuthLogListView.as_view(), name='requestlogs_list'),
]

View File

@ -60,6 +60,7 @@ from django.views.generic import (
ArchiveIndexView,
)
# Django Ledger
from django_ledger.io import roles
from django_ledger.utils import accruable_net_summary
@ -149,6 +150,8 @@ from .utils import (
CarTransfer,
)
from .tasks import create_accounts_for_make, send_email
#djago easy audit log
from easyaudit.models import RequestEvent, CRUDEvent, LoginEvent
logger = logging.getLogger(__name__)
@ -8249,6 +8252,47 @@ def user_management(request):
}
return render(request, "admin_management/user_management.html", context)
#audit log Management
def audit_log_management(request):
return render(request, "admin_management/audit_log_lists.html")
#audit logs views
class RequestLogListView(ListView):
"""Displays a list of RequestEvents."""
model = RequestEvent
template_name = 'admin_management/request_logs.html'
context_object_name = 'request_events'
paginate_by = 20
def get_queryset(self):
# The field name in RequestEvent is 'datetime', not 'created'
return RequestEvent.objects.all().order_by('-datetime')
class ModelLogListView(ListView):
"""Displays a list of CRUDEvents (model changes)."""
# Corrected: Use CRUDEvent model
model = CRUDEvent
template_name = 'admin_management/model_logs.html'
context_object_name = 'model_events'
paginate_by = 20
def get_queryset(self):
# The field name in CRUDEvent is 'datetime', not 'created'
return CRUDEvent.objects.all().order_by('-datetime')
class AuthLogListView(ListView):
"""Displays a list of LoginEvents (authentication events)."""
model = LoginEvent
template_name = 'admin_management/auth_logs.html'
context_object_name = 'auth_events'
paginate_by = 20
def get_queryset(self):
# The field name in LoginEvent is 'datetime', not 'created'
return LoginEvent.objects.all().order_by('-datetime')
def activate_account(request, content_type, slug):
try:

View File

@ -94,3 +94,4 @@ urllib3==2.3.0
wcwidth==0.2.13
langchain
langchain_ollama
django-easy-audit==1.3.7

View File

@ -0,0 +1,65 @@
{% extends "base.html" %}
{% load i18n custom_filters %}
{% block title %}{% trans "Accounts" %}{% endblock title %}
{% block accounts %}
<a class="nav-link active fw-bold">
{% trans "Accounts"|capfirst %}
<span class="visually-hidden">(current)</span>
</a>
{% endblock %}
{% block content %}
<div class="row mt-4">
<div class="d-flex justify-content-between mb-2">
<h3 class=""><i class="fa-solid fa-book"></i> {% trans "Audit Log Management" %}</h3>
</div>
<!-- Log Type Tabs -->
<div class="mb-4">
<ul class="nav nav-tabs" id="accountTypeTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="modellogs-tab" data-bs-toggle="tab" data-bs-target="#modellogs" type="button" role="tab" aria-controls="modellogs" aria-selected="true">
<i class="fas fa-wallet me-2"></i>{% trans "User Actions" %}
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="authlogs-tab" data-bs-toggle="tab" data-bs-target="#authlogs" type="button" role="tab" aria-controls="authlogs" aria-selected="false">
<i class="fas fa-boxes me-2"></i>{% trans "User Login Events" %}
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="requestslog-tab" data-bs-toggle="tab" data-bs-target="#requestslog" type="button" role="tab" aria-controls="requestslog" aria-selected="false">
<i class="fas fa-landmark me-2"></i>{% trans "User Page Requests" %}
</button>
</li>
</ul>
<div class="tab-content p-3 border border-top-0 rounded-bottom" id="accountTypeTabsContent">
<!-- Tab -->
<div class="tab-pane fade show active" id="modellogs" role="tabpanel" aria-labelledby="modellogs-tab">
{% include "partials/search_box.html" %}
{% include "admin_management/model_logs.html" %}
</div>
<!-- COGS Tab -->
<div class="tab-pane fade" id="authlogs" role="tabpanel" aria-labelledby="authlogs-tab">
{% include "partials/search_box.html" %}
{% include "admin_management/auth_logs.html" %}
</div>
<!-- Capital Tab -->
<div class="tab-pane fade" id="requestslog" role="tabpanel" aria-labelledby="requestslog-tab">
{% include "partials/search_box.html" %}
{% include "admin_management/request_logs.html" %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -0,0 +1,29 @@
{% if auth_events %}
<table>
<thead>
<tr>
<th>Timestamp</th>
<th>User</th>
<th>Event Type</th>
<th>Username</th> {# Added username field #}
<th>IP Address</th>
</tr>
</thead>
<tbody>
{% for event in auth_events %}
<tr>
<td>{{ event.datetime }}</td> {# Corrected field name #}
<td>{{ event.user.username|default:"N/A" }}</td>
<td>{{ event.get_login_type_display }}</td> {# Corrected: get_login_type_display #}
<td>{{ event.username }}</td> {# Added username field #}
<td>{{ event.remote_ip }}</td> {# Corrected field name #}
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No authentication audit events found.</p>
{% endif %}

View File

@ -2,17 +2,28 @@
{% load i18n %}
{%block title%} {%trans 'Admin Management' %} {%endblock%}
{% block content %}
<h1 class="mt-4"><i class="fas fa-tools me-2"> </i>{{ _("Admin Management")}}</h1>
<div class="row row-cols-1 row-cols-md-4 g-4 mt-10">
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-4 g-4 mt-10">
<div class="col">
<a href="{% url 'user_management' %}">
<div class="card h-100">
<div class="card-header text-center">
<h5 class="card-title">{{ _("User Management")}}</h5>
<span class="me-2"><i class="fas fa-user fa-2x"></i></span>
</div>
</div>
</a>
<a href="{% url 'user_management' %}">
<div class="card h-100">
<div class="card-header text-center">
<h5 class="card-title">{{ _("User Management")}}</h5>
<span class="me-2"><i class="fas fa-user fa-2x"></i></span>
</div>
</div>
</a>
</div>
</div>
<div class="col">
<a href="{% url 'audit_log_management' %}">
<div class="card h-100">
<div class="card-header text-center">
<h5 class="card-title">{{ _("Audit Log Management")}}</h5>
<span class="me-2"><i class="fas fa-user fa-2x"></i></span>
</div>
</div>
</a>
</div>
</div>
{% endblock content %}

View File

@ -0,0 +1,37 @@
{% if model_events %}
<table>
<thead>
<tr>
<th>Timestamp</th>
<th>User</th>
<th>Action</th>
<th>Model</th>
<th>Object ID</th>
<th>Changes</th>
<th>Object Repr</th> {# Added for object representation #}
</tr>
</thead>
<tbody>
{% for event in model_events %}
<tr>
<td>{{ event.datetime }}</td> {# Corrected field name #}
<td>{{ event.user.username|default:"Anonymous" }}</td>
<td>{{ event.get_event_type_display }}</td>
<td>{{ event.content_type.model|title }}</td> {# Model name #}
<td>{{ event.object_id }}</td> {# Object ID #}
<td>
{% if event.changed_fields %} {# Corrected field name #}
<pre style="white-space: pre-wrap; word-break: break-all;">{{ event.changed_fields|safe }}</pre>
{% else %}
N/A
{% endif %}
</td>
<td>{{ event.object_repr }}</td> {# Object representation #}
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No model change audit events found.</p>
{% endif %}

View File

@ -0,0 +1,29 @@
{% if request_events %}
<table>
<thead>
<tr>
<th>Timestamp</th>
<th>User</th>
<th>URL</th> {# Changed from Path to URL based on model #}
<th>Method</th>
<th>IP Address</th>
{# No status_code in RequestEvent model #}
</tr>
</thead>
<tbody>
{% for event in request_events %}
<tr>
<td>{{ event.datetime }}</td> {# Corrected field name #}
<td>{{ event.user.username|default:"Anonymous" }}</td>
<td>{{ event.url }}</td> {# Corrected field name #}
<td>{{ event.method }}</td>
<td>{{ event.remote_ip }}</td> {# Corrected field name #}
{# Removed status_code as it's not in the model #}
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No request audit events found.</p>
{% endif %}