Fixing PLans page
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""
|
||||
Management command to clean up expired and orphaned sessions
|
||||
Helps prevent session contamination and reduces DB bloat
|
||||
"""
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.contrib.sessions.models import Session
|
||||
from django.contrib.auth import get_user_model
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Clean up expired sessions and detect session contamination'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--dry-run',
|
||||
action='store_true',
|
||||
help='Show what would be deleted without actually deleting',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--days',
|
||||
type=int,
|
||||
default=7,
|
||||
help='Delete sessions older than X days (default: 7)',
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
dry_run = options['dry_run']
|
||||
days = options['days']
|
||||
cutoff_date = datetime.now() - timedelta(days=days)
|
||||
|
||||
# Get all sessions
|
||||
all_sessions = Session.objects.all()
|
||||
expired_sessions = Session.objects.filter(expire_date__lt=datetime.now())
|
||||
old_sessions = Session.objects.filter(expire_date__lt=cutoff_date)
|
||||
|
||||
self.stdout.write(f"\n📊 Session Statistics:")
|
||||
self.stdout.write(f" Total sessions: {all_sessions.count()}")
|
||||
self.stdout.write(f" Expired sessions: {expired_sessions.count()}")
|
||||
self.stdout.write(f" Sessions older than {days} days: {old_sessions.count()}")
|
||||
|
||||
# Count sessions by user
|
||||
user_sessions = {}
|
||||
for session in all_sessions:
|
||||
try:
|
||||
data = session.get_decoded()
|
||||
user_id = data.get('_auth_user_id')
|
||||
if user_id:
|
||||
user = User.objects.get(id=user_id)
|
||||
key = f"{user.username} ({user.account.slug if user.account else 'no-account'})"
|
||||
user_sessions[key] = user_sessions.get(key, 0) + 1
|
||||
except:
|
||||
pass
|
||||
|
||||
if user_sessions:
|
||||
self.stdout.write(f"\n📈 Active sessions by user:")
|
||||
for user_key, count in sorted(user_sessions.items(), key=lambda x: x[1], reverse=True)[:10]:
|
||||
indicator = "⚠️ " if count > 20 else " "
|
||||
self.stdout.write(f"{indicator}{user_key}: {count} sessions")
|
||||
|
||||
# Delete expired sessions
|
||||
if expired_sessions.exists():
|
||||
if dry_run:
|
||||
self.stdout.write(self.style.WARNING(f"\n[DRY RUN] Would delete {expired_sessions.count()} expired sessions"))
|
||||
else:
|
||||
count = expired_sessions.delete()[0]
|
||||
self.stdout.write(self.style.SUCCESS(f"\n✓ Deleted {count} expired sessions"))
|
||||
else:
|
||||
self.stdout.write(f"\n✓ No expired sessions to clean")
|
||||
|
||||
# Detect potential contamination
|
||||
warnings = []
|
||||
for user_key, count in user_sessions.items():
|
||||
if count > 50:
|
||||
warnings.append(f"User '{user_key}' has {count} active sessions (potential proliferation)")
|
||||
|
||||
if warnings:
|
||||
self.stdout.write(self.style.WARNING(f"\n⚠️ Contamination Warnings:"))
|
||||
for warning in warnings:
|
||||
self.stdout.write(self.style.WARNING(f" {warning}"))
|
||||
self.stdout.write(f"\n💡 Consider running: python manage.py clearsessions")
|
||||
Reference in New Issue
Block a user