quantum-ai-v3/authentication/views.py
Claude d36cf9a79d Fix email URLs to use Railway domain instead of localhost
- Add SITE_URL configuration that auto-detects Railway environment
- Update forgot password view to use correct site URL in emails
- Ensure password reset links work on both local and Railway deployments

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-16 13:11:06 +05:30

197 lines
7.1 KiB
Python

from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.contrib.auth.forms import UserCreationForm
from django.http import JsonResponse
from django.core.mail import send_mail
from django.conf import settings
from django.urls import reverse
from .models import User, PasswordResetToken
def login_view(request):
"""User login view"""
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, username=email, password=password)
if user is not None:
login(request, user)
# Redirect to 'next' parameter if provided, otherwise homepage
next_url = request.GET.get('next') or request.POST.get('next')
if next_url:
return redirect(next_url)
return redirect('core:homepage')
else:
messages.error(request, 'Invalid email or password')
return render(request, 'authentication/login.html')
def register_view(request):
"""User registration view"""
if request.method == 'POST':
username = request.POST.get('username')
email = request.POST.get('email')
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
if password1 != password2:
messages.error(request, 'Passwords do not match')
return render(request, 'authentication/register.html')
if User.objects.filter(email=email).exists():
messages.error(request, 'Email already exists')
return render(request, 'authentication/register.html')
try:
user = User.objects.create_user(
username=username,
email=email,
password=password1
)
login(request, user)
messages.success(request, 'Account created successfully!')
return redirect('core:homepage')
except Exception as e:
messages.error(request, 'Error creating account')
return render(request, 'authentication/register.html')
def logout_view(request):
"""User logout view"""
logout(request)
messages.success(request, 'You have been logged out successfully')
return redirect('core:homepage')
@login_required
def profile_view(request):
"""User profile view"""
# Get all transactions first (not sliced)
all_transactions = request.user.wallet_transactions.all()
# Get recent transactions (sliced for display)
transactions = all_transactions[:50]
# Calculate usage statistics using all transactions
total_spent = sum(abs(t.amount) for t in all_transactions if t.type == 'agent_usage')
total_topped_up = sum(t.amount for t in all_transactions if t.type == 'top_up')
total_agents_used = all_transactions.filter(type='agent_usage').count()
# Get most used agents
from django.db.models import Count
popular_agents = (all_transactions.filter(type='agent_usage')
.values('agent_slug')
.annotate(count=Count('agent_slug'))
.order_by('-count')[:5])
# Wallet status
balance = request.user.wallet_balance
if balance < 5:
wallet_status = {'status': 'low', 'color': 'red', 'message': 'Low balance - Add money to continue using agents'}
elif balance < 20:
wallet_status = {'status': 'medium', 'color': 'orange', 'message': 'Consider adding more funds'}
else:
wallet_status = {'status': 'high', 'color': 'green', 'message': 'Good balance'}
context = {
'transactions': transactions,
'total_spent': total_spent,
'total_topped_up': total_topped_up,
'total_agents_used': total_agents_used,
'popular_agents': popular_agents,
'wallet_status': wallet_status,
}
return render(request, 'authentication/profile.html', context)
def forgot_password_view(request):
"""Forgot password view - request password reset"""
if request.method == 'POST':
email = request.POST.get('email')
try:
user = User.objects.get(email=email)
# Create password reset token
reset_token = PasswordResetToken.objects.create(user=user)
# Build reset URL using correct site URL
reset_path = reverse('authentication:reset_password', kwargs={'token': reset_token.token})
reset_url = f"{settings.SITE_URL}{reset_path}"
# Send email
subject = 'Password Reset Request'
message = f'''
Hello {user.username},
You requested a password reset for your NetCop account.
Click the link below to reset your password:
{reset_url}
This link will expire in 1 hour.
If you didn't request this reset, please ignore this email.
Best regards,
NetCop Team
'''
try:
send_mail(
subject,
message,
settings.DEFAULT_FROM_EMAIL,
[email],
fail_silently=False,
)
messages.success(request, 'Password reset instructions have been sent to your email.')
except Exception as e:
messages.error(request, 'Failed to send reset email. Please try again later.')
except User.DoesNotExist:
# Don't reveal if email exists or not for security
messages.success(request, 'If an account with that email exists, password reset instructions have been sent.')
return render(request, 'authentication/forgot_password.html')
def reset_password_view(request, token):
"""Reset password view - using token from email"""
reset_token = get_object_or_404(PasswordResetToken, token=token)
if not reset_token.is_valid():
messages.error(request, 'This password reset link has expired or is invalid.')
return redirect('authentication:forgot_password')
if request.method == 'POST':
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
if password1 != password2:
messages.error(request, 'Passwords do not match.')
return render(request, 'authentication/reset_password.html', {'token': token})
if len(password1) < 8:
messages.error(request, 'Password must be at least 8 characters long.')
return render(request, 'authentication/reset_password.html', {'token': token})
# Reset password
user = reset_token.user
user.set_password(password1)
user.save()
# Mark token as used
reset_token.mark_as_used()
messages.success(request, 'Your password has been reset successfully. You can now log in.')
return redirect('authentication:login')
return render(request, 'authentication/reset_password.html', {'token': token})