diff --git a/home/admin.py b/home/admin.py
index 7abd91a..ee54876 100644
--- a/home/admin.py
+++ b/home/admin.py
@@ -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):
diff --git a/home/migrations/0010_loginattempt.py b/home/migrations/0010_loginattempt.py
new file mode 100644
index 0000000..3f008a9
--- /dev/null
+++ b/home/migrations/0010_loginattempt.py
@@ -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)),
+ ],
+ ),
+ ]
diff --git a/home/models.py b/home/models.py
index 2bd828c..e3666f3 100644
--- a/home/models.py
+++ b/home/models.py
@@ -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):
diff --git a/home/templates/partials/security_history.html b/home/templates/partials/security_history.html
index 01fe561..d62b8b0 100644
--- a/home/templates/partials/security_history.html
+++ b/home/templates/partials/security_history.html
@@ -1,82 +1,65 @@
-
-
-
Historial de seguridad
-
-
-
-
-
Aquà verás la actividad de la cuenta y los últimos 20 intentos de conexión de tu cuenta a la página web.
-
Si observas alguna actividad sospechosa puedes cambiar la contraseña o contactar con el equipo de {{ NOMBRE_SERVIDOR }}.
-
-
-
-
-
Historial de actividad
-
-
-
-
-
Historial de conexiones
-
-
-
- | Usuario |
- Estado |
- IP |
- Fecha |
-
-
- | INNAPMINE |
- Conexión exitosa |
- 37.133.171.76 |
- 12:13:36 11-11-2024 |
-
-
- | INNAPMINE |
- Conexión exitosa |
- 37.133.171.76 |
- 12:03:48 11-11-2024 |
-
-
- | INNAPMINE |
- Conexión exitosa |
- 37.133.171.76 |
- 10:12:54 11-11-2024 |
-
-
- | INNAPMINE |
- Conexión exitosa |
- 37.133.171.76 |
- 05:55:34 11-11-2024 |
-
-
- | INNAPMINE |
- Conexión exitosa |
- 84.236.195.21 |
- 18:48:48 10-11-2024 |
-
-
- | INNAPMINE |
- Conexión exitosa |
- 84.236.195.21 |
- 18:17:30 10-11-2024 |
-
-
- | INNAPMINE |
- Conexión exitosa |
- 84.236.195.21 |
- 14:25:53 10-11-2024 |
-
-
-
-
+
+
+
Historial de seguridad
+
+
+
+
+
Aquà verás la actividad de la cuenta y los últimos 20 intentos de conexión de tu cuenta a la página web.
+
Si observas alguna actividad sospechosa puedes cambiar la contraseña o contactar con el equipo de {{ NOMBRE_SERVIDOR }}.
-
\ No newline at end of file
+
+
+
Historial de actividad
+
+
+
+ {% if login_attempts %}
+ {% for attempt in login_attempts %}
+
+ | {{ attempt.username }} |
+ {{ attempt.timestamp|date:"d-m-Y H:i:s" }} |
+ {{ attempt.status }} |
+ {{ attempt.ip_address }} |
+
+ {% endfor %}
+ {% else %}
+
+ | No hay actividad |
+
+ {% endif %}
+
+
+
+
+
+
+
Historial de conexiones
+
+
+
+
+ | Usuario |
+ Estado |
+ IP |
+ Fecha |
+
+
+
+ {% for attempt in login_attempts %}
+
+ | {{ attempt.username }} |
+ {{ attempt.status }} |
+ {{ attempt.ip_address }} |
+ {{ attempt.timestamp|date:"d-m-Y H:i:s" }} |
+
+ {% endfor %}
+
+
+
+
+
+
+
diff --git a/home/views.py b/home/views.py
index f3d95eb..536798b 100644
--- a/home/views.py
+++ b/home/views.py
@@ -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):