327 lines
12 KiB
Python
327 lines
12 KiB
Python
"""
|
|
Admin configuration for security models
|
|
"""
|
|
from django.contrib import admin
|
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
|
from django.utils.html import format_html
|
|
from django.utils import timezone
|
|
|
|
from .models import (
|
|
DataClassification, Role, User, MFADevice,
|
|
AuditLog, SSOProvider, AccessPolicy, DevicePosture,
|
|
GeolocationRule, RiskAssessment, AdaptiveAuthentication,
|
|
UserBehaviorProfile
|
|
)
|
|
|
|
|
|
@admin.register(DataClassification)
|
|
class DataClassificationAdmin(admin.ModelAdmin):
|
|
list_display = ['name', 'level', 'color_code', 'requires_clearance', 'created_at']
|
|
list_filter = ['requires_clearance', 'created_at']
|
|
search_fields = ['name', 'description']
|
|
ordering = ['level']
|
|
|
|
|
|
@admin.register(Role)
|
|
class RoleAdmin(admin.ModelAdmin):
|
|
list_display = ['name', 'is_active', 'permission_count', 'classification_count', 'created_at']
|
|
list_filter = ['is_active', 'created_at']
|
|
search_fields = ['name', 'description']
|
|
filter_horizontal = ['permissions', 'data_classification_access']
|
|
|
|
def permission_count(self, obj):
|
|
return obj.permissions.count()
|
|
permission_count.short_description = 'Permissions'
|
|
|
|
def classification_count(self, obj):
|
|
return obj.data_classification_access.count()
|
|
classification_count.short_description = 'Classifications'
|
|
|
|
|
|
class MFADeviceInline(admin.TabularInline):
|
|
model = MFADevice
|
|
extra = 0
|
|
readonly_fields = ['secret_key', 'last_used', 'created_at']
|
|
|
|
|
|
@admin.register(User)
|
|
class UserAdmin(BaseUserAdmin):
|
|
list_display = [
|
|
'username', 'email', 'first_name', 'last_name',
|
|
'clearance_level', 'mfa_enabled', 'is_active', 'is_staff'
|
|
]
|
|
list_filter = [
|
|
'is_active', 'is_staff', 'is_superuser', 'mfa_enabled',
|
|
'clearance_level', 'sso_provider', 'created_at'
|
|
]
|
|
search_fields = ['username', 'email', 'first_name', 'last_name', 'employee_id']
|
|
ordering = ['username']
|
|
|
|
fieldsets = BaseUserAdmin.fieldsets + (
|
|
('Security Information', {
|
|
'fields': (
|
|
'employee_id', 'department', 'clearance_level',
|
|
'mfa_enabled', 'mfa_secret', 'last_login_ip',
|
|
'failed_login_attempts', 'account_locked_until'
|
|
)
|
|
}),
|
|
('SSO Information', {
|
|
'fields': ('sso_provider', 'sso_identifier')
|
|
}),
|
|
('Additional Information', {
|
|
'fields': ('attributes', 'created_at', 'updated_at')
|
|
}),
|
|
)
|
|
|
|
readonly_fields = ['mfa_secret', 'last_login_ip', 'failed_login_attempts',
|
|
'account_locked_until', 'created_at', 'updated_at']
|
|
|
|
filter_horizontal = ['roles']
|
|
inlines = [MFADeviceInline]
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('clearance_level')
|
|
|
|
|
|
@admin.register(MFADevice)
|
|
class MFADeviceAdmin(admin.ModelAdmin):
|
|
list_display = ['user', 'name', 'device_type', 'is_active', 'is_primary', 'last_used']
|
|
list_filter = ['device_type', 'is_active', 'is_primary', 'created_at']
|
|
search_fields = ['user__username', 'name']
|
|
readonly_fields = ['secret_key', 'created_at', 'updated_at']
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('user')
|
|
|
|
|
|
@admin.register(AuditLog)
|
|
class AuditLogAdmin(admin.ModelAdmin):
|
|
list_display = [
|
|
'timestamp', 'user', 'action_type', 'resource_type',
|
|
'severity', 'ip_address'
|
|
]
|
|
list_filter = [
|
|
'action_type', 'severity', 'timestamp', 'user'
|
|
]
|
|
search_fields = [
|
|
'user__username', 'action_type', 'resource_type',
|
|
'resource_id', 'ip_address'
|
|
]
|
|
readonly_fields = [
|
|
'id', 'timestamp', 'hash_value'
|
|
]
|
|
date_hierarchy = 'timestamp'
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('user')
|
|
|
|
def has_add_permission(self, request):
|
|
return False # Audit logs should not be manually created
|
|
|
|
def has_change_permission(self, request, obj=None):
|
|
return False # Audit logs should be immutable
|
|
|
|
def has_delete_permission(self, request, obj=None):
|
|
return False # Audit logs should not be deleted
|
|
|
|
|
|
@admin.register(SSOProvider)
|
|
class SSOProviderAdmin(admin.ModelAdmin):
|
|
list_display = ['name', 'provider_type', 'is_active', 'created_at']
|
|
list_filter = ['provider_type', 'is_active', 'created_at']
|
|
search_fields = ['name']
|
|
readonly_fields = ['created_at', 'updated_at']
|
|
|
|
|
|
@admin.register(AccessPolicy)
|
|
class AccessPolicyAdmin(admin.ModelAdmin):
|
|
list_display = [
|
|
'name', 'policy_type', 'priority', 'requires_device_trust',
|
|
'requires_geolocation_check', 'is_active', 'created_at'
|
|
]
|
|
list_filter = [
|
|
'policy_type', 'requires_device_trust', 'requires_geolocation_check',
|
|
'is_active', 'created_at'
|
|
]
|
|
search_fields = ['name', 'description']
|
|
readonly_fields = ['created_at', 'updated_at']
|
|
ordering = ['priority', 'name']
|
|
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('name', 'description', 'policy_type', 'priority', 'is_active')
|
|
}),
|
|
('Zero Trust Settings', {
|
|
'fields': ('requires_device_trust', 'min_device_trust_level', 'requires_geolocation_check', 'geolocation_rule')
|
|
}),
|
|
('Risk & Compliance', {
|
|
'fields': ('max_risk_score', 'requires_compliant_device')
|
|
}),
|
|
('Adaptive Authentication', {
|
|
'fields': ('adaptive_auth_enabled', 'auth_factors_required')
|
|
}),
|
|
('Conditions & Actions', {
|
|
'fields': ('conditions', 'resource_type', 'actions', 'time_restrictions')
|
|
})
|
|
)
|
|
|
|
|
|
@admin.register(DevicePosture)
|
|
class DevicePostureAdmin(admin.ModelAdmin):
|
|
list_display = ['device_name', 'user', 'device_type', 'os_type', 'trust_level', 'risk_score', 'is_compliant', 'last_seen']
|
|
list_filter = ['device_type', 'os_type', 'trust_level', 'is_compliant', 'is_managed', 'is_active', 'last_seen']
|
|
search_fields = ['device_name', 'device_id', 'user__username', 'user__email']
|
|
readonly_fields = ['device_id', 'risk_score', 'trust_level', 'first_seen', 'last_seen']
|
|
ordering = ['-last_seen']
|
|
|
|
fieldsets = (
|
|
('Device Information', {
|
|
'fields': ('user', 'device_id', 'device_name', 'device_type', 'os_type', 'os_version', 'browser_info')
|
|
}),
|
|
('Security Posture', {
|
|
'fields': ('is_managed', 'has_antivirus', 'antivirus_status', 'firewall_enabled', 'encryption_enabled', 'screen_lock_enabled', 'biometric_auth')
|
|
}),
|
|
('Network Information', {
|
|
'fields': ('ip_address', 'mac_address', 'network_type', 'vpn_connected')
|
|
}),
|
|
('Risk Assessment', {
|
|
'fields': ('risk_score', 'trust_level', 'is_trusted', 'is_compliant', 'compliance_issues', 'assessment_details')
|
|
}),
|
|
('Status & Timestamps', {
|
|
'fields': ('is_active', 'first_seen', 'last_seen')
|
|
})
|
|
)
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('user')
|
|
|
|
|
|
@admin.register(GeolocationRule)
|
|
class GeolocationRuleAdmin(admin.ModelAdmin):
|
|
list_display = ['name', 'rule_type', 'priority', 'is_active', 'created_at']
|
|
list_filter = ['rule_type', 'is_active', 'created_at']
|
|
search_fields = ['name', 'description']
|
|
ordering = ['priority', 'name']
|
|
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('name', 'description', 'rule_type', 'priority', 'is_active')
|
|
}),
|
|
('Geographic Conditions', {
|
|
'fields': ('allowed_countries', 'blocked_countries', 'allowed_regions', 'blocked_regions', 'allowed_cities', 'blocked_cities')
|
|
}),
|
|
('IP-based Rules', {
|
|
'fields': ('allowed_ip_ranges', 'blocked_ip_ranges')
|
|
}),
|
|
('Time-based Conditions', {
|
|
'fields': ('allowed_time_zones', 'working_hours_only', 'working_hours_start', 'working_hours_end', 'working_days')
|
|
}),
|
|
('Distance Rules', {
|
|
'fields': ('max_distance_from_office', 'office_latitude', 'office_longitude')
|
|
}),
|
|
('Actions & Notifications', {
|
|
'fields': ('notification_message', 'log_violation', 'require_manager_approval')
|
|
})
|
|
)
|
|
|
|
|
|
@admin.register(RiskAssessment)
|
|
class RiskAssessmentAdmin(admin.ModelAdmin):
|
|
list_display = ['user', 'assessment_type', 'risk_level', 'overall_risk_score', 'access_decision', 'assessed_at']
|
|
list_filter = ['assessment_type', 'risk_level', 'access_decision', 'assessed_at']
|
|
search_fields = ['user__username', 'user__email', 'resource_type', 'resource_id']
|
|
readonly_fields = ['assessed_at', 'overall_risk_score', 'risk_level', 'access_decision']
|
|
ordering = ['-assessed_at']
|
|
|
|
fieldsets = (
|
|
('Assessment Context', {
|
|
'fields': ('user', 'assessment_type', 'resource_type', 'resource_id')
|
|
}),
|
|
('Risk Scores', {
|
|
'fields': ('device_risk_score', 'location_risk_score', 'behavior_risk_score', 'network_risk_score', 'time_risk_score', 'user_risk_score')
|
|
}),
|
|
('Overall Assessment', {
|
|
'fields': ('overall_risk_score', 'risk_level', 'access_decision', 'decision_reason')
|
|
}),
|
|
('Context Data', {
|
|
'fields': ('ip_address', 'user_agent', 'location_data', 'device_data', 'behavior_data')
|
|
}),
|
|
('Assessment Details', {
|
|
'fields': ('risk_factors', 'mitigation_actions', 'assessment_details')
|
|
}),
|
|
('Timestamps', {
|
|
'fields': ('assessed_at', 'expires_at')
|
|
})
|
|
)
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('user')
|
|
|
|
|
|
@admin.register(AdaptiveAuthentication)
|
|
class AdaptiveAuthenticationAdmin(admin.ModelAdmin):
|
|
list_display = ['name', 'is_active', 'ml_enabled', 'enable_behavioral_analysis', 'created_at']
|
|
list_filter = ['is_active', 'ml_enabled', 'enable_behavioral_analysis', 'created_at']
|
|
search_fields = ['name', 'description']
|
|
ordering = ['name']
|
|
|
|
fieldsets = (
|
|
('Basic Information', {
|
|
'fields': ('name', 'description', 'is_active')
|
|
}),
|
|
('Risk Thresholds', {
|
|
'fields': ('low_risk_threshold', 'medium_risk_threshold', 'high_risk_threshold')
|
|
}),
|
|
('Authentication Methods by Risk Level', {
|
|
'fields': ('low_risk_auth_methods', 'medium_risk_auth_methods', 'high_risk_auth_methods', 'critical_risk_auth_methods')
|
|
}),
|
|
('Context-based Adjustments', {
|
|
'fields': ('device_trust_multiplier', 'location_trust_multiplier', 'time_trust_multiplier')
|
|
}),
|
|
('Behavioral Analysis', {
|
|
'fields': ('enable_behavioral_analysis', 'behavior_learning_period', 'anomaly_threshold')
|
|
}),
|
|
('Machine Learning', {
|
|
'fields': ('ml_enabled', 'ml_model_path', 'ml_confidence_threshold')
|
|
}),
|
|
('Fallback Options', {
|
|
'fields': ('fallback_auth_methods', 'max_auth_attempts', 'lockout_duration')
|
|
})
|
|
)
|
|
|
|
|
|
@admin.register(UserBehaviorProfile)
|
|
class UserBehaviorProfileAdmin(admin.ModelAdmin):
|
|
list_display = ['user', 'is_learning', 'anomaly_score', 'sample_count', 'last_updated']
|
|
list_filter = ['is_learning', 'last_updated']
|
|
search_fields = ['user__username', 'user__email']
|
|
readonly_fields = ['learning_start_date', 'learning_complete_date', 'sample_count', 'last_updated', 'created_at']
|
|
ordering = ['-last_updated']
|
|
|
|
fieldsets = (
|
|
('User Information', {
|
|
'fields': ('user',)
|
|
}),
|
|
('Login Patterns', {
|
|
'fields': ('typical_login_times', 'typical_login_locations', 'typical_login_devices')
|
|
}),
|
|
('Access Patterns', {
|
|
'fields': ('typical_access_times', 'typical_access_patterns', 'typical_session_duration')
|
|
}),
|
|
('Network Patterns', {
|
|
'fields': ('typical_ip_ranges', 'typical_user_agents')
|
|
}),
|
|
('Behavioral Metrics', {
|
|
'fields': ('login_frequency', 'access_frequency', 'anomaly_score')
|
|
}),
|
|
('Learning Status', {
|
|
'fields': ('is_learning', 'learning_start_date', 'learning_complete_date', 'sample_count')
|
|
}),
|
|
('Timestamps', {
|
|
'fields': ('created_at', 'last_updated')
|
|
})
|
|
)
|
|
|
|
def get_queryset(self, request):
|
|
return super().get_queryset(request).select_related('user')
|