Adapta el portal a 3.4.3 (cuentas Battle.net + selector de cuenta de juego)
- home/bnet.py: SRP6 v2 (PBKDF2-HMAC-SHA512) para battlenet_accounts y SRP6 Grunt (SHA1) para las cuentas de juego, con helpers bnet<->game account - login por email contra battlenet_accounts; selector de cuenta de juego cuando la cuenta bnet tiene varias (my_account redirige al selector) - registro/activación crean battlenet_accounts + account enlazada (<bnetId>#1, battlenet_account/battlenet_index) - cambio de contraseña sobre battlenet_accounts; cambio de email recalcula salt/verifier (el usuario SRP depende del email) - AccountActivation: identidad por email (username/salt/verifier opcionales) + migración - plantillas login/register por email + nueva plantilla del selector - docs/MIGRACION_3.4.3.md con el detalle y los pasos de verificación Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+203
-122
@@ -15,6 +15,7 @@ from django.views.decorators.csrf import csrf_exempt
|
||||
from datetime import datetime, timedelta
|
||||
from .zone_definitions import get_zone_name
|
||||
from .ac_soap import execute_soap_command
|
||||
from . import bnet
|
||||
from django.utils import timezone
|
||||
from .library_correo import enviar_correo
|
||||
from django.utils.crypto import get_random_string
|
||||
@@ -131,9 +132,9 @@ def formatear_fecha(fecha):
|
||||
return f"{dia_semana} {fecha.day:02d} de {mes} del {fecha.year}"
|
||||
|
||||
|
||||
# Clase de formulario de inicio de sesión
|
||||
# Clase de formulario de inicio de sesión (Battle.net: login por email)
|
||||
class LoginForm(forms.Form):
|
||||
username = forms.CharField(max_length=32, required=True)
|
||||
email = forms.EmailField(max_length=320, required=True)
|
||||
password = forms.CharField(widget=forms.PasswordInput, required=True)
|
||||
|
||||
def sha1(data):
|
||||
@@ -164,60 +165,96 @@ def calculate_srp6_verifier(username, password, salt):
|
||||
# Convertir el resultado a hexadecimal en mayúsculas
|
||||
return binascii.hexlify(verifier_bytes).decode('utf-8').upper()
|
||||
|
||||
def authenticate(username, password):
|
||||
def authenticate(email, password):
|
||||
"""Autentica una cuenta Battle.net por email (SRP6 v2)."""
|
||||
try:
|
||||
# Obtener el salt y el verifier de la base de datos
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute("SELECT salt, verifier FROM account WHERE username = %s", [username])
|
||||
result = cursor.fetchone()
|
||||
|
||||
if not result:
|
||||
return False
|
||||
|
||||
salt, stored_verifier = result
|
||||
|
||||
# Convertir `salt` y `verifier` a formato hexadecimal si son bytes
|
||||
if isinstance(salt, bytes):
|
||||
salt = salt.hex()
|
||||
if isinstance(stored_verifier, bytes):
|
||||
stored_verifier = stored_verifier.hex()
|
||||
|
||||
# Calcular el verifier con el username y password proporcionados
|
||||
calculated_verifier = calculate_srp6_verifier(username, password, salt)
|
||||
|
||||
# Comparar el verifier calculado con el almacenado en la base de datos
|
||||
return calculated_verifier.strip().upper() == stored_verifier.strip().upper()
|
||||
|
||||
account = bnet.get_bnet_account_by_email(cursor, email)
|
||||
if not account:
|
||||
return None
|
||||
if bnet.bnet_verify(account['email'], password, account['salt'], account['verifier']):
|
||||
return account
|
||||
return None
|
||||
except Exception:
|
||||
return False
|
||||
return None
|
||||
|
||||
|
||||
def _set_game_account_session(request, game_account):
|
||||
"""Fija en sesión la cuenta de juego seleccionada (para las demás vistas)."""
|
||||
request.session['username'] = game_account['username'].upper()
|
||||
request.session['account_id'] = game_account['id']
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
def login_view(request):
|
||||
if request.method == 'POST':
|
||||
form = LoginForm(request.POST)
|
||||
if form.is_valid():
|
||||
username = form.cleaned_data['username']
|
||||
email = form.cleaned_data['email']
|
||||
password = form.cleaned_data['password']
|
||||
ip_address = request.META.get('REMOTE_ADDR') # Obtener la IP del cliente
|
||||
ip_address = request.META.get('REMOTE_ADDR')
|
||||
|
||||
# Llamar a la función de autenticación
|
||||
if authenticate(username, password):
|
||||
# Guardar el intento exitoso
|
||||
log_login_attempt(username, "Exito", ip_address)
|
||||
account = authenticate(email, password)
|
||||
if account:
|
||||
log_login_attempt(email, "Exito", ip_address)
|
||||
|
||||
# Guardar la identidad Battle.net en la sesión
|
||||
request.session['bnet_id'] = account['id']
|
||||
request.session['bnet_email'] = account['email']
|
||||
|
||||
# Resolver las cuentas de juego enlazadas
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
game_accounts = bnet.get_game_accounts_for_bnet(cursor, account['id'])
|
||||
|
||||
if len(game_accounts) == 1:
|
||||
# Una sola cuenta de juego: seleccionar automáticamente
|
||||
_set_game_account_session(request, game_accounts[0])
|
||||
elif len(game_accounts) > 1:
|
||||
# Varias: dejar la selección pendiente (my-account redirige al selector)
|
||||
request.session.pop('username', None)
|
||||
request.session.pop('account_id', None)
|
||||
# 0 cuentas: se queda sin username; el selector mostrará el aviso
|
||||
|
||||
# Guardar el nombre de usuario en mayúsculas en la sesión
|
||||
request.session['username'] = username.upper()
|
||||
return JsonResponse({'success': True})
|
||||
else:
|
||||
# Guardar el intento fallido
|
||||
log_login_attempt(username, "Fracaso", ip_address)
|
||||
|
||||
return JsonResponse({'success': False, 'error': "Usuario o contraseña incorrectos"})
|
||||
log_login_attempt(email, "Fracaso", ip_address)
|
||||
return JsonResponse({'success': False, 'error': "Correo o contraseña incorrectos"})
|
||||
else:
|
||||
return JsonResponse({'success': False, 'error': "Formulario no valido"})
|
||||
|
||||
|
||||
form = LoginForm()
|
||||
return render(request, 'auth/login.html', {'form': form})
|
||||
|
||||
|
||||
def select_account_view(request):
|
||||
"""Selector de cuenta de juego para cuentas Battle.net con varias."""
|
||||
bnet_id = request.session.get('bnet_id')
|
||||
if not bnet_id:
|
||||
return redirect('login')
|
||||
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
game_accounts = bnet.get_game_accounts_for_bnet(cursor, bnet_id)
|
||||
|
||||
if request.method == 'POST':
|
||||
try:
|
||||
selected_id = int(request.POST.get('account_id', ''))
|
||||
except (TypeError, ValueError):
|
||||
selected_id = None
|
||||
chosen = next((g for g in game_accounts if g['id'] == selected_id), None)
|
||||
if chosen:
|
||||
_set_game_account_session(request, chosen)
|
||||
return redirect('my-account')
|
||||
messages.error(request, 'Cuenta de juego no válida.')
|
||||
|
||||
# Autoseleccionar si solo hay una
|
||||
if len(game_accounts) == 1:
|
||||
_set_game_account_session(request, game_accounts[0])
|
||||
return redirect('my-account')
|
||||
|
||||
return render(request, 'auth/select_account.html', {
|
||||
'game_accounts': game_accounts,
|
||||
'bnet_email': request.session.get('bnet_email'),
|
||||
})
|
||||
# Función para contar los personajes en línea
|
||||
def get_online_characters_count():
|
||||
with connections['acore_characters'].cursor() as cursor:
|
||||
@@ -292,42 +329,46 @@ def server_status_view(request):
|
||||
|
||||
# Vista para cerrar sesión
|
||||
def logout_view(request):
|
||||
if 'username' in request.session:
|
||||
del request.session['username']
|
||||
for key in ('username', 'account_id', 'bnet_id', 'bnet_email'):
|
||||
request.session.pop(key, None)
|
||||
return redirect('index')
|
||||
|
||||
# Vistas adicionales
|
||||
@csrf_exempt
|
||||
def register_view(request):
|
||||
if request.method == 'POST':
|
||||
username = request.POST.get('username').strip()
|
||||
password = request.POST.get('password').strip()
|
||||
conf_password = request.POST.get('conf-password').strip()
|
||||
email = request.POST.get('email').strip()
|
||||
conf_email = request.POST.get('conf-email').strip()
|
||||
recruiter = request.POST.get('recruiter').strip()
|
||||
password = request.POST.get('password', '').strip()
|
||||
conf_password = request.POST.get('conf-password', '').strip()
|
||||
email = request.POST.get('email', '').strip()
|
||||
conf_email = request.POST.get('conf-email', '').strip()
|
||||
recruiter = request.POST.get('recruiter', '').strip()
|
||||
|
||||
# Validar entradas
|
||||
if not username or not password or not email:
|
||||
# En 3.4.3 la identidad es el email (cuenta Battle.net); no hay username.
|
||||
if not password or not email:
|
||||
return JsonResponse({'success': False, 'message': 'Por favor, complete todos los campos.'})
|
||||
|
||||
if len(username) > 17 or not username.isalnum():
|
||||
return JsonResponse({'success': False, 'message': 'Nombre de usuario no válido.'})
|
||||
|
||||
if password != conf_password:
|
||||
return JsonResponse({'success': False, 'message': 'Las contraseñas no coinciden.'})
|
||||
|
||||
if len(password) > 16:
|
||||
return JsonResponse({'success': False, 'message': 'La contraseña no debe exceder los 16 caracteres.'})
|
||||
|
||||
if email != conf_email or not re.match(r'^[a-zA-Z0-9._%+-]+@gmail\.com$', email):
|
||||
return JsonResponse({'success': False, 'message': 'El correo electrónico no es válido.'})
|
||||
|
||||
# Verificar si el usuario ya existe
|
||||
# Verificar si ya existe una cuenta Battle.net con ese email
|
||||
email_norm = bnet.normalize_email(email)
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute("SELECT COUNT(*) FROM account WHERE username = %s", [username])
|
||||
cursor.execute("SELECT COUNT(*) FROM battlenet_accounts WHERE email = %s", [email_norm])
|
||||
if cursor.fetchone()[0] > 0:
|
||||
return JsonResponse({'success': False, 'message': 'El nombre de usuario ya está en uso.'})
|
||||
return JsonResponse({'success': False, 'message': 'Ya existe una cuenta con ese correo electrónico.'})
|
||||
|
||||
# Validar y obtener recruiter_id
|
||||
recruiter_id = 0 # Valor por defecto si no se proporciona un reclutador
|
||||
# Comprobar que no haya un registro de activación pendiente para ese email
|
||||
if AccountActivation.objects.filter(email=email, old_email__isnull=True).exists():
|
||||
AccountActivation.objects.filter(email=email, old_email__isnull=True).delete()
|
||||
|
||||
# Validar y obtener recruiter_id (id de cuenta de juego del reclutador)
|
||||
recruiter_id = 0
|
||||
if recruiter:
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute("SELECT id FROM account WHERE username = %s", [recruiter])
|
||||
@@ -343,24 +384,13 @@ def register_view(request):
|
||||
else:
|
||||
return JsonResponse({'success': False, 'message': 'El reclutador ingresado no existe.'})
|
||||
|
||||
# Generar salt y verifier
|
||||
salt = binascii.hexlify(os.urandom(32)).decode('utf-8').upper()
|
||||
verifier = calculate_srp6_verifier(username, password, salt)
|
||||
|
||||
# Convertir `salt` y `verifier` a bytes antes de guardarlos en la base de datos
|
||||
salt_bytes = binascii.unhexlify(salt)
|
||||
verifier_bytes = binascii.unhexlify(verifier)
|
||||
|
||||
# Generar un hash único para activación
|
||||
# Generar un hash único para activación. Los salt/verifier se calculan al
|
||||
# activar (tanto el de bnet como el de la cuenta de juego).
|
||||
activation_hash = get_random_string(32)
|
||||
|
||||
# Guardar la información en la tabla `AccountActivation`
|
||||
AccountActivation.objects.create(
|
||||
username=username,
|
||||
email=email,
|
||||
password=password,
|
||||
salt=salt_bytes,
|
||||
verifier=verifier_bytes,
|
||||
recruiter_id=recruiter_id,
|
||||
hash=activation_hash
|
||||
)
|
||||
@@ -368,57 +398,82 @@ def register_view(request):
|
||||
# Enviar correo de activación
|
||||
activation_link = f"{settings.URL_PRINCIPAL}/es/activate-account?act={activation_hash}"
|
||||
context = {
|
||||
'username': username,
|
||||
'username': email,
|
||||
'password': password,
|
||||
'activation_link': activation_link,
|
||||
'NOMBRE_SERVIDOR': settings.NOMBRE_SERVIDOR
|
||||
}
|
||||
enviar_correo(
|
||||
subject=f'Activación de la cuenta {username} - {settings.NOMBRE_SERVIDOR}',
|
||||
subject=f'Activación de la cuenta {email} - {settings.NOMBRE_SERVIDOR}',
|
||||
to_email=email,
|
||||
template='emails/activation.html',
|
||||
context=context
|
||||
)
|
||||
|
||||
# Preparar el mensaje de respuesta
|
||||
message = f"""
|
||||
<div class="alert-message" id="create-response" style="display: block;">
|
||||
<span class="ok-form-response">La cuenta '{username}' ha sido creada.</span><br><br>
|
||||
<span class="ok-form-response">La cuenta '{email}' ha sido creada.</span><br><br>
|
||||
<span>Se ha enviado un enlace de activación al correo {email}.</span>
|
||||
</div>
|
||||
"""
|
||||
return JsonResponse({'success': True, 'message': message})
|
||||
|
||||
return render(request, 'auth/register.html')
|
||||
|
||||
|
||||
|
||||
|
||||
def activate_account_view(request):
|
||||
activation_hash = request.GET.get('act')
|
||||
|
||||
try:
|
||||
activation = AccountActivation.objects.get(hash=activation_hash)
|
||||
|
||||
|
||||
if activation.is_expired():
|
||||
return render(request, 'auth/activation_invalid.html')
|
||||
|
||||
# Insertar la cuenta en `acore_auth`
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute("""
|
||||
INSERT INTO account (username, salt, verifier, email, reg_mail, recruiter, joindate, last_ip)
|
||||
VALUES (%s, %s, %s, %s, %s, %s, NOW(), %s)
|
||||
""", [
|
||||
activation.username, activation.salt, activation.verifier,
|
||||
activation.email, activation.email, activation.recruiter_id,
|
||||
request.META.get('REMOTE_ADDR')
|
||||
])
|
||||
|
||||
# Eliminar el registro de activación
|
||||
activation.delete()
|
||||
email_norm = bnet.normalize_email(activation.email)
|
||||
password = activation.password
|
||||
last_ip = request.META.get('REMOTE_ADDR')
|
||||
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
# Evitar duplicados si el enlace se usa dos veces
|
||||
cursor.execute("SELECT id FROM battlenet_accounts WHERE email = %s", [email_norm])
|
||||
existing = cursor.fetchone()
|
||||
if existing:
|
||||
activation.delete()
|
||||
return render(request, 'auth/activation_success.html')
|
||||
|
||||
# 1) Crear la cuenta Battle.net (SRP6 v2)
|
||||
bnet_salt, bnet_verifier, srp_version = bnet.bnet_make_registration(email_norm, password)
|
||||
cursor.execute(
|
||||
"INSERT INTO battlenet_accounts (email, srp_version, salt, verifier) "
|
||||
"VALUES (%s, %s, %s, %s)",
|
||||
[email_norm, srp_version, bnet_salt, bnet_verifier]
|
||||
)
|
||||
|
||||
# 2) Recuperar el id de la cuenta bnet recién creada
|
||||
cursor.execute("SELECT id FROM battlenet_accounts WHERE email = %s", [email_norm])
|
||||
bnet_id = cursor.fetchone()[0]
|
||||
|
||||
# 3) Crear la cuenta de juego enlazada (<bnetId>#1, SRP6 Grunt)
|
||||
game_username = bnet.make_game_account_username(bnet_id, 1)
|
||||
game_salt, game_verifier = bnet.game_make_registration(game_username, password)
|
||||
cursor.execute(
|
||||
"INSERT INTO account "
|
||||
"(username, salt, verifier, email, reg_mail, recruiter, joindate, "
|
||||
" last_ip, expansion, battlenet_account, battlenet_index) "
|
||||
"VALUES (%s, %s, %s, %s, %s, %s, NOW(), %s, %s, %s, %s)",
|
||||
[
|
||||
game_username, game_salt, game_verifier,
|
||||
email_norm, email_norm, activation.recruiter_id or 0,
|
||||
last_ip, 2, bnet_id, 1
|
||||
]
|
||||
)
|
||||
|
||||
activation.delete()
|
||||
return render(request, 'auth/activation_success.html')
|
||||
|
||||
except AccountActivation.DoesNotExist:
|
||||
return render(request, 'auth/activation_invalid.html')
|
||||
return render(request, 'auth/activation_invalid.html')
|
||||
|
||||
def recover_account_view(request):
|
||||
return render(request, 'auth/recover_account.html')
|
||||
@@ -610,11 +665,14 @@ def get_recruited_friends_at_level_80(account_id, required_count):
|
||||
|
||||
|
||||
def my_account(request):
|
||||
# Verificar si la sesión contiene el usuario
|
||||
# Verificar si la sesión contiene la cuenta de juego seleccionada
|
||||
username = request.session.get('username')
|
||||
|
||||
# Si la sesión no tiene el usuario, redirigir al inicio de sesión
|
||||
|
||||
# Si aún no se ha elegido cuenta de juego pero hay login Battle.net,
|
||||
# enviar al selector; si no, al inicio de sesión.
|
||||
if not username:
|
||||
if request.session.get('bnet_id'):
|
||||
return redirect('select-account')
|
||||
return redirect('login')
|
||||
|
||||
is_logged_in = True # Si el usuario está en la sesión, asumimos que está conectado
|
||||
@@ -868,27 +926,29 @@ def change_password_view(request):
|
||||
if existing_token.token != security_token:
|
||||
return JsonResponse({'success': False, 'message': '<span class="red-form-response">El token ingresado es incorrecto.</span>'})
|
||||
|
||||
# Verificar la contraseña actual usando la función `authenticate`
|
||||
if not authenticate(username, current_password):
|
||||
# Verificar la contraseña actual contra la cuenta Battle.net (por email)
|
||||
if not authenticate(email, current_password):
|
||||
return JsonResponse({'success': False, 'message': '<span class="red-form-response">La contraseña actual es incorrecta.</span>'})
|
||||
|
||||
# Generar salt y verifier para la nueva contraseña
|
||||
new_salt = binascii.hexlify(os.urandom(32)).decode('utf-8').upper()
|
||||
new_verifier = calculate_srp6_verifier(username, new_password, new_salt)
|
||||
# Generar salt y verifier SRP6 v2 para la nueva contraseña (bnet)
|
||||
new_salt_bytes, new_verifier_bytes, srp_version = bnet.bnet_make_registration(email, new_password)
|
||||
|
||||
# Convertir `salt` y `verifier` a bytes antes de guardarlos en la base de datos
|
||||
new_salt_bytes = binascii.unhexlify(new_salt)
|
||||
new_verifier_bytes = binascii.unhexlify(new_verifier)
|
||||
|
||||
# Actualizar la contraseña en la base de datos
|
||||
# Localizar la cuenta bnet (por sesión o por email) y actualizarla
|
||||
bnet_id = request.session.get('bnet_id')
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute("""
|
||||
UPDATE account SET salt = %s, verifier = %s WHERE username = %s
|
||||
""", [new_salt_bytes, new_verifier_bytes, username])
|
||||
if not bnet_id:
|
||||
account = bnet.get_bnet_account_by_email(cursor, email)
|
||||
bnet_id = account['id'] if account else None
|
||||
if not bnet_id:
|
||||
return JsonResponse({'success': False, 'message': '<span class="red-form-response">No se ha encontrado la cuenta.</span>'})
|
||||
cursor.execute(
|
||||
"UPDATE battlenet_accounts SET srp_version = %s, salt = %s, verifier = %s WHERE id = %s",
|
||||
[srp_version, new_salt_bytes, new_verifier_bytes, bnet_id]
|
||||
)
|
||||
|
||||
# Cerrar la sesión por seguridad
|
||||
if 'username' in request.session:
|
||||
del request.session['username']
|
||||
for key in ('username', 'account_id', 'bnet_id', 'bnet_email'):
|
||||
request.session.pop(key, None)
|
||||
|
||||
# Redirigir al usuario a la página de inicio de sesión
|
||||
return JsonResponse({
|
||||
@@ -1051,21 +1111,22 @@ def change_email_view(request):
|
||||
if not security_token or security_token.token != token:
|
||||
return JsonResponse({'success': False, 'message': '<span class="red-form-response">Token de seguridad incorrecto.</span>'})
|
||||
|
||||
if not authenticate(username, current_password):
|
||||
# Verificar la contraseña contra la cuenta Battle.net (por email actual)
|
||||
if not authenticate(current_email, current_password):
|
||||
return JsonResponse({'success': False, 'message': '<span class="red-form-response">Contraseña incorrecta.</span>'})
|
||||
|
||||
# Generar hashes
|
||||
old_email_hash = secrets.token_urlsafe(16)
|
||||
new_email_hash = secrets.token_urlsafe(16)
|
||||
|
||||
# Guardar en `AccountActivation`
|
||||
# Guardar en `AccountActivation`. Se conserva la contraseña porque al
|
||||
# cambiar el email hay que recalcular el verifier de bnet (el usuario SRP
|
||||
# depende del email).
|
||||
AccountActivation.objects.create(
|
||||
username=username,
|
||||
email=new_email,
|
||||
old_email=current_email,
|
||||
password='',
|
||||
salt=b'',
|
||||
verifier=b'',
|
||||
password=current_password,
|
||||
recruiter_id=user_id,
|
||||
hash=new_email_hash,
|
||||
old_email_hash=old_email_hash
|
||||
@@ -1136,13 +1197,33 @@ def confirm_new_email_view(request):
|
||||
activation.is_new_email_used = True
|
||||
activation.save()
|
||||
|
||||
# Actualizar el correo en la base de datos
|
||||
# Cambiar el email en la cuenta Battle.net implica recalcular salt/verifier,
|
||||
# porque el usuario SRP = SHA256(UPPER(email)).
|
||||
new_email_norm = bnet.normalize_email(activation.email)
|
||||
old_email_norm = bnet.normalize_email(activation.old_email or '')
|
||||
new_salt, new_verifier, srp_version = bnet.bnet_make_registration(new_email_norm, activation.password)
|
||||
|
||||
with connections['acore_auth'].cursor() as cursor:
|
||||
cursor.execute("""
|
||||
UPDATE account
|
||||
SET email = %s, reg_mail = %s
|
||||
WHERE username = %s
|
||||
""", [activation.email, activation.email, activation.username])
|
||||
# Localizar la cuenta bnet por su email actual (el antiguo)
|
||||
cursor.execute("SELECT id FROM battlenet_accounts WHERE email = %s", [old_email_norm])
|
||||
row = cursor.fetchone()
|
||||
if not row:
|
||||
return JsonResponse({
|
||||
'success': False,
|
||||
'message': '<span class="red-form-response">No se ha encontrado la cuenta Battle.net.</span>',
|
||||
})
|
||||
bnet_id = row[0]
|
||||
|
||||
# Actualizar email + verifier en battlenet_accounts
|
||||
cursor.execute(
|
||||
"UPDATE battlenet_accounts SET email = %s, srp_version = %s, salt = %s, verifier = %s WHERE id = %s",
|
||||
[new_email_norm, srp_version, new_salt, new_verifier, bnet_id]
|
||||
)
|
||||
# Actualizar el email de las cuentas de juego enlazadas (cosmético)
|
||||
cursor.execute(
|
||||
"UPDATE account SET email = %s, reg_mail = %s WHERE battlenet_account = %s",
|
||||
[new_email_norm, new_email_norm, bnet_id]
|
||||
)
|
||||
|
||||
# Enviar notificación al correo anterior
|
||||
context_old_email = {
|
||||
@@ -2390,9 +2471,9 @@ def rename_guild_view(request):
|
||||
|
||||
if not old_guild_name or not new_guild_name or not conf_new_guild_name or not current_password or not token:
|
||||
return JsonResponse({'success': False, 'message': '<span class="red-form-response">Por favor, completa todos los campos.</span>'})
|
||||
|
||||
if not authenticate(username, current_password):
|
||||
return JsonResponse({'success': False, 'message': '<span class="red-form-response">La contraseña actual es incorrecta.</span>'})
|
||||
|
||||
if not authenticate(email, current_password):
|
||||
return JsonResponse({'success': False, 'message': '<span class="red-form-response">La contraseña actual es incorrecta.</span>'})
|
||||
|
||||
if not security_token or security_token.token != token:
|
||||
return JsonResponse({'success': False, 'message': '<span class="red-form-response">Token de seguridad incorrecto.</span>'})
|
||||
|
||||
Reference in New Issue
Block a user