Implementado Logs de Pagos de Stripe y Historial de conexiones de seguridad

This commit is contained in:
adevopg
2025-02-18 11:42:46 +01:00
parent e94915e667
commit 0a650eb161
5 changed files with 136 additions and 91 deletions
+11 -1
View File
@@ -3,7 +3,8 @@ from django.contrib import admin
from django import forms
from .models import (
Noticia, ClienteCategoria, SistemaOperativo, ServerSelection,
RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, GuildRenameSettings, VoteSite, RenamePrice, CustomizePrice, ChangeRacePrice, ChangeFactionPrice, LevelUpPrice, GoldPrice, TransferPrice, MaintenanceMode
RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, GuildRenameSettings, VoteSite, RenamePrice, CustomizePrice, ChangeRacePrice, ChangeFactionPrice, LevelUpPrice, GoldPrice, TransferPrice, MaintenanceMode,
StripeLog
)
from django.db import connections
import logging
@@ -12,6 +13,15 @@ from django_ckeditor_5.widgets import CKEditor5Widget
logger = logging.getLogger(__name__)
@admin.register(StripeLog)
class StripeLogAdmin(admin.ModelAdmin):
list_display = (
'account_id', 'username', 'email', 'acore_ip', 'stripe_ip', 'product_name',
'amount', 'session_id', 'mode', 'character_name', 'timestamp'
) # Añadido stripe_ip
list_filter = ('mode', 'timestamp') # Filtros por campo en la parte lateral
search_fields = ('username', 'product_name', 'session_id', 'email', 'stripe_ip') # Ahora incluye 'stripe_ip' en la búsqueda
ordering = ('-timestamp',) # Ordenar por timestamp descendentes
@admin.register(ChangeFactionPrice)
class ChangeFactionPriceAdmin(admin.ModelAdmin):
+23
View File
@@ -0,0 +1,23 @@
# Generated by Django 5.1.4 on 2025-02-18 10:37
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('home', '0009_stripelog'),
]
operations = [
migrations.CreateModel(
name='LoginAttempt',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('username', models.CharField(max_length=100)),
('status', models.CharField(max_length=50)),
('ip_address', models.GenericIPAddressField()),
('timestamp', models.DateTimeField(auto_now_add=True)),
],
),
]
+10 -1
View File
@@ -270,7 +270,16 @@ class HomeApiPoints(models.Model):
db_table = 'home_api_points'
def __str__(self):
return f"Cuenta {self.accountID} - PV: {self.vp}, DP: {self.dp}"
return f"Cuenta {self.accountID} - PV: {self.vp}, DP: {self.dp}"
class LoginAttempt(models.Model):
username = models.CharField(max_length=100)
status = models.CharField(max_length=50) # Ejemplo: 'Éxito' o 'Fracaso'
ip_address = models.GenericIPAddressField() # IP del intento de inicio de sesión
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.username} - {self.status} - {self.timestamp}"
class StripeLog(models.Model):
+62 -79
View File
@@ -1,82 +1,65 @@
<div class="main-page">
<div class="middle-content">
<div class="body-content">
<div class="title-content"><h1>Historial de seguridad</h1></div>
<div class="box-content">
<div class="title-box-content"><h2>Información</h2><a class="back-to-account" href="my-account">Regresar a mi cuenta</a><a class="back-to-account-responsive" href="my-account">Regresar</a></div>
<div class="body-box-content justified">
<br>
<p>Aquí verás la actividad de la cuenta y los últimos 20 intentos de conexión de tu cuenta a la página web.</p>
<p>Si observas alguna actividad sospechosa puedes cambiar la contraseña o contactar con el equipo de {{ NOMBRE_SERVIDOR }}.</p>
</div>
</div>
<div class="box-content">
<div class="title-box-content"><h2>Historial de actividad</h2></div>
<div class="body-box-content centered">
<table class="max-center-table-aligned2">
<tbody><tr>
<td class="centered"><span>No hay actividad</span></td>
</tr>
</tbody></table>
</div>
</div>
<div class="box-content">
<div class="title-box-content"><h2>Historial de conexiones</h2></div>
<div class="body-box-content centered">
<table class="max-center-table-aligned">
<tbody><tr>
<th>Usuario</th>
<th>Estado</th>
<th>IP</th>
<th>Fecha</th>
</tr>
<tr>
<td><span>INNAPMINE</span></td>
<td><span>Conexión exitosa</span></td>
<td class="long-td"><span>37.133.171.76</span></td>
<td><span>12:13:36 11-11-2024</span></td>
</tr>
<tr>
<td><span>INNAPMINE</span></td>
<td><span>Conexión exitosa</span></td>
<td class="long-td"><span>37.133.171.76</span></td>
<td><span>12:03:48 11-11-2024</span></td>
</tr>
<tr>
<td><span>INNAPMINE</span></td>
<td><span>Conexión exitosa</span></td>
<td class="long-td"><span>37.133.171.76</span></td>
<td><span>10:12:54 11-11-2024</span></td>
</tr>
<tr>
<td><span>INNAPMINE</span></td>
<td><span>Conexión exitosa</span></td>
<td class="long-td"><span>37.133.171.76</span></td>
<td><span>05:55:34 11-11-2024</span></td>
</tr>
<tr>
<td><span>INNAPMINE</span></td>
<td><span>Conexión exitosa</span></td>
<td class="long-td"><span>84.236.195.21</span></td>
<td><span>18:48:48 10-11-2024</span></td>
</tr>
<tr>
<td><span>INNAPMINE</span></td>
<td><span>Conexión exitosa</span></td>
<td class="long-td"><span>84.236.195.21</span></td>
<td><span>18:17:30 10-11-2024</span></td>
</tr>
<tr>
<td><span>INNAPMINE</span></td>
<td><span>Conexión exitosa</span></td>
<td class="long-td"><span>84.236.195.21</span></td>
<td><span>14:25:53 10-11-2024</span></td>
</tr>
</tbody></table>
</div>
</div>
<div class="middle-content">
<div class="body-content">
<div class="title-content"><h1>Historial de seguridad</h1></div>
<div class="box-content">
<div class="title-box-content"><h2>Información</h2><a class="back-to-account" href="my-account">Regresar a mi cuenta</a><a class="back-to-account-responsive" href="my-account">Regresar</a></div>
<div class="body-box-content justified">
<br>
<p>Aquí verás la actividad de la cuenta y los últimos 20 intentos de conexión de tu cuenta a la página web.</p>
<p>Si observas alguna actividad sospechosa puedes cambiar la contraseña o contactar con el equipo de {{ NOMBRE_SERVIDOR }}.</p>
</div>
</div>
</div>
<div class="box-content">
<div class="title-box-content"><h2>Historial de actividad</h2></div>
<div class="body-box-content centered">
<table class="max-center-table-aligned2">
<tbody>
{% if login_attempts %}
{% for attempt in login_attempts %}
<tr>
<td>{{ attempt.username }}</td> <!-- Agregado: Mostrar el nombre de usuario -->
<td>{{ attempt.timestamp|date:"d-m-Y H:i:s" }}</td>
<td>{{ attempt.status }}</td>
<td>{{ attempt.ip_address }}</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="4" class="centered"><span>No hay actividad</span></td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
<div class="box-content">
<div class="title-box-content"><h2>Historial de conexiones</h2></div>
<div class="body-box-content centered">
<table class="max-center-table-aligned">
<thead>
<tr>
<th>Usuario</th>
<th>Estado</th>
<th>IP</th>
<th>Fecha</th>
</tr>
</thead>
<tbody>
{% for attempt in login_attempts %}
<tr>
<td>{{ attempt.username }}</td>
<td>{{ attempt.status }}</td>
<td>{{ attempt.ip_address }}</td>
<td>{{ attempt.timestamp|date:"d-m-Y H:i:s" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
+30 -10
View File
@@ -8,7 +8,8 @@ from django.contrib.auth import logout
from django import forms
import stripe
from .pagos_stripe import create_checkout_session
from .models import Noticia, ClienteCategoria, ServerSelection, RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, ClaimedReward, AccountActivation, SecurityToken, GuildRenameSettings, VoteSite, VoteLog, HomeApiPoints, UnstuckHistory, ReviveHistory, RenamePrice, CustomizePrice, ChangeRacePrice, ChangeFactionPrice, LevelUpPrice, GoldPrice, TransferPrice, Category, Item, StripeLog
from .models import Noticia, ClienteCategoria, ServerSelection, RecruitAFriend, DownloadClientPage, ContentCreator, RecruitReward, ClaimedReward, AccountActivation, SecurityToken, GuildRenameSettings, VoteSite, VoteLog, HomeApiPoints, UnstuckHistory, ReviveHistory, RenamePrice, CustomizePrice, ChangeRacePrice, ChangeFactionPrice, LevelUpPrice, GoldPrice, TransferPrice, Category, Item, StripeLog, LoginAttempt
from django.views.decorators.csrf import csrf_exempt
from datetime import datetime, timedelta
from .zone_definitions import get_zone_name
@@ -196,20 +197,26 @@ def login_view(request):
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
ip_address = request.META.get('REMOTE_ADDR') # Obtener la IP del cliente
# Llamar a la función de autenticación
# Llamar a la funci¨®n de autenticaci¨®n
if authenticate(username, password):
# Guardar el nombre de usuario en mayúsculas en la sesión
# Guardar el intento exitoso
log_login_attempt(username, "Exito", ip_address)
# Guardar el nombre de usuario en may¨²sculas en la sesi¨®n
request.session['username'] = username.upper()
return JsonResponse({'success': True})
else:
return JsonResponse({'success': False, 'error': "Usuario o contraseña incorrectos"})
# Guardar el intento fallido
log_login_attempt(username, "Fracaso", ip_address)
return JsonResponse({'success': False, 'error': "Usuario o contrase?a incorrectos"})
else:
return JsonResponse({'success': False, 'error': "Formulario no válido"})
return JsonResponse({'success': False, 'error': "Formulario no valido"})
form = LoginForm()
return render(request, 'auth/login.html', {'form': form})
# Función para contar los personajes en línea
def get_online_characters_count():
with connections['acore_characters'].cursor() as cursor:
@@ -2320,10 +2327,23 @@ def ban_history_view(request):
return render(request, 'account/ban_history.html')
def security_history_view(request):
"""
Vista para mostrar el historial de seguridad del usuario.
"""
return render(request, 'account/security_history.html')
username = request.session.get('username')
if not username:
return redirect('login') # Si no est¨¢ autenticado, redirigir al login
# Obtener los ¨²ltimos 20 intentos de inicio de sesi¨®n
login_attempts = LoginAttempt.objects.filter(username=username).order_by('-timestamp')[:20]
return render(request, 'account/security_history.html', {'login_attempts': login_attempts})
def log_login_attempt(username, status, ip_address):
# Registrar intento de inicio de sesi¨®n en el historial
LoginAttempt.objects.create(
username=username,
status=status,
ip_address=ip_address,
timestamp=timezone.now()
)
def trade_points_view(request):