Skip to content

Commit

Permalink
Workshop 5 (#1164)
Browse files Browse the repository at this point in the history
  • Loading branch information
nas-tabchiche authored Dec 11, 2024
2 parents a20824f + 1805005 commit 16f2350
Show file tree
Hide file tree
Showing 16 changed files with 405 additions and 58 deletions.
26 changes: 26 additions & 0 deletions backend/core/migrations/0046_riskassessment_ebios_rm_study.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 5.1.4 on 2024-12-11 11:07

import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("core", "0045_alter_appliedcontrol_category_and_more"),
("ebios_rm", "0003_remove_ebiosrmstudy_risk_assessments"),
]

operations = [
migrations.AddField(
model_name="riskassessment",
name="ebios_rm_study",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="risk_assessments",
to="ebios_rm.ebiosrmstudy",
verbose_name="EBIOS RM study",
),
),
]
8 changes: 8 additions & 0 deletions backend/core/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1997,6 +1997,14 @@ class RiskAssessment(Assessment):
ref_id = models.CharField(
max_length=100, null=True, blank=True, verbose_name=_("reference id")
)
ebios_rm_study = models.ForeignKey(
"ebios_rm.EbiosRMStudy",
verbose_name=_("EBIOS RM study"),
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="risk_assessments",
)

class Meta:
verbose_name = _("Risk assessment")
Expand Down
2 changes: 1 addition & 1 deletion backend/core/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ class RiskAssessmentReadSerializer(AssessmentReadSerializer):

class Meta:
model = RiskAssessment
fields = "__all__"
exclude = ["ebios_rm_study"]


class AssetWriteSerializer(BaseModelSerializer):
Expand Down
1 change: 1 addition & 0 deletions backend/core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,7 @@ class RiskAssessmentViewSet(BaseModelViewSet):
"authors",
"risk_matrix",
"status",
"ebios_rm_study",
]

@action(detail=False, name="Risk assessments per status")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Generated by Django 5.1.4 on 2024-12-11 11:07

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("ebios_rm", "0002_alter_roto_target_objective"),
]

operations = [
migrations.RemoveField(
model_name="ebiosrmstudy",
name="risk_assessments",
),
]
8 changes: 0 additions & 8 deletions backend/ebios_rm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
Asset,
ComplianceAssessment,
Qualification,
RiskAssessment,
RiskMatrix,
Threat,
)
Expand Down Expand Up @@ -49,13 +48,6 @@ class Status(models.TextChoices):
"Compliance assessments established as security baseline during workshop 1.4"
),
)
risk_assessments = models.ManyToManyField(
RiskAssessment,
blank=True,
verbose_name=_("Risk assessments"),
related_name="ebios_rm_studies",
help_text=_("Risk assessments generated at the end of workshop 4"),
)
reference_entity = models.ForeignKey(
Entity,
on_delete=models.PROTECT,
Expand Down
5 changes: 5 additions & 0 deletions backend/ebios_rm/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ class EbiosRMStudyViewSet(BaseModelViewSet):
def status(self, request):
return Response(dict(EbiosRMStudy.Status.choices))

@action(detail=True, name="Get risk matrix", url_path="risk-matrix")
def risk_matrix(self, request, pk=None):
ebios_rm_study = self.get_object()
return Response(RiskMatrixReadSerializer(ebios_rm_study.risk_matrix).data)

@method_decorator(cache_page(60 * LONG_CACHE_TTL))
@action(detail=True, name="Get gravity choices")
def gravity(self, request, pk):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
bind:cachedValue={formDataCache['risk_matrix']}
label={m.riskMatrix()}
helpText={m.riskAssessmentMatrixHelpText()}
hidden={initialData.risk_matrix}
/>
<AutocompleteSelect
{form}
Expand Down Expand Up @@ -109,4 +110,15 @@
cacheLock={cacheLocks['observation']}
bind:cachedValue={formDataCache['observation']}
/>
{#if initialData.ebios_rm_study}
<AutocompleteSelect
{form}
field="ebios_rm_study"
cacheLock={cacheLocks['ebios_rm_study']}
bind:cachedValue={formDataCache['ebios_rm_study']}
label={m.ebiosRmStudy()}
options={getOptions({ objects: model.foreignKeys['ebios_rm_study'] })}
hidden
/>
{/if}
{/if}
23 changes: 3 additions & 20 deletions frontend/src/lib/utils/crud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import LanguageDisplay from '$lib/components/ModelTable/LanguageDisplay.svelte';
import LibraryActions from '$lib/components/ModelTable/LibraryActions.svelte';
import UserGroupNameDisplay from '$lib/components/ModelTable/UserGroupNameDisplay.svelte';
import { BASE_API_URL } from './constants';
import { URL_MODEL, type urlModel } from './types';
import { type urlModel } from './types';

type GetOptionsParams = {
objects: any[];
Expand Down Expand Up @@ -191,7 +191,8 @@ export const URL_MODEL_MAP: ModelMap = {
{ field: 'authors', urlModel: 'users' },
{ field: 'reviewers', urlModel: 'users', urlParams: 'is_third_party=false' },
{ field: 'risk_matrix', urlModel: 'risk-matrices' },
{ field: 'risk_scenarios', urlModel: 'risk-scenarios' }
{ field: 'risk_scenarios', urlModel: 'risk-scenarios' },
{ field: 'ebios_rm_study', urlModel: 'ebios-rm' }
],
reverseForeignKeyFields: [{ field: 'risk_assessment', urlModel: 'risk-scenarios' }],
selectFields: [{ field: 'status' }],
Expand Down Expand Up @@ -672,24 +673,6 @@ export const URL_MODEL_MAP: ModelMap = {
{ field: 'folder', urlModel: 'folders', urlParams: 'content_type=DO' }
]
},
'ro-to': {
endpointUrl: 'ebios-rm/ro-to',
name: 'roto',
localName: 'roto',
localNamePlural: 'roto',
verboseName: 'Ro to',
verboseNamePlural: 'Ro to',
foreignKeyFields: [
{ field: 'ebios_rm_study', urlModel: 'ebios-rm' },
{ field: 'feared_events', urlModel: 'feared-events' }
],
selectFields: [
{ field: 'risk-origin' },
{ field: 'motivation' },
{ field: 'resources' },
{ field: 'pertinence' }
]
},
attack_paths: {
endpointUrl: 'ebios-rm/attack-paths',
name: 'attackpath',
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/lib/utils/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ export const RiskAssessmentSchema = z.object({
due_date: z.union([z.literal('').transform(() => null), z.string().date()]).nullish(),
authors: z.array(z.string().optional()).optional(),
reviewers: z.array(z.string().optional()).optional(),
observation: z.string().optional().nullable()
observation: z.string().optional().nullable(),
ebios_rm_study: z.string().uuid().optional()
});

export const ThreatSchema = z.object({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { loadDetail } from '$lib/utils/load';
import type { PageServerLoad } from './$types';
import { getModelInfo } from '$lib/utils/crud';

export const load: PageServerLoad = async (event) => {
return await loadDetail({ event, model: getModelInfo('ebios-rm'), id: event.params.id });
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
import { loadDetail } from '$lib/utils/load';
import type { PageServerLoad } from './$types';
import { defaultWriteFormAction } from '$lib/utils/actions';
import { BASE_API_URL } from '$lib/utils/constants';
import { getModelInfo } from '$lib/utils/crud';
import { modelSchema } from '$lib/utils/schemas';
import type { ModelInfo } from '$lib/utils/types';
import { type Actions } from '@sveltejs/kit';
import { superValidate } from 'sveltekit-superforms';
import { zod } from 'sveltekit-superforms/adapters';
import type { PageServerLoad } from './$types';

export const load: PageServerLoad = async ({ params, fetch }) => {
const URLModel = 'ebios-rm';
const model: ModelInfo = getModelInfo(URLModel);

const endpoint = model.endpointUrl
? `${BASE_API_URL}/${model.endpointUrl}/${params.id}/`
: `${BASE_API_URL}/${model.urlModel}/${params.id}/`;
const res = await fetch(endpoint);
const data = await res.json();

const initialData = {
risk_matrix: data.risk_matrix.id,
ebios_rm_study: params.id
};

const createSchema = modelSchema('risk-assessments');
const createRiskAnalysisForm = await superValidate(initialData, zod(createSchema), {
errors: false
});

return { createRiskAnalysisForm, model: getModelInfo('risk-assessments') };
};

export const load: PageServerLoad = async (event) => {
return await loadDetail({ event, model: getModelInfo('ebios-rm'), id: event.params.id });
export const actions: Actions = {
create: async (event) => {
// const redirectToWrittenObject = Boolean(event.params.model === 'entity-assessments');
return defaultWriteFormAction({
event,
urlModel: 'risk-assessments',
action: 'create'
// redirectToWrittenObject: redirectToWrittenObject
});
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@
import { page } from '$app/stores';
import type { PageData } from './$types';
import { breadcrumbObject } from '$lib/utils/stores';
import type { ModalComponent, ModalSettings, ModalStore } from '@skeletonlabs/skeleton';
import { getModalStore } from '@skeletonlabs/skeleton';
import CreateModal from '$lib/components/Modals/CreateModal.svelte';
import MissingConstraintsModal from '$lib/components/Modals/MissingConstraintsModal.svelte';
import { checkConstraints } from '$lib/utils/crud';
const modalStore: ModalStore = getModalStore();
export let data: PageData;
$: breadcrumbObject.set(data.data);
const riskAnalysisCreated: boolean = data.data.risk_assessments.length > 0;
const dummydata = {
ws1: [
{
Expand Down Expand Up @@ -80,13 +88,64 @@
}
],
ws5: [
{ title: safeTranslate(m.ebiosWs5_1()), status: 'done', href: '#' },
{ title: safeTranslate(m.ebiosWs5_2()), status: 'done', href: '#' },
{ title: safeTranslate(m.ebiosWs5_3()), status: 'to_do', href: '#' },
{ title: safeTranslate(m.ebiosWs5_4()), status: 'to_do', href: '#' },
{ title: safeTranslate(m.ebiosWs5_5()), status: 'done', href: '#' }
{
title: safeTranslate(m.ebiosWs5_1()),
status: riskAnalysisCreated ? 'done' : 'to_do',
href: '#'
},
{
title: safeTranslate(m.ebiosWs5_2()),
status: 'done',
href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}`
},
{
title: safeTranslate(m.ebiosWs5_3()),
status: 'to_do',
href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}`
},
{
title: safeTranslate(m.ebiosWs5_4()),
status: 'to_do',
href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}`
},
{
title: safeTranslate(m.ebiosWs5_5()),
status: 'done',
href: `${$page.url.pathname}/workshop-five/risk-analyses?next=${$page.url.pathname}`
}
]
};
function modalCreateForm(): void {
let modalComponent: ModalComponent = {
ref: CreateModal,
props: {
form: data.createRiskAnalysisForm,
model: data.model
}
};
let modal: ModalSettings = {
type: 'component',
component: modalComponent,
// Data
title: safeTranslate('add-' + data.model.localName)
};
if (
checkConstraints(data.createRiskAnalysisForm.constraints, data.model.foreignKeys).length > 0
) {
modalComponent = {
ref: MissingConstraintsModal
};
modal = {
type: 'component',
component: modalComponent,
title: m.warning(),
body: safeTranslate('add-' + data.model.localName).toLowerCase(),
value: checkConstraints(data.createRiskAnalysisForm.constraints, data.model.foreignKeys)
};
}
modalStore.trigger(modal);
}
</script>

<div class="h-full w-full p-8">
Expand All @@ -97,7 +156,25 @@
<Tile title={m.ebiosWs2()} accent_color="bg-fuchsia-900" status="to_do" meta={dummydata.ws2} />
<Tile title={m.ebiosWs3()} accent_color="bg-teal-500" status="to_do" meta={dummydata.ws3} />
<Tile title={m.ebiosWs4()} accent_color="bg-yellow-600" status="to_do" meta={dummydata.ws4} />
<Tile title={m.ebiosWs5()} accent_color="bg-red-500" status="to_do" meta={dummydata.ws5} />
<Tile
title={m.ebiosWs5()}
accent_color="bg-red-500"
status="to_do"
meta={dummydata.ws5}
createRiskAnalysis={true}
>
<div slot="addRiskAnalysis">
<button class="flex flex-col text-left hover:text-purple-800" on:click={modalCreateForm}>
<span
class="absolute flex items-center justify-center w-8 h-8 bg-gray-100 rounded-full -start-4 ring-4 ring-white"
>
<i class="fa-solid fa-clipboard-check"></i>
</span>
<h3 class="font-medium leading-tight">{m.activity()} 1</h3>
<p class="text-sm">{safeTranslate(m.ebiosWs5_1())}</p>
</button>
</div>
</Tile>
<Tile title={m.summary()} accent_color="bg-purple-800" status="to_do" />
</div>
</div>
Loading

0 comments on commit 16f2350

Please sign in to comment.