Updates
This commit is contained in:
374
ETB-API/security/views/zero_trust.py
Normal file
374
ETB-API/security/views/zero_trust.py
Normal file
@@ -0,0 +1,374 @@
|
||||
"""
|
||||
Zero Trust API Views
|
||||
Provides endpoints for device registration, risk assessment, and Zero Trust management
|
||||
"""
|
||||
import logging
|
||||
from rest_framework import status, generics, permissions
|
||||
from rest_framework.decorators import api_view, permission_classes, action
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
from rest_framework.permissions import IsAuthenticated, IsAdminUser
|
||||
from django.utils import timezone
|
||||
from django.db import models
|
||||
|
||||
from ..models import (
|
||||
DevicePosture, GeolocationRule, RiskAssessment,
|
||||
AdaptiveAuthentication, UserBehaviorProfile
|
||||
)
|
||||
from ..serializers.zero_trust import (
|
||||
DevicePostureSerializer, GeolocationRuleSerializer,
|
||||
RiskAssessmentSerializer, AdaptiveAuthenticationSerializer,
|
||||
UserBehaviorProfileSerializer, DeviceRegistrationSerializer,
|
||||
RiskAssessmentRequestSerializer
|
||||
)
|
||||
from ..services.zero_trust import zero_trust_service
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DevicePostureViewSet(ModelViewSet):
|
||||
"""ViewSet for device posture management"""
|
||||
queryset = DevicePosture.objects.all()
|
||||
serializer_class = DevicePostureSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_queryset(self):
|
||||
"""Users can only see their own devices"""
|
||||
return DevicePosture.objects.filter(user=self.request.user)
|
||||
|
||||
def perform_create(self, serializer):
|
||||
"""Create device posture for current user"""
|
||||
serializer.save(user=self.request.user)
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def update_posture(self, request, pk=None):
|
||||
"""Update device posture information"""
|
||||
device = self.get_object()
|
||||
|
||||
# Update device posture data
|
||||
device_data = request.data
|
||||
for field, value in device_data.items():
|
||||
if hasattr(device, field) and field not in ['id', 'user', 'created_at']:
|
||||
setattr(device, field, value)
|
||||
|
||||
# Recalculate risk score and trust level
|
||||
device.risk_score = device.calculate_risk_score()
|
||||
device.update_trust_level()
|
||||
device.save()
|
||||
|
||||
return Response({
|
||||
'message': 'Device posture updated',
|
||||
'risk_score': device.risk_score,
|
||||
'trust_level': device.trust_level,
|
||||
'is_compliant': device.is_compliant
|
||||
})
|
||||
|
||||
@action(detail=False, methods=['post'])
|
||||
def register_device(self, request):
|
||||
"""Register a new device"""
|
||||
serializer = DeviceRegistrationSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
try:
|
||||
device = zero_trust_service.register_device(
|
||||
request.user,
|
||||
serializer.validated_data
|
||||
)
|
||||
|
||||
return Response({
|
||||
'success': True,
|
||||
'device_id': device.device_id,
|
||||
'trust_level': device.trust_level,
|
||||
'risk_score': device.risk_score,
|
||||
'is_compliant': device.is_compliant,
|
||||
'message': 'Device registered successfully'
|
||||
}, status=status.HTTP_201_CREATED)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Device registration failed: {e}")
|
||||
return Response({
|
||||
'error': 'Device registration failed',
|
||||
'details': str(e)
|
||||
}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
class GeolocationRuleViewSet(ModelViewSet):
|
||||
"""ViewSet for geolocation rule management"""
|
||||
queryset = GeolocationRule.objects.all()
|
||||
serializer_class = GeolocationRuleSerializer
|
||||
permission_classes = [IsAdminUser]
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def test_rule(self, request, pk=None):
|
||||
"""Test geolocation rule against provided location data"""
|
||||
rule = self.get_object()
|
||||
location_data = request.data
|
||||
|
||||
result = rule.evaluate_location(**location_data)
|
||||
|
||||
return Response({
|
||||
'rule_name': rule.name,
|
||||
'rule_type': rule.rule_type,
|
||||
'test_result': result,
|
||||
'location_data': location_data
|
||||
})
|
||||
|
||||
|
||||
class RiskAssessmentViewSet(ModelViewSet):
|
||||
"""ViewSet for risk assessment management"""
|
||||
queryset = RiskAssessment.objects.all()
|
||||
serializer_class = RiskAssessmentSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_queryset(self):
|
||||
"""Users can only see their own risk assessments"""
|
||||
return RiskAssessment.objects.filter(user=self.request.user)
|
||||
|
||||
@action(detail=False, methods=['post'])
|
||||
def assess_access(self, request):
|
||||
"""Perform risk assessment for access request"""
|
||||
serializer = RiskAssessmentRequestSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
try:
|
||||
# Collect request context
|
||||
request_context = {
|
||||
'ip_address': self._get_client_ip(request),
|
||||
'user_agent': request.META.get('HTTP_USER_AGENT', ''),
|
||||
'device_id': request.headers.get('X-Device-ID'),
|
||||
'timestamp': timezone.now(),
|
||||
**serializer.validated_data
|
||||
}
|
||||
|
||||
# Perform assessment
|
||||
assessment_result = zero_trust_service.assess_access_request(
|
||||
request.user,
|
||||
request_context
|
||||
)
|
||||
|
||||
return Response(assessment_result)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Risk assessment failed: {e}")
|
||||
return Response({
|
||||
'error': 'Risk assessment failed',
|
||||
'details': str(e)
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@action(detail=False, methods=['get'])
|
||||
def my_risk_profile(self, request):
|
||||
"""Get user's current risk profile"""
|
||||
try:
|
||||
# Get latest risk assessment
|
||||
latest_assessment = RiskAssessment.objects.filter(
|
||||
user=request.user
|
||||
).order_by('-assessed_at').first()
|
||||
|
||||
# Get behavior profile
|
||||
try:
|
||||
behavior_profile = UserBehaviorProfile.objects.get(user=request.user)
|
||||
except UserBehaviorProfile.DoesNotExist:
|
||||
behavior_profile = None
|
||||
|
||||
# Get device postures
|
||||
devices = DevicePosture.objects.filter(
|
||||
user=request.user,
|
||||
is_active=True
|
||||
).order_by('-last_seen')
|
||||
|
||||
return Response({
|
||||
'latest_assessment': RiskAssessmentSerializer(latest_assessment).data if latest_assessment else None,
|
||||
'behavior_profile': UserBehaviorProfileSerializer(behavior_profile).data if behavior_profile else None,
|
||||
'devices': DevicePostureSerializer(devices, many=True).data,
|
||||
'risk_summary': {
|
||||
'total_devices': devices.count(),
|
||||
'trusted_devices': devices.filter(is_trusted=True).count(),
|
||||
'compliant_devices': devices.filter(is_compliant=True).count(),
|
||||
'average_risk_score': devices.aggregate(avg_risk=models.Avg('risk_score'))['avg_risk'] or 0
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get risk profile: {e}")
|
||||
return Response({
|
||||
'error': 'Failed to get risk profile',
|
||||
'details': str(e)
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
def _get_client_ip(self, request):
|
||||
"""Get client IP address from request"""
|
||||
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||
if x_forwarded_for:
|
||||
ip = x_forwarded_for.split(',')[0].strip()
|
||||
else:
|
||||
ip = request.META.get('REMOTE_ADDR')
|
||||
return ip
|
||||
|
||||
|
||||
class AdaptiveAuthenticationViewSet(ModelViewSet):
|
||||
"""ViewSet for adaptive authentication management"""
|
||||
queryset = AdaptiveAuthentication.objects.all()
|
||||
serializer_class = AdaptiveAuthenticationSerializer
|
||||
permission_classes = [IsAdminUser]
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def test_auth_requirements(self, request, pk=None):
|
||||
"""Test authentication requirements for given risk score"""
|
||||
adaptive_auth = self.get_object()
|
||||
risk_score = request.data.get('risk_score', 0)
|
||||
|
||||
required_methods = adaptive_auth.get_required_auth_methods(risk_score)
|
||||
|
||||
return Response({
|
||||
'risk_score': risk_score,
|
||||
'required_auth_methods': required_methods,
|
||||
'adaptive_auth_name': adaptive_auth.name
|
||||
})
|
||||
|
||||
|
||||
class UserBehaviorProfileViewSet(ModelViewSet):
|
||||
"""ViewSet for user behavior profile management"""
|
||||
queryset = UserBehaviorProfile.objects.all()
|
||||
serializer_class = UserBehaviorProfileSerializer
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_queryset(self):
|
||||
"""Users can only see their own behavior profile"""
|
||||
return UserBehaviorProfile.objects.filter(user=self.request.user)
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def calculate_anomaly(self, request, pk=None):
|
||||
"""Calculate anomaly score for current behavior"""
|
||||
profile = self.get_object()
|
||||
current_behavior = request.data
|
||||
|
||||
anomaly_score = profile.calculate_anomaly_score(current_behavior)
|
||||
|
||||
return Response({
|
||||
'anomaly_score': anomaly_score,
|
||||
'is_anomalous': anomaly_score > 0.7, # Threshold
|
||||
'current_behavior': current_behavior
|
||||
})
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def zero_trust_status(request):
|
||||
"""Get Zero Trust system status and configuration"""
|
||||
try:
|
||||
# Get user's Zero Trust status
|
||||
user_devices = DevicePosture.objects.filter(user=request.user, is_active=True)
|
||||
latest_assessment = RiskAssessment.objects.filter(user=request.user).order_by('-assessed_at').first()
|
||||
|
||||
# Get system configuration
|
||||
adaptive_auth = AdaptiveAuthentication.objects.filter(is_active=True).first()
|
||||
geo_rules = GeolocationRule.objects.filter(is_active=True).count()
|
||||
|
||||
return Response({
|
||||
'zero_trust_enabled': True,
|
||||
'user_status': {
|
||||
'registered_devices': user_devices.count(),
|
||||
'trusted_devices': user_devices.filter(is_trusted=True).count(),
|
||||
'latest_risk_level': latest_assessment.risk_level if latest_assessment else 'UNKNOWN',
|
||||
'latest_risk_score': latest_assessment.overall_risk_score if latest_assessment else 0
|
||||
},
|
||||
'system_configuration': {
|
||||
'adaptive_auth_enabled': adaptive_auth is not None,
|
||||
'geolocation_rules_count': geo_rules,
|
||||
'behavioral_analysis_enabled': True,
|
||||
'device_posture_enabled': True
|
||||
},
|
||||
'recommendations': _get_security_recommendations(request.user, user_devices, latest_assessment)
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to get Zero Trust status: {e}")
|
||||
return Response({
|
||||
'error': 'Failed to get Zero Trust status',
|
||||
'details': str(e)
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def perform_risk_assessment(request):
|
||||
"""Perform a comprehensive risk assessment"""
|
||||
try:
|
||||
# Collect request context
|
||||
request_context = {
|
||||
'ip_address': _get_client_ip(request),
|
||||
'user_agent': request.META.get('HTTP_USER_AGENT', ''),
|
||||
'device_id': request.headers.get('X-Device-ID'),
|
||||
'timestamp': timezone.now(),
|
||||
**request.data
|
||||
}
|
||||
|
||||
# Perform assessment
|
||||
assessment_result = zero_trust_service.assess_access_request(
|
||||
request.user,
|
||||
request_context
|
||||
)
|
||||
|
||||
return Response(assessment_result)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Risk assessment failed: {e}")
|
||||
return Response({
|
||||
'error': 'Risk assessment failed',
|
||||
'details': str(e)
|
||||
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||
|
||||
|
||||
def _get_security_recommendations(user, devices, latest_assessment):
|
||||
"""Get security recommendations based on user's current status"""
|
||||
recommendations = []
|
||||
|
||||
# Device recommendations
|
||||
if devices.count() == 0:
|
||||
recommendations.append({
|
||||
'type': 'device',
|
||||
'priority': 'high',
|
||||
'message': 'Register your device for enhanced security',
|
||||
'action': 'register_device'
|
||||
})
|
||||
|
||||
untrusted_devices = devices.filter(is_trusted=False)
|
||||
if untrusted_devices.exists():
|
||||
recommendations.append({
|
||||
'type': 'device',
|
||||
'priority': 'medium',
|
||||
'message': f'{untrusted_devices.count()} untrusted devices detected',
|
||||
'action': 'improve_device_security'
|
||||
})
|
||||
|
||||
# Risk recommendations
|
||||
if latest_assessment and latest_assessment.risk_level in ['HIGH', 'CRITICAL']:
|
||||
recommendations.append({
|
||||
'type': 'risk',
|
||||
'priority': 'high',
|
||||
'message': f'High risk level detected: {latest_assessment.risk_level}',
|
||||
'action': 'review_security_settings'
|
||||
})
|
||||
|
||||
# MFA recommendations
|
||||
if not user.mfa_enabled:
|
||||
recommendations.append({
|
||||
'type': 'authentication',
|
||||
'priority': 'medium',
|
||||
'message': 'Enable Multi-Factor Authentication',
|
||||
'action': 'enable_mfa'
|
||||
})
|
||||
|
||||
return recommendations
|
||||
|
||||
|
||||
def _get_client_ip(request):
|
||||
"""Get client IP address from request"""
|
||||
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
|
||||
if x_forwarded_for:
|
||||
ip = x_forwarded_for.split(',')[0].strip()
|
||||
else:
|
||||
ip = request.META.get('REMOTE_ADDR')
|
||||
return ip
|
||||
Reference in New Issue
Block a user