diff --git a/backend/ebios_rm/helpers.py b/backend/ebios_rm/helpers.py index 61f57d768f..33cfacd7b1 100644 --- a/backend/ebios_rm/helpers.py +++ b/backend/ebios_rm/helpers.py @@ -1,6 +1,7 @@ from django.db.models.query import QuerySet import math import random +from global_settings.models import GlobalSettings def ecosystem_radar_chart_data(stakeholders_queryset: QuerySet): @@ -35,7 +36,7 @@ def get_reliability_cluster(value): """ // data format: f1-f4 (fiabilité cyber = maturité x confiance ) to get the clusters and colors // x,y, z - // x: criticité calculée avec cap à 5,5 + // x: criticité calculée avec cap basé sur le max finalement // y: the angle (output of dict to make sure they end up on the right quadrant, min: 45, max:-45) -> done on BE // z: the size of item (exposition = dependence x penetration) based on a dict, -> done on BE // label: name of the 3rd party entity @@ -46,6 +47,8 @@ def get_reliability_cluster(value): r_data = {"clst1": [], "clst2": [], "clst3": [], "clst4": []} angle_offset = {"client": 135, "partner": 225, "supplier": 45} + max_val = GlobalSettings.objects.get(name="general").value.get("ebios_radar_max", 6) + for sh in qs: # current c_reliability = sh.current_maturity * sh.current_trust @@ -54,8 +57,8 @@ def get_reliability_cluster(value): c_criticality = ( math.floor(sh.current_criticality * 100) / 100.0 - if sh.current_criticality <= 5 - else 5.25 + if sh.current_criticality <= max_val + else max_val - 1 + 0.25 ) angle = angle_offset[sh.category] + ( @@ -74,8 +77,8 @@ def get_reliability_cluster(value): r_criticality = ( math.floor(sh.residual_criticality * 100) / 100.0 - if sh.residual_criticality <= 5 - else 5.25 + if sh.residual_criticality <= max_val + else max_val - 1 + 0.25 ) angle = angle_offset[sh.category] + ( diff --git a/backend/global_settings/serializers.py b/backend/global_settings/serializers.py index bb68b0f778..71d0d5ed9f 100644 --- a/backend/global_settings/serializers.py +++ b/backend/global_settings/serializers.py @@ -4,6 +4,10 @@ GENERAL_SETTINGS_KEYS = [ "security_objective_scale", + "ebios_radar_max", + "ebios_radar_green_zone_radius", + "ebios_radar_yellow_zone_radius", + "ebios_radar_red_zone_radius", ] diff --git a/backend/global_settings/views.py b/backend/global_settings/views.py index 1f969f0951..17e3929346 100644 --- a/backend/global_settings/views.py +++ b/backend/global_settings/views.py @@ -59,11 +59,23 @@ def get_object(self): @action(detail=True, name="Get write data") def object(self, request, pk=None): - GlobalSettings.objects.get_or_create( - name="general", - defaults={"value": {"security_objective_scale": "1-4"}}, - ) - return Response(GeneralSettingsSerializer(self.get_object()).data.get("value")) + default_settings = { + "security_objective_scale": "1-4", + "ebios_radar_max": 6, + "ebios_radar_green_zone_radius": 0.2, + "ebios_radar_yellow_zone_radius": 0.9, + "ebios_radar_red_zone_radius": 2.5, + } + + settings, created = GlobalSettings.objects.get_or_create(name="general") + + if created or not all(key in settings.value for key in default_settings): + existing_value = settings.value or {} + updated_value = {**default_settings, **existing_value} + settings.value = updated_value + settings.save() + + return Response(GeneralSettingsSerializer(settings).data.get("value")) @action(detail=True, name="Get security objective scales") def security_objective_scale(self, request): @@ -74,6 +86,22 @@ def security_objective_scale(self, request): } return Response(choices) + @action(detail=True, name="Get ebios rm radar parameters") + def ebios_radar_parameters(self, request): + ebios_rm_parameters = { + "ebios_radar_max": self.get_object().value.get("ebios_radar_max"), + "ebios_radar_green_zone_radius": self.get_object().value.get( + "ebios_radar_green_zone_radius" + ), + "ebios_radar_yellow_zone_radius": self.get_object().value.get( + "ebios_radar_yellow_zone_radius" + ), + "ebios_radar_red_zone_radius": self.get_object().value.get( + "ebios_radar_red_zone_radius" + ), + } + return Response(ebios_rm_parameters) + @api_view(["GET"]) @permission_classes([permissions.AllowAny]) diff --git a/frontend/messages/en.json b/frontend/messages/en.json index c19b3389ce..5b044af158 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -1128,5 +1128,10 @@ "missingLibrariesInImport": "Some libraries are missing, see the list above", "yes": "Yes", "no": "No", - "updateAvailable": "Update available" + "updateAvailable": "Update available", + "ebiosRadarParameters": "Ebios RM radar parameters", + "maxRadius": "Max Radius", + "greenZoneRadius": "Green zone radius", + "yellowZoneRadius": "Yellow zone radius", + "redZoneRadius": "Red zone radius" } diff --git a/frontend/messages/fr.json b/frontend/messages/fr.json index a515ce7cdb..d5612a77c5 100644 --- a/frontend/messages/fr.json +++ b/frontend/messages/fr.json @@ -1128,5 +1128,10 @@ "missingLibrariesInImport": "Certaines bibliothèques sont manquantes, voir la liste ci-dessus", "yes": "Oui", "no": "Non", - "updateAvailable": "Mise à jour disponible" + "updateAvailable": "Mise à jour disponible", + "ebiosRadarParameters": "Paramètres du radar Ebios RM", + "maxRadius": "Rayon maximal", + "greenZoneRadius": "Rayon de la zone verte", + "yellowZoneRadius": "Rayon de la zone jaune", + "redZoneRadius": "Rayon de la zone rouge" } diff --git a/frontend/src/lib/components/Chart/EcosystemRadarChart.svelte b/frontend/src/lib/components/Chart/EcosystemRadarChart.svelte index d4e1b3aff3..5f2b19d3db 100644 --- a/frontend/src/lib/components/Chart/EcosystemRadarChart.svelte +++ b/frontend/src/lib/components/Chart/EcosystemRadarChart.svelte @@ -2,6 +2,7 @@ import { onMount } from 'svelte'; import { safeTranslate } from '$lib/utils/i18n'; import * as m from '$paraglide/messages.js'; + import { page } from '$app/stores'; // export let name: string; @@ -12,6 +13,11 @@ export let name = ''; export let data; + export let max = $page.data.settings.ebios_radar_max; + export let greenZoneRadius = $page.data.settings.ebios_radar_green_zone_radius; + export let yellowZoneRadius = $page.data.settings.ebios_radar_yellow_zone_radius; + export let redZoneRadius = $page.data.settings.ebios_radar_red_zone_radius; + // data format: f1-f4 (fiabilité cyber = maturité x confiance ) to get the clusters and colors // x,y, z // x: criticité calculée avec cap à 5,5 @@ -122,7 +128,7 @@ }, radiusAxis: { type: 'value', - max: 6, + max: max, inverse: true, axisLabel: { show: true }, axisLine: { @@ -188,50 +194,48 @@ } }, { - name: 'Circle', + name: 'CircleR', type: 'line', coordinateSystem: 'polar', itemStyle: { borderJoin: 'round' }, symbol: 'none', data: new Array(360).fill(0).map((_, index) => { - return [2.5, index]; + return [redZoneRadius, index]; }), lineStyle: { color: '#E73E51', width: 5 }, - // If you don't want this to show up in the legend: showInLegend: false, silent: true, zlevel: -1 }, { - name: 'Circle', + name: 'CircleY', type: 'line', coordinateSystem: 'polar', symbol: 'none', data: new Array(360).fill(0).map((_, index) => { - return [0.2, index]; + return [yellowZoneRadius, index]; }), lineStyle: { - color: '#00ADA8', + color: '#F8EA47', width: 5 }, - // If you don't want this to show up in the legend: showInLegend: false, silent: true, zlevel: -1 }, { - name: 'Circle', + name: 'CircleG', type: 'line', coordinateSystem: 'polar', symbol: 'none', data: new Array(360).fill(0).map((_, index) => { - return [0.9, index]; + return [greenZoneRadius, index]; }), lineStyle: { - color: '#F8EA47', + color: '#00ADA8', width: 5 }, // If you don't want this to show up in the legend: @@ -250,7 +254,7 @@ color: '#007FB9', borderWidth: 1 }, - data: [[5.999, 0]], + data: [[max - 0.001, 0]], silent: true, zlevel: -1, showInLegend: false @@ -267,7 +271,7 @@ }, data: mainAngles.flatMap((angle) => [ [0, angle], - [6, angle], + [max, angle], [NaN, NaN] ]) } diff --git a/frontend/src/lib/components/Forms/ModelForm/GeneralSettingForm.svelte b/frontend/src/lib/components/Forms/ModelForm/GeneralSettingForm.svelte index 9860f23b21..3f7c6a42c5 100644 --- a/frontend/src/lib/components/Forms/ModelForm/GeneralSettingForm.svelte +++ b/frontend/src/lib/components/Forms/ModelForm/GeneralSettingForm.svelte @@ -1,8 +1,10 @@ - + + + + {m.ebiosRadarParameters()} + + + + + + + + diff --git a/frontend/src/lib/components/Forms/NumberField.svelte b/frontend/src/lib/components/Forms/NumberField.svelte index 2ca5183a20..7b77edde75 100644 --- a/frontend/src/lib/components/Forms/NumberField.svelte +++ b/frontend/src/lib/components/Forms/NumberField.svelte @@ -6,6 +6,7 @@ let _class = ''; export { _class as class }; export let label: string | undefined = undefined; + export let step: number = 1; export let field: string; export let helpText: string | undefined = undefined; export let cachedValue: string | undefined; @@ -57,6 +58,7 @@