Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[frontend/backend] Chaining injects logically #1551

Merged
merged 34 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d27f9b4
[frontend/backend] Chaining injects logically
Dimfacion Sep 27, 2024
15b0fe2
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 1, 2024
68ad3c0
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 2, 2024
94d37ca
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 2, 2024
2b31dfd
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 2, 2024
e512548
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 2, 2024
1c2f357
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 2, 2024
3ce3eb5
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 3, 2024
72aa260
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 3, 2024
03ca9a1
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 3, 2024
b3c7f63
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 4, 2024
19ec378
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 11, 2024
52bb8a0
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 11, 2024
facf4dc
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 11, 2024
9148d26
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 11, 2024
9863aa7
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 11, 2024
78675be
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 11, 2024
8ac59ca
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 12, 2024
149de85
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 12, 2024
30505fc
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 12, 2024
d413b57
[frontend/backend] Chaining injects conditionally
Dimfacion Oct 12, 2024
33ba7bf
[frontend/backend] Fixes following PR comments
Dimfacion Oct 16, 2024
cc98848
[frontend/backend] Fixes following PR comments
Dimfacion Oct 16, 2024
0afe5af
[frontend/backend] Fixes following PR comments
Dimfacion Oct 16, 2024
9466c82
[frontend/backend] Chaining injects conditionally (#1385)
Dimfacion Oct 21, 2024
84325a8
[frontend/backend] Chaining injects conditionally (#1385)
Dimfacion Oct 21, 2024
8bd93e2
[frontend/backend] Chaining injects conditionally (#1385)
Dimfacion Oct 21, 2024
1daa8a5
[frontend/backend] Chaining injects conditionally (#1385)
Dimfacion Oct 21, 2024
f1ccba5
[frontend/backend] Chaining injects conditionally (#1385)
Dimfacion Oct 21, 2024
b651335
[frontend/backend] Chaining injects conditionally (#1385)
Dimfacion Oct 21, 2024
fca8642
[frontend/backend] Chaining injects conditionally (#1385)
Dimfacion Oct 22, 2024
2c74d81
[frontend] Chaining Injects UI improvements (#1385)
Dimfacion Oct 22, 2024
79faac7
[frontend] Chaining Injects conditionally (#1385)
Dimfacion Oct 22, 2024
5db2b2d
[frontend] Chaining injects logically (#1385)
Dimfacion Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.openbas.migration;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.openbas.database.model.InjectDependencyConditions;
import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.springframework.stereotype.Component;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;

@Component
public class V3_46__Add_table_inject_dependencies extends BaseJavaMigration {

@Override
public void migrate(Context context) throws Exception {
ObjectMapper mapper = new ObjectMapper();
Statement select = context.getConnection().createStatement();
select.execute("""
CREATE TABLE injects_dependencies (
inject_parent_id VARCHAR(255) NOT NULL REFERENCES injects(inject_id) ON DELETE CASCADE,
inject_children_id VARCHAR(255) NOT NULL REFERENCES injects(inject_id) ON DELETE CASCADE,
dependency_condition JSONB,
dependency_created_at TIMESTAMP DEFAULT now(),
dependency_updated_at TIMESTAMP DEFAULT now(),
PRIMARY KEY(inject_parent_id, inject_children_id)
);
CREATE INDEX idx_injects_dependencies ON injects_dependencies(inject_children_id);
""");

// Migration datas
ResultSet results = select.executeQuery("SELECT * FROM injects WHERE inject_depends_from_another IS NOT NULL");
PreparedStatement statement = context.getConnection().prepareStatement(
"""
INSERT INTO injects_dependencies(inject_parent_id, inject_children_id, dependency_condition)
VALUES (?, ?, to_json(?::json))
"""
);
while (results.next()) {
String injectId = results.getString("inject_id");
String parentId = results.getString("inject_depends_from_another");
InjectDependencyConditions.InjectDependencyCondition injectDependencyCondition = new InjectDependencyConditions.InjectDependencyCondition();
injectDependencyCondition.setMode(InjectDependencyConditions.DependencyMode.and);
InjectDependencyConditions.Condition condition = new InjectDependencyConditions.Condition();
condition.setKey("Execution");
condition.setOperator(InjectDependencyConditions.DependencyOperator.eq);
condition.setValue(true);
injectDependencyCondition.setConditions(List.of(condition));
statement.setString(1, parentId);
statement.setString(2, injectId);
statement.setString(3, mapper.writeValueAsString(injectDependencyCondition));
statement.addBatch();
}
statement.executeBatch();
}
}
68 changes: 65 additions & 3 deletions openbas-api/src/main/java/io/openbas/rest/inject/InjectApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -297,7 +298,20 @@ public Inject createInjectForExercise(@PathVariable String exerciseId, @Valid @R
inject.setUser(userRepository.findById(currentUser().getId()).orElseThrow(ElementNotFoundException::new));
inject.setExercise(exercise);
// Set dependencies
inject.setDependsOn(resolveOptionalRelation(input.getDependsOn(), injectRepository));
if(input.getDependsOn() != null) {
RomuDeuxfois marked this conversation as resolved.
Show resolved Hide resolved
inject.getDependsOn().addAll(
input.getDependsOn()
.stream()
.map(injectDependencyInput -> {
InjectDependency dependency = new InjectDependency();
dependency.setInjectDependencyCondition(injectDependencyInput.getConditions());
dependency.setCompositeId(new InjectDependencyId());
dependency.getCompositeId().setInjectChildren(inject);
dependency.getCompositeId().setInjectParent(injectRepository.findById(injectDependencyInput.getRelationship().getInjectParentId()).orElse(null));
return dependency;
}).toList()
);
}
inject.setTeams(fromIterable(teamRepository.findAllById(input.getTeams())));
inject.setAssets(fromIterable(assetService.assets(input.getAssets())));
inject.setAssetGroups(fromIterable(assetGroupService.assetGroups(input.getAssetGroups())));
Expand Down Expand Up @@ -467,7 +481,20 @@ public Inject createInjectForScenario(
inject.setUser(this.userRepository.findById(currentUser().getId()).orElseThrow(ElementNotFoundException::new));
inject.setScenario(scenario);
// Set dependencies
inject.setDependsOn(resolveOptionalRelation(input.getDependsOn(), this.injectRepository));
if(input.getDependsOn() != null) {
inject.getDependsOn().addAll(
input.getDependsOn()
.stream()
.map(injectDependencyInput -> {
InjectDependency dependency = new InjectDependency();
dependency.setInjectDependencyCondition(injectDependencyInput.getConditions());
dependency.setCompositeId(new InjectDependencyId());
dependency.getCompositeId().setInjectChildren(inject);
dependency.getCompositeId().setInjectParent(injectRepository.findById(injectDependencyInput.getRelationship().getInjectParentId()).orElse(null));
return dependency;
}).toList()
);
}
inject.setTeams(fromIterable(teamRepository.findAllById(input.getTeams())));
inject.setAssets(fromIterable(assetService.assets(input.getAssets())));
inject.setAssetGroups(fromIterable(assetGroupService.assetGroups(input.getAssetGroups())));
Expand Down Expand Up @@ -575,7 +602,42 @@ private Inject updateInject(@NotBlank final String injectId, @NotNull InjectInpu
inject.setUpdateAttributes(input);

// Set dependencies
inject.setDependsOn(updateRelation(input.getDependsOn(), inject.getDependsOn(), this.injectRepository));
if(input.getDependsOn() != null) {
input.getDependsOn().forEach(entry -> {
Optional<InjectDependency> existingDependency = inject.getDependsOn().stream()
.filter(injectDependency -> injectDependency.getCompositeId().getInjectParent().getId().equals(entry.getRelationship().getInjectParentId()))
.findFirst();
if(existingDependency.isPresent()) {
existingDependency.get().getInjectDependencyCondition().setConditions(entry.getConditions().getConditions());
existingDependency.get().getInjectDependencyCondition().setMode(entry.getConditions().getMode());
} else {
InjectDependency injectDependency = new InjectDependency();
injectDependency.getCompositeId().setInjectChildren(inject);
injectDependency.getCompositeId().setInjectParent(injectRepository.findById(entry.getRelationship().getInjectParentId()).orElse(null));
injectDependency.setInjectDependencyCondition(new InjectDependencyConditions.InjectDependencyCondition());
injectDependency.getInjectDependencyCondition().setConditions(entry.getConditions().getConditions());
injectDependency.getInjectDependencyCondition().setMode(entry.getConditions().getMode());
inject.getDependsOn().add(injectDependency);
}
});
}

List<InjectDependency> injectDepencyToRemove = new ArrayList<>();
if(inject.getDependsOn() != null && !inject.getDependsOn().isEmpty()) {
if (input.getDependsOn() != null && !input.getDependsOn().isEmpty()) {
inject.getDependsOn().forEach(
injectDependency -> {
if (!input.getDependsOn().stream().map((injectDependencyInput -> injectDependencyInput.getRelationship().getInjectParentId())).toList().contains(injectDependency.getCompositeId().getInjectParent().getId())) {
injectDepencyToRemove.add(injectDependency);
}
}
);
} else {
injectDepencyToRemove.addAll(inject.getDependsOn());
}
inject.getDependsOn().removeAll(injectDepencyToRemove);
}

inject.setTeams(fromIterable(this.teamRepository.findAllById(input.getTeams())));
inject.setAssets(fromIterable(this.assetService.assets(input.getAssets())));
inject.setAssetGroups(fromIterable(this.assetGroupService.assetGroups(input.getAssetGroups())));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package io.openbas.rest.inject.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.openbas.database.model.Inject;
import io.openbas.database.model.InjectDependencyConditions;
import io.openbas.database.model.InjectDependencyId;
import io.openbas.helper.MonoIdDeserializer;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import lombok.Getter;
import lombok.Setter;

@Setter
@Getter
public class InjectDependencyIdInput {

@JsonProperty("inject_parent_id")
private String injectParentId;

@JsonProperty("inject_children_id")
private String injectChildrenId;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.openbas.rest.inject.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.openbas.database.model.*;
import jakarta.persistence.EmbeddedId;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Setter
@Getter
public class InjectDependencyInput {

@JsonProperty("dependency_relationship")
private InjectDependencyIdInput relationship;

@JsonProperty("dependency_condition")
private InjectDependencyConditions.InjectDependencyCondition conditions;

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.openbas.database.model.Inject;
import io.openbas.database.model.InjectDependency;
import io.openbas.database.model.InjectorContract;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Setter
@Getter
Expand All @@ -28,7 +30,7 @@ public class InjectInput {
private ObjectNode content;

@JsonProperty("inject_depends_on")
private String dependsOn;
private List<InjectDependencyInput> dependsOn = new ArrayList<>();

@JsonProperty("inject_depends_duration")
private Long dependsDuration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.openbas.database.model.InjectDependency;
import io.openbas.database.model.InjectorContract;
import io.openbas.helper.InjectModelHelper;
import io.openbas.injectors.email.EmailContract;
Expand All @@ -12,6 +13,8 @@
import lombok.Data;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Data
public class InjectOutput {
Expand Down Expand Up @@ -39,7 +42,7 @@ public class InjectOutput {
private Long dependsDuration;

@JsonProperty("inject_depends_on")
private String dependsOn;
private List<InjectDependency> dependsOn;

@JsonProperty("inject_injector_contract")
private InjectorContract injectorContract;
Expand Down Expand Up @@ -79,20 +82,19 @@ public InjectOutput(
String exerciseId,
String scenarioId,
Long dependsDuration,
String dependsOn,
InjectorContract injectorContract,
String[] tags,
String[] teams,
String[] assets,
String[] assetGroups,
String injectType) {
String injectType,
InjectDependency injectDependency) {
this.id = id;
this.title = title;
this.enabled = enabled;
this.exercise = exerciseId;
this.scenario = scenarioId;
this.dependsDuration = dependsDuration;
this.dependsOn = dependsOn;
this.injectorContract = injectorContract;
this.tags = tags != null ? new HashSet<>(Arrays.asList(tags)) : new HashSet<>();

Expand All @@ -111,5 +113,10 @@ public InjectOutput(
this.injectType = injectType;
this.teams = teams != null ? new ArrayList<>(Arrays.asList(teams)) : new ArrayList<>();
this.content = content;

if (injectDependency != null) {
this.dependsOn = List.of(injectDependency);
}

}
}
Loading