Implementado Logs de Pagos de Stripe y Historial de conexiones de seguridad
This commit is contained in:
+11
-1
@@ -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):
|
||||
|
||||
@@ -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
@@ -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):
|
||||
|
||||
@@ -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
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user