Resolve "Sve tabele i grafove u projektu staviti da budu 5 sa 5" #70
@@ -4,56 +4,48 @@ from backend.core.utils import calculate_aggregate_likelihood, calculate_aggrega
|
||||
|
||||
def risk_matrix_table():
|
||||
likelihood_labels = [
|
||||
"Certain (90-100%)",
|
||||
"Almost Certain (80-89%)",
|
||||
"Very Probable (70-79%)",
|
||||
"Probable (60-69%)",
|
||||
"Highly Likely (50-59%)",
|
||||
"Likely (40-49%)",
|
||||
"Occasional (30-39%)",
|
||||
"Possible (20-29%)",
|
||||
"Unlikely (10-19%)",
|
||||
"Rare (0-9%)"
|
||||
"Almost Certain (90-100%) (5)",
|
||||
"Probable (51-89%) (4)",
|
||||
"Possible (25-50%) (3)",
|
||||
"Unlikely (11-24%) (2)",
|
||||
"Rare (0-10%) (1)"
|
||||
]
|
||||
|
||||
impact_labels = [
|
||||
"Insignificant",
|
||||
"Minor",
|
||||
"Moderate",
|
||||
"Major",
|
||||
"Severe",
|
||||
"Catastrophic",
|
||||
"Critical",
|
||||
"Extreme",
|
||||
"Disastrous",
|
||||
"Unrecoverable"
|
||||
"Insignificant (1)",
|
||||
"Significant (2)",
|
||||
"Severe (3)",
|
||||
"Material (4)",
|
||||
"Major (5)"
|
||||
]
|
||||
|
||||
color_mapping = {
|
||||
"Very Low": "green",
|
||||
"Low": "lightgreen",
|
||||
"Very Low": "lightgreen",
|
||||
"Low": "green",
|
||||
"Medium": "yellow",
|
||||
"High": "orange",
|
||||
"Critical": "red"
|
||||
}
|
||||
|
||||
table_matrix_risk = [["Impact ↓ / Likelihood →"] + impact_labels]
|
||||
def get_label(score):
|
||||
if score <= 2:
|
||||
return "Very Low"
|
||||
elif score <= 4:
|
||||
return "Low"
|
||||
elif score <= 10:
|
||||
return "Medium"
|
||||
elif score <= 16:
|
||||
return "High"
|
||||
else:
|
||||
return "Critical"
|
||||
|
||||
for likelihood_index, likelihood_label in enumerate(likelihood_labels, start=1):
|
||||
reversed_index = 11 - likelihood_index
|
||||
row = [likelihood_label]
|
||||
for impact_index in range(1, 11):
|
||||
score = reversed_index * impact_index
|
||||
if score <= 20:
|
||||
label = "Very Low"
|
||||
elif score <= 40:
|
||||
label = "Low"
|
||||
elif score <= 60:
|
||||
label = "Medium"
|
||||
elif score <= 80:
|
||||
label = "High"
|
||||
else:
|
||||
label = "Critical"
|
||||
table_matrix_risk = [["Likelihood ↓ / Impact →"] + impact_labels]
|
||||
|
||||
for likelihood in range(5, 0, -1):
|
||||
row = [likelihood_labels[5 - likelihood]]
|
||||
for impact in range(1, 6):
|
||||
score = likelihood * impact
|
||||
label = get_label(score)
|
||||
color_class = color_mapping[label]
|
||||
row.append((score, label, color_class))
|
||||
table_matrix_risk.append(row)
|
||||
@@ -82,7 +74,7 @@ def get_risk_table(document):
|
||||
.values('control', 'control__name', 'weight', 'likelihood')
|
||||
.distinct()
|
||||
)
|
||||
max_weight = 10*10
|
||||
max_weight = 10*5
|
||||
total_weight = calculate_aggregate_weight(controls)
|
||||
total_likelihood = calculate_aggregate_likelihood(controls)
|
||||
impact, likelihood = map_weight_to_impact_likelihood(total_weight, total_likelihood, max_weight)
|
||||
|
||||
@@ -71,7 +71,7 @@ class UtilsTests(TestCase):
|
||||
mock_openai.return_value = mock_client
|
||||
mock_response = MagicMock()
|
||||
|
||||
control_lines = [f"{i} : 8 : 5" for i in range(1, 11)]
|
||||
control_lines = [f"{i} : 4 : 3" for i in range(1, 11)]
|
||||
mock_response.choices[0].message.content = "\n".join(control_lines)
|
||||
mock_client.chat.completions.create.return_value = mock_response
|
||||
|
||||
@@ -100,7 +100,7 @@ class UtilsTests(TestCase):
|
||||
self.assertEqual(calculate_aggregate_likelihood(controls), 6)
|
||||
|
||||
def test_map_weight_to_impact_likelihood(self):
|
||||
impact, likelihood = map_weight_to_impact_likelihood(50, 30, 100)
|
||||
impact, likelihood = map_weight_to_impact_likelihood(50, 30, 50)
|
||||
self.assertAlmostEqual(impact, 5.0)
|
||||
self.assertAlmostEqual(likelihood, 3.0)
|
||||
|
||||
@@ -123,7 +123,7 @@ class UtilsTests(TestCase):
|
||||
def test_generate_risk_graph(self):
|
||||
risks_with_controls = [
|
||||
{'risk': {'id': 1}, 'impact': 5.0, 'likelihood': 3.0},
|
||||
{'risk': {'id': 2}, 'impact': 7.0, 'likelihood': 4.0}
|
||||
{'risk': {'id': 2}, 'impact': 4.0, 'likelihood': 4.0}
|
||||
]
|
||||
|
||||
graph_data = generate_risk_graph(risks_with_controls)
|
||||
|
||||
@@ -90,14 +90,14 @@ def get_controls_for_risk(risk, organization):
|
||||
prompt = f"""
|
||||
You are an expert in cybersecurity risk management. Given the risk "{risk.risk_name}" and its associated organization details "{organization_details}",
|
||||
your task is to select **exactly 10 unique controls** from the provided list that best mitigate this risk. Each control should be assigned:
|
||||
- A weight between **1 and 10** (1 = low impact, 10 = high impact).
|
||||
- A likelihood score between **1 and 10** (1 = rare occurrence, 10 = highly likely).
|
||||
- A weight between **1 and 5** (1 = low impact, 5 = high impact).
|
||||
- A likelihood score between **1 and 5** (1 = rare occurrence, 5 = highly likely).
|
||||
|
||||
### Rules:
|
||||
1. **Each control ID must be unique** (no duplicates).
|
||||
2. **Only return control IDs, weights, and likelihood scores** in the exact format below.
|
||||
3. **Weights must be between 1 and 10** (1 = low impact, 10 = high impact).
|
||||
4. **Likelihood scores must be between 1 and 10** (1 = rare occurrence, 10 = highly likely).
|
||||
3. **Weights must be between 1 and 5** (1 = low impact, 5 = high impact).
|
||||
4. **Likelihood scores must be between 1 and 5** (1 = rare occurrence, 5 = highly likely).
|
||||
5. **Do NOT add explanations, descriptions, or extra text.**
|
||||
6. **Ensure that control IDs are randomly distributed and diverse across different categories.**
|
||||
### Available Controls:
|
||||
@@ -108,8 +108,8 @@ def get_controls_for_risk(risk, organization):
|
||||
<control_id> : <weight> : <likelihood>
|
||||
|
||||
### Example Correct Response (NO DUPLICATES):
|
||||
12 : 8 : 90
|
||||
45 : 7 : 60
|
||||
12 : 5 : 2
|
||||
45 : 4 : 1
|
||||
|
||||
⚠️ **If you provide duplicate control IDs, your response will be rejected. Ensure all control IDs are unique.**
|
||||
⚠️ **Follow the response format exactly. Any deviation will be considered invalid.**
|
||||
@@ -138,7 +138,7 @@ def get_controls_for_risk(risk, organization):
|
||||
weight = int(weight_str)
|
||||
likelihood = int(likelihood_str)
|
||||
|
||||
if control_id in valid_control_ids and 1 <= weight <= 10 and 1 <= likelihood <= 10 and control_id not in control_ids_seen:
|
||||
if control_id in valid_control_ids and 1 <= weight <= 5 and 1 <= likelihood <= 5 and control_id not in control_ids_seen:
|
||||
selected_controls.append((control_id, weight, likelihood))
|
||||
control_ids_seen.add(control_id)
|
||||
except ValueError:
|
||||
@@ -155,14 +155,14 @@ def get_controls_for_risk(risk, organization):
|
||||
retry_prompt = f"""
|
||||
You are an expert in cybersecurity risk management. Given the risk "{risk.risk_name}" and the organization's details "{organization_details}",
|
||||
your task is to select **exactly {missing_count} unique controls** from the provided list that best mitigate this risk. Each control should be assigned:
|
||||
- A **weight** between **1 and 10** based on its effectiveness in reducing the risk.
|
||||
- A likelihood score between **1 and 10** (1 = rare occurrence, 10 = highly likely).
|
||||
- A **weight** between **1 and 5** based on its effectiveness in reducing the risk.
|
||||
- A likelihood score between **1 and 5** (1 = rare occurrence, 5 = highly likely).
|
||||
|
||||
### Rules:
|
||||
1. **Each control ID must be unique** (no duplicates).
|
||||
2. **Only return control IDs, weights, and likelihood scores** in the exact format below.
|
||||
3. **Weights must be between 1 and 10** (1 = low impact, 10 = high impact).
|
||||
4. **Likelihood scores must be between 1 and 10** (1 = rare occurrence, 10 = highly likely).
|
||||
3. **Weights must be between 1 and 5** (1 = low impact, 5 = high impact).
|
||||
4. **Likelihood scores must be between 1 and 5** (1 = rare occurrence, 5 = highly likely).
|
||||
5. **Do NOT add explanations, descriptions, or extra text.**
|
||||
6. **Ensure that control IDs are diverse and well-distributed across different categories.**
|
||||
|
||||
@@ -174,8 +174,8 @@ def get_controls_for_risk(risk, organization):
|
||||
<control_id> : <weight> : <likelihood>
|
||||
|
||||
### Example Correct Response (NO DUPLICATES):
|
||||
12 : 8 : 85
|
||||
45 : 7 : 60
|
||||
12 : 4 : 5
|
||||
45 : 5 : 3
|
||||
|
||||
⚠️ **If you provide duplicate control IDs, your response will be rejected. Ensure all control IDs are unique.**
|
||||
⚠️ **Follow the response format exactly. Any deviation will be considered invalid.**
|
||||
@@ -201,7 +201,7 @@ def get_controls_for_risk(risk, organization):
|
||||
weight = int(weight_str)
|
||||
likelihood = int(likelihood_str)
|
||||
|
||||
if control_id in valid_control_ids and 1 <= weight <= 10 and 1 <= likelihood <= 10 and control_id not in control_ids_seen:
|
||||
if control_id in valid_control_ids and 1 <= weight <= 5 and 1 <= likelihood <= 5 and control_id not in control_ids_seen:
|
||||
selected_controls.append((control_id, weight, likelihood))
|
||||
control_ids_seen.add(control_id)
|
||||
except ValueError:
|
||||
@@ -243,10 +243,8 @@ def calculate_aggregate_likelihood(controls):
|
||||
return total_likelihood
|
||||
|
||||
def map_weight_to_impact_likelihood(total_weight, total_likelihood, max_weight):
|
||||
normalized_weight = total_weight / max_weight
|
||||
|
||||
impact = min(10.0, max(1.0, normalized_weight * 10.0))
|
||||
likelihood = min(10.0, max(1.0, total_likelihood / 10.0))
|
||||
impact = min(5.0, max(1.0, total_weight / 10.0))
|
||||
likelihood = min(5.0, max(1.0, total_likelihood / 10.0))
|
||||
|
||||
return impact, likelihood
|
||||
|
||||
@@ -256,12 +254,12 @@ def generate_risk_graph(risks_with_controls):
|
||||
likelihoods = [risk['likelihood'] for risk in risks_with_controls]
|
||||
risk_ids = [risk['risk']['id'] for risk in risks_with_controls]
|
||||
|
||||
bg_img_path = find('img/graph_matrix (3).png')
|
||||
bg_img_path = find('img/graph_matrix.png')
|
||||
bg_img = mpimg.imread(bg_img_path)
|
||||
|
||||
fig, ax = plt.subplots(figsize=(10, 8))
|
||||
|
||||
ax.imshow(bg_img, extent=[0, 11.2, 0, 11.2], aspect='auto')
|
||||
ax.imshow(bg_img, extent=[0.0, 5.4, 0.0, 5.4], aspect='auto')
|
||||
|
||||
scatter = ax.scatter(
|
||||
likelihoods, impacts,
|
||||
|
||||
@@ -38,6 +38,7 @@ DEBUG = config('DEBUG', default=False, cast=bool)
|
||||
ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[], cast=Csv())
|
||||
|
||||
SITE_DOMAIN = "http://64.226.105.114"
|
||||
#SITE_DOMAIN = "http://127.0.0.1:8000"
|
||||
|
||||
# Application definition
|
||||
|
||||
|
||||
@@ -148,26 +148,26 @@
|
||||
Impact is aslo defined with the following table:
|
||||
headers: ["Level", "Financial Cost", "Reputational Impact", "Management Effort", "Operational Resources", "RPO", "RTO"]
|
||||
rows:
|
||||
- ["Insignificant (1-2)", "< 0.05% Material", "Normal", "Normal", "Normal", "16 hr", "64 hr"]
|
||||
- ["Significant (3-4)", "> 0.5% Material", "Minor", "Minor", "Minor", "8 hr", "32 hr"]
|
||||
- ["Severe (5-6)", "> 10% Material", "Moderate", "Moderate", "Moderate", "4 hr", "16 hr"]
|
||||
- ["Material (7-8)", "> 50% Material", "Critical", "Critical", "Critical", "2 hr", "8 hr"]
|
||||
- ["Major (9-10)", "> Material", "Precarious", "Precarious", "Precarious", "1 hr", "4 hr"]
|
||||
- ["Insignificant (1)", "< 0.05% Material", "Normal", "Normal", "Normal", "16 hr", "64 hr"]
|
||||
- ["Significant (2)", "> 0.5% Material", "Minor", "Minor", "Minor", "8 hr", "32 hr"]
|
||||
- ["Severe (3)", "> 10% Material", "Moderate", "Moderate", "Moderate", "4 hr", "16 hr"]
|
||||
- ["Material (4)", "> 50% Material", "Critical", "Critical", "Critical", "2 hr", "8 hr"]
|
||||
- ["Major (5)", "> Material", "Precarious", "Precarious", "Precarious", "1 hr", "4 hr"]
|
||||
|
||||
- segment_type: "list_stack_sights"
|
||||
content:
|
||||
- description: |
|
||||
For determining likelihood, we use StackSight's commonly referenced scale:
|
||||
- level: 1-2
|
||||
description: "0-3% chance of happening in a year"
|
||||
- level: 3-4
|
||||
description: "4-10% chance of happening in a year"
|
||||
- level: 5-6
|
||||
description: "11-50% chance of happening in a year"
|
||||
- level: 7-8
|
||||
description: "51-90% chance of happening in a year"
|
||||
- level: 9-10
|
||||
description: "91-100% chance of happening in a year"
|
||||
- level: 1
|
||||
description: 1. "0-3% chance of happening in a year"
|
||||
- level: 2
|
||||
description: 2. "4-10% chance of happening in a year"
|
||||
- level: 3
|
||||
description: 3. "11-50% chance of happening in a year"
|
||||
- level: 4
|
||||
description: 4. "51-90% chance of happening in a year"
|
||||
- level: 5
|
||||
description: 5. "91-100% chance of happening in a year"
|
||||
|
||||
- segment_type: "likelihood_table"
|
||||
content:
|
||||
|
||||
Reference in New Issue
Block a user