mirror of
https://github.com/house-of-vanity/OutFleet.git
synced 2025-08-21 14:37:16 +00:00
Improve acl model
This commit is contained in:
105
vpn/views.py
105
vpn/views.py
@@ -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.'
|
||||||
|
Reference in New Issue
Block a user