Improve acl model

This commit is contained in:
Ultradesu
2025-07-21 12:47:47 +03:00
parent df5493bf14
commit 243a6734fd

View File

@@ -1,6 +1,8 @@
def userPortal(request, user_hash): def userPortal(request, user_hash):
"""HTML portal for user to view their VPN access links and server information""" """HTML portal for user to view their VPN access links and server information"""
from .models import User, ACLLink from .models import User, ACLLink, AccessLog
from django.utils import timezone
from datetime import datetime, timedelta
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -18,15 +20,36 @@ def userPortal(request, user_hash):
try: try:
# Get all ACL links for the user with server information # Get all ACL links for the user with server information
acl_links = ACLLink.objects.filter(acl__user=user).select_related('acl__server', 'acl') acl_links = ACLLink.objects.filter(acl__user=user).select_related('acl__server', 'acl')
logger.info(f"Found {acl_links.count()} ACL links for user {user.username}")
# Calculate date ranges for statistics
now = timezone.now()
thirty_days_ago = now - timedelta(days=30)
logger.debug(f"Calculating stats from {thirty_days_ago} to {now}")
# Calculate total connection statistics
total_connections = AccessLog.objects.filter(
user=user.username,
action='Success'
).count()
recent_connections = AccessLog.objects.filter(
user=user.username,
action='Success',
timestamp__gte=thirty_days_ago
).count()
logger.info(f"User {user.username} stats: total_connections={total_connections}, recent_connections={recent_connections}")
# Group links by server # Group links by server
servers_data = {} servers_data = {}
total_links = 0 total_links = 0
total_connections = 0 # Can be calculated from AccessLog if needed
for link in acl_links: for link in acl_links:
server = link.acl.server server = link.acl.server
server_name = server.name server_name = server.name
logger.debug(f"Processing link {link.link} for server {server_name}")
logger.debug(f"Link last_access_time: {link.last_access_time}")
if server_name not in servers_data: if server_name not in servers_data:
# Get server status and info # Get server status and info
@@ -34,12 +57,20 @@ def userPortal(request, user_hash):
server_status = server.get_server_status() server_status = server.get_server_status()
server_accessible = True server_accessible = True
server_error = None server_error = None
logger.debug(f"Server {server_name} status retrieved successfully")
except Exception as e: except Exception as e:
logger.warning(f"Could not get status for server {server_name}: {e}") logger.warning(f"Could not get status for server {server_name}: {e}")
server_status = {} server_status = {}
server_accessible = False server_accessible = False
server_error = str(e) server_error = str(e)
# Calculate server-specific connection stats
server_total_connections = AccessLog.objects.filter(
user=user.username,
server=server_name,
action='Success'
).count()
servers_data[server_name] = { servers_data[server_name] = {
'server': server, 'server': server,
'status': server_status, 'status': server_status,
@@ -47,32 +78,92 @@ def userPortal(request, user_hash):
'error': server_error, 'error': server_error,
'links': [], 'links': [],
'server_type': server.server_type, 'server_type': server.server_type,
'total_connections': 0, 'total_connections': server_total_connections,
} }
logger.debug(f"Created server data for {server_name} with {server_total_connections} connections")
# Add link information with simple last access from denormalized field # Calculate link-specific statistics
# Note: AccessLog doesn't have link-specific tracking, so we'll use server-based stats
link_connections = AccessLog.objects.filter(
user=user.username,
server=server_name,
action='Success'
).count()
link_recent_connections = AccessLog.objects.filter(
user=user.username,
server=server_name,
action='Success',
timestamp__gte=thirty_days_ago
).count()
# Generate daily usage data for the last 30 days
daily_usage = []
max_daily = 0
for i in range(30):
day_start = (now - timedelta(days=29-i)).replace(hour=0, minute=0, second=0, microsecond=0)
day_end = day_start + timedelta(days=1)
day_connections = AccessLog.objects.filter(
user=user.username,
server=server_name,
action='Success',
timestamp__gte=day_start,
timestamp__lt=day_end
).count()
daily_usage.append(day_connections)
max_daily = max(max_daily, day_connections)
logger.debug(f"Link {link.link} stats: connections={link_connections}, recent={link_recent_connections}, max_daily={max_daily}")
# Add link information with comprehensive statistics
link_url = f"{EXTERNAL_ADDRESS}/ss/{link.link}#{server_name}" link_url = f"{EXTERNAL_ADDRESS}/ss/{link.link}#{server_name}"
servers_data[server_name]['links'].append({ link_data = {
'link': link, 'link': link,
'url': link_url, 'url': link_url,
'comment': link.comment or 'Default', 'comment': link.comment or 'Default',
'last_access': link.last_access_time, 'last_access': link.last_access_time,
}) 'connections': link_connections,
'recent_connections': link_recent_connections,
'daily_usage': daily_usage,
'max_daily': max_daily,
}
servers_data[server_name]['links'].append(link_data)
total_links += 1 total_links += 1
logger.debug(f"Added comprehensive link data for {link.link}")
logger.info(f"Prepared data for {len(servers_data)} servers and {total_links} total links")
logger.info(f"Portal statistics: total_connections={total_connections}, recent_connections={recent_connections}")
context = { context = {
'user': user, 'user': user,
'servers_data': servers_data, 'servers_data': servers_data,
'total_servers': len(servers_data), 'total_servers': len(servers_data),
'total_links': total_links, 'total_links': total_links,
'total_connections': total_connections,
'recent_connections': recent_connections,
'external_address': EXTERNAL_ADDRESS, 'external_address': EXTERNAL_ADDRESS,
} }
logger.debug(f"Context prepared with keys: {list(context.keys())}")
logger.debug(f"Servers in context: {list(servers_data.keys())}")
logger.debug(f"Final context values: total_connections={context['total_connections']}, recent_connections={context['recent_connections']}")
# Log sample server data for debugging
for server_name, server_data in servers_data.items():
logger.debug(f"Server {server_name}: total_connections={server_data['total_connections']}, links_count={len(server_data['links'])}")
for i, link_data in enumerate(server_data['links']):
logger.debug(f" Link {i}: connections={link_data['connections']}, recent={link_data['recent_connections']}, daily_usage_len={len(link_data['daily_usage'])}")
return render(request, 'vpn/user_portal.html', context) return render(request, 'vpn/user_portal.html', context)
except Exception as e: except Exception as e:
logger.error(f"Error loading user portal for {user.username}: {e}") logger.error(f"Error loading user portal for {user.username}: {e}", exc_info=True)
return render(request, 'vpn/user_portal_error.html', { return render(request, 'vpn/user_portal_error.html', {
'error_title': 'Server Error', 'error_title': 'Server Error',
'error_message': 'Unable to load your VPN information. Please try again later or contact support.' 'error_message': 'Unable to load your VPN information. Please try again later or contact support.'