auto-claude: subtask-2-2 - Implement security scoring algorithm (50% weight)

Security scoring implementation with 7 security elements:
- EDR: +15 pts (highest security value)
- MFA: +10 pts (identity security)
- Firewall: +10 pts (network protection)
- Backup: +10 pts (data protection)
- DR Plan: +10 pts (disaster recovery readiness)
- VPN: +5 pts (secure remote access)
- Monitoring: +5 pts (security visibility)

Max raw score: 65 points. Returns raw score directly.
Normalization to 0-100 happens in overall score calculation.

Verification: has_edr + has_mfa returns 25 (15 + 10).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-09 08:30:37 +01:00
parent e929a9e825
commit 5cdd33857f

View File

@ -237,56 +237,55 @@ class ITAuditService:
"""
Calculate security score from audit data.
Security elements and their point values:
- has_edr: +15 pts
- has_mfa: +10 pts
- has_firewall (network_firewall_brand): +10 pts
- has_backup (backup_solution): +10 pts
- has_dr_plan: +10 pts
- has_vpn: +5 pts
- has_monitoring (monitoring_solution): +5 pts
Security elements and their point values (max 65 points):
- has_edr: +15 pts (EDR solution - highest security value)
- has_mfa: +10 pts (Multi-factor authentication)
- has_firewall: +10 pts (Network firewall)
- has_backup: +10 pts (Backup solution)
- has_dr_plan: +10 pts (Disaster recovery plan)
- has_vpn: +5 pts (VPN solution)
- has_monitoring: +5 pts (Monitoring solution)
Max raw: 65 points, normalized to 100
The raw score (0-65) is returned directly. When calculating
the overall score, this is weighted at 50% and normalized.
Args:
audit_data: Dictionary with audit field values
Returns:
Normalized security score (0-100)
Raw security score (0-65)
"""
raw_score = 0
score = 0
# EDR
# EDR - highest security value
if audit_data.get('has_edr'):
raw_score += SECURITY_SCORES['has_edr']
score += SECURITY_SCORES['has_edr']
# MFA
# MFA - critical for identity security
if audit_data.get('has_mfa'):
raw_score += SECURITY_SCORES['has_mfa']
score += SECURITY_SCORES['has_mfa']
# Firewall (check for brand name presence)
# Firewall (check for brand name presence or explicit flag)
if audit_data.get('network_firewall_brand') or audit_data.get('has_firewall'):
raw_score += SECURITY_SCORES['has_firewall']
score += SECURITY_SCORES['has_firewall']
# Backup solution
# Backup solution (check for solution name or explicit flag)
if audit_data.get('backup_solution') or audit_data.get('has_backup'):
raw_score += SECURITY_SCORES['has_backup']
score += SECURITY_SCORES['has_backup']
# DR plan
# DR plan - disaster recovery readiness
if audit_data.get('has_dr_plan'):
raw_score += SECURITY_SCORES['has_dr_plan']
score += SECURITY_SCORES['has_dr_plan']
# VPN
# VPN - secure remote access
if audit_data.get('has_vpn'):
raw_score += SECURITY_SCORES['has_vpn']
score += SECURITY_SCORES['has_vpn']
# Monitoring
# Monitoring (check for solution name or explicit flag)
if audit_data.get('monitoring_solution') or audit_data.get('has_monitoring'):
raw_score += SECURITY_SCORES['has_monitoring']
score += SECURITY_SCORES['has_monitoring']
# Normalize to 0-100
normalized = min(round(raw_score / SECURITY_MAX_RAW * 100), 100)
return normalized
return score
def _calculate_collaboration_score(self, audit_data: dict) -> int:
"""
@ -390,9 +389,9 @@ class ITAuditService:
Calculate all scores from form data.
Overall score formula:
- Security: 50% weight
- Collaboration: 30% weight
- Completeness: 20% weight
- Security: 50% weight (normalized from 0-65 to 0-100)
- Collaboration: 30% weight (already 0-100)
- Completeness: 20% weight (already 0-100)
Args:
audit_data: Dictionary with all form field values
@ -403,13 +402,16 @@ class ITAuditService:
company_id = audit_data.get('company_id', 0)
# Calculate component scores
security_score = self._calculate_security_score(audit_data)
collaboration_score = self._calculate_collaboration_score(audit_data)
completeness_score = self._calculate_completeness_score(audit_data)
security_score = self._calculate_security_score(audit_data) # Returns 0-65
collaboration_score = self._calculate_collaboration_score(audit_data) # Returns 0-100
completeness_score = self._calculate_completeness_score(audit_data) # Returns 0-100
# Normalize security score to 0-100 for overall calculation
security_normalized = (security_score / SECURITY_MAX_RAW) * 100
# Calculate weighted overall score
overall_score = round(
security_score * 0.50 +
security_normalized * 0.50 +
collaboration_score * 0.30 +
completeness_score * 0.20
)