From 77ae23fc97be7a59feb1ab252245d67c282f2209 Mon Sep 17 00:00:00 2001 From: Stephanya Casanova Date: Mon, 14 Oct 2024 14:28:06 +0200 Subject: [PATCH] [backend/frontend] Fix bulk update injects (#1628) --- .../io/openbas/rest/inject/InjectApi.java | 33 +++++++++++++++++++ openbas-front/src/actions/Inject.js | 10 ++++++ .../src/admin/components/common/Context.ts | 4 +++ .../components/common/injects/Injects.tsx | 9 ++--- .../scenarios/scenario/ScenarioContext.ts | 4 +++ .../simulations/simulation/ExerciseContext.ts | 4 +++ 6 files changed, 58 insertions(+), 6 deletions(-) diff --git a/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java b/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java index d96bef345b..c8234aad59 100644 --- a/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java +++ b/openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java @@ -177,6 +177,17 @@ public Inject updateInject( return injectRepository.save(inject); } + @Transactional(rollbackFor = Exception.class) + @PutMapping(INJECT_URI + "/{exerciseId}/{injectId}/bulk") + @PreAuthorize("isExercisePlanner(#exerciseId)") + public Inject bulkUpdateInject( + @PathVariable String exerciseId, + @PathVariable String injectId, + @Valid @RequestBody InjectInput input) { + Inject inject = bulkUpdateInject(injectId, input); + return injectRepository.save(inject); + } + // -- EXERCISES -- @GetMapping(EXERCISE_URI + "/{exerciseId}/injects") @@ -490,6 +501,17 @@ public Inject scenarioInject( return injectRepository.findById(injectId).orElseThrow(ElementNotFoundException::new); } + @Transactional(rollbackFor = Exception.class) + @PutMapping(SCENARIO_URI + "/{scenarioId}/injects/{injectId}/bulk") + @PreAuthorize("isScenarioPlanner(#scenarioId)") + public Inject bulkUpdateInjectForScenario( + @PathVariable String scenarioId, + @PathVariable String injectId, + @Valid @RequestBody InjectInput input) { + Inject inject = bulkUpdateInject(injectId, input); + return injectRepository.save(inject); + } + @Transactional(rollbackFor = Exception.class) @PutMapping(SCENARIO_URI + "/{scenarioId}/injects/{injectId}") @PreAuthorize("isScenarioPlanner(#scenarioId)") @@ -581,6 +603,17 @@ private Inject updateInject(@NotBlank final String injectId, @NotNull InjectInpu return inject; } + private Inject bulkUpdateInject(@NotBlank final String injectId, @NotNull InjectInput input) { + Inject inject = this.injectRepository.findById(injectId).orElseThrow(ElementNotFoundException::new); + + // Set dependencies + inject.setTeams(fromIterable(this.teamRepository.findAllById(input.getTeams()))); + inject.setAssets(fromIterable(this.assetService.assets(input.getAssets()))); + inject.setAssetGroups(fromIterable(this.assetGroupService.assetGroups(input.getAssetGroups()))); + + return inject; + } + private Inject updateInjectActivation(@NotBlank final String injectId, @NotNull final InjectUpdateActivationInput input) { Inject inject = this.injectRepository.findById(injectId).orElseThrow(ElementNotFoundException::new); diff --git a/openbas-front/src/actions/Inject.js b/openbas-front/src/actions/Inject.js index fc42351ed2..5925724c61 100644 --- a/openbas-front/src/actions/Inject.js +++ b/openbas-front/src/actions/Inject.js @@ -25,6 +25,11 @@ export const updateInjectForExercise = (exerciseId, injectId, data) => (dispatch return putReferential(schema.inject, uri, data)(dispatch); }; +export const bulkUpdateInjectForExercise = (exerciseId, injectId, data) => (dispatch) => { + const uri = `/api/injects/${exerciseId}/${injectId}/bulk`; + return putReferential(schema.inject, uri, data)(dispatch); +}; + export const updateInjectTriggerForExercise = (exerciseId, injectId) => (dispatch) => { const uri = `/api/exercises/${exerciseId}/injects/${injectId}/trigger`; return putReferential(schema.inject, uri)(dispatch); @@ -87,6 +92,11 @@ export const fetchScenarioInjects = (scenarioId) => (dispatch) => { return getReferential(schema.arrayOfInjects, uri)(dispatch); }; +export const bulkUpdateInjectForScenario = (scenarioId, injectId, data) => (dispatch) => { + const uri = `/api/scenarios/${scenarioId}/injects/${injectId}/bulk`; + return putReferential(schema.inject, uri, data)(dispatch); +}; + export const updateInjectForScenario = (scenarioId, injectId, data) => (dispatch) => { const uri = `/api/scenarios/${scenarioId}/injects/${injectId}`; return putReferential(schema.inject, uri, data)(dispatch); diff --git a/openbas-front/src/admin/components/common/Context.ts b/openbas-front/src/admin/components/common/Context.ts index 00747deeaf..aedf0d5300 100644 --- a/openbas-front/src/admin/components/common/Context.ts +++ b/openbas-front/src/admin/components/common/Context.ts @@ -85,6 +85,7 @@ export type TeamContextType = { export type InjectContextType = { searchInjects: (input: SearchPaginationInput) => Promise<{ data: Page }>, onAddInject: (inject: Inject) => Promise<{ result: string, entities: { injects: Record } }>, + onBulkUpdateInject: (injectId: Inject['inject_id'], inject: Inject) => Promise<{ result: string, entities: { injects: Record } }>, onUpdateInject: (injectId: Inject['inject_id'], inject: Inject) => Promise<{ result: string, entities: { injects: Record } }>, onUpdateInjectTrigger?: (injectId: Inject['inject_id']) => Promise<{ result: string, entities: { injects: Record } }>, onUpdateInjectActivation: (injectId: Inject['inject_id'], injectEnabled: { inject_enabled: boolean }) => Promise<{ @@ -192,6 +193,9 @@ export const InjectContext = createContext({ onAddInject(_inject: Inject): Promise<{ result: string, entities: { injects: Record } }> { return Promise.resolve({ result: '', entities: { injects: {} } }); }, + onBulkUpdateInject(_injectId: Inject['inject_id'], _inject: Inject): Promise<{ result: string, entities: { injects: Record } }> { + return Promise.resolve({ result: '', entities: { injects: {} } }); + }, onUpdateInject(_injectId: Inject['inject_id'], _inject: Inject): Promise<{ result: string, entities: { injects: Record } }> { return Promise.resolve({ result: '', entities: { injects: {} } }); }, diff --git a/openbas-front/src/admin/components/common/injects/Injects.tsx b/openbas-front/src/admin/components/common/injects/Injects.tsx index 56f962047f..31618b2f48 100644 --- a/openbas-front/src/admin/components/common/injects/Injects.tsx +++ b/openbas-front/src/admin/components/common/injects/Injects.tsx @@ -92,11 +92,8 @@ const inlineStyles: Record = { interface Props { exerciseOrScenarioId: string - setViewMode?: (mode: string) => void - availableButtons: string[] - teams: TeamStore[] articles: ArticleStore[] variables: Variable[] @@ -411,7 +408,7 @@ const Injects: FunctionComponent = ({ injectToUpdate[`inject_${action.field}`] = R.uniq(action.values.map((n) => n.value)); } // eslint-disable-next-line no-await-in-loop - await injectContext.onUpdateInject(injectToUpdate.inject_id, R.pick(updateFields, injectToUpdate)) + await injectContext.onBulkUpdateInject(injectToUpdate.inject_id, R.pick(updateFields, injectToUpdate)) .then((result: { result: string, entities: { injects: Record } }) => { onUpdate(result); }); @@ -420,7 +417,7 @@ const Injects: FunctionComponent = ({ // @ts-expect-error define type injectToUpdate[`inject_${action.field}`] = R.uniq(action.values.map((n) => n.value)); // eslint-disable-next-line no-await-in-loop - await injectContext.onUpdateInject(injectToUpdate.inject_id, R.pick(updateFields, injectToUpdate)) + await injectContext.onBulkUpdateInject(injectToUpdate.inject_id, R.pick(updateFields, injectToUpdate)) .then((result: { result: string, entities: { injects: Record } }) => { onUpdate(result); }); @@ -435,7 +432,7 @@ const Injects: FunctionComponent = ({ injectToUpdate[`inject_${action.field}`] = []; } // eslint-disable-next-line no-await-in-loop - await injectContext.onUpdateInject(injectToUpdate.inject_id, R.pick(updateFields, injectToUpdate)) + await injectContext.onBulkUpdateInject(injectToUpdate.inject_id, R.pick(updateFields, injectToUpdate)) .then((result: { result: string, entities: { injects: Record } }) => { onUpdate(result); }); diff --git a/openbas-front/src/admin/components/scenarios/scenario/ScenarioContext.ts b/openbas-front/src/admin/components/scenarios/scenario/ScenarioContext.ts index 9fb306b473..3f4a3c8b81 100644 --- a/openbas-front/src/admin/components/scenarios/scenario/ScenarioContext.ts +++ b/openbas-front/src/admin/components/scenarios/scenario/ScenarioContext.ts @@ -2,6 +2,7 @@ import type { ImportTestSummary, Inject, InjectsImportInput, InjectTestStatus, S import { addInjectForScenario, bulkDeleteInjectsForScenario, + bulkUpdateInjectForScenario, deleteInjectScenario, fetchScenarioInjects, updateInjectActivationForScenario, @@ -24,6 +25,9 @@ const injectContextForScenario = (scenario: ScenarioStore) => { onAddInject(inject: Inject): Promise<{ result: string, entities: { injects: Record } }> { return dispatch(addInjectForScenario(scenario.scenario_id, inject)); }, + onBulkUpdateInject(injectId: Inject['inject_id'], inject: Inject): Promise<{ result: string, entities: { injects: Record } }> { + return dispatch(bulkUpdateInjectForScenario(scenario.scenario_id, injectId, inject)); + }, onUpdateInject(injectId: Inject['inject_id'], inject: Inject): Promise<{ result: string, entities: { injects: Record } }> { return dispatch(updateInjectForScenario(scenario.scenario_id, injectId, inject)); }, diff --git a/openbas-front/src/admin/components/simulations/simulation/ExerciseContext.ts b/openbas-front/src/admin/components/simulations/simulation/ExerciseContext.ts index 12dd6ccd2a..c019807ba7 100644 --- a/openbas-front/src/admin/components/simulations/simulation/ExerciseContext.ts +++ b/openbas-front/src/admin/components/simulations/simulation/ExerciseContext.ts @@ -8,6 +8,7 @@ import { fetchExerciseInjects, injectDone, updateInjectActivationForExercise, + bulkUpdateInjectForExercise, updateInjectForExercise, updateInjectTriggerForExercise, } from '../../../../actions/Inject'; @@ -27,6 +28,9 @@ const injectContextForExercise = (exercise: ExerciseStore) => { onAddInject(inject: Inject): Promise<{ result: string, entities: { injects: Record } }> { return dispatch(addInjectForExercise(exercise.exercise_id, inject)); }, + onBulkUpdateInject(injectId: Inject['inject_id'], inject: Inject): Promise<{ result: string, entities: { injects: Record } }> { + return dispatch(bulkUpdateInjectForExercise(exercise.exercise_id, injectId, inject)); + }, onUpdateInject(injectId: Inject['inject_id'], inject: Inject): Promise<{ result: string, entities: { injects: Record } }> { return dispatch(updateInjectForExercise(exercise.exercise_id, injectId, inject)); },