Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/OpenBAS-Platform/openbas
Browse files Browse the repository at this point in the history
…into bug/1205

# Conflicts:
#	openbas-front/src/admin/components/atomic_testings/atomic_testing/AtomicTestingHeader.tsx
#	openbas-front/src/admin/components/simulations/simulation/ExercisePopover.tsx
  • Loading branch information
Christian-DONGMO committed Jul 26, 2024
2 parents c8c3bc5 + 70ae861 commit 66b9041
Show file tree
Hide file tree
Showing 69 changed files with 839 additions and 490 deletions.
4 changes: 2 additions & 2 deletions openbas-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>io.openbas</groupId>
<artifactId>openbas-platform</artifactId>
<version>1.2.2</version>
<version>1.3.0</version>
</parent>

<artifactId>openbas-api</artifactId>
Expand Down Expand Up @@ -35,7 +35,7 @@
<dependency>
<groupId>io.openbas</groupId>
<artifactId>openbas-framework</artifactId>
<version>1.2.2</version>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>com.rabbitmq</groupId>
Expand Down
109 changes: 42 additions & 67 deletions openbas-api/src/main/java/io/openbas/rest/exercise/ExerciseApi.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,31 @@

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import io.openbas.config.OpenBASConfig;
import io.openbas.database.model.*;
import io.openbas.database.repository.ArticleRepository;
import io.openbas.database.repository.ExerciseRepository;
import io.openbas.rest.exercise.form.ExerciseSimple;
import io.openbas.rest.inject.service.InjectDuplicateService;
import io.openbas.service.GrantService;
import io.openbas.service.InjectService;
import io.openbas.service.VariableService;
import jakarta.annotation.Resource;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.Tuple;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.*;
import jakarta.transaction.Transactional;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.Instant;
Expand All @@ -32,9 +37,9 @@
import static io.openbas.helper.StreamHelper.fromIterable;
import static io.openbas.utils.AtomicTestingUtils.getExpectationResultByTypes;
import static io.openbas.utils.Constants.ARTICLES;
import static io.openbas.utils.Constants.MAX_SIZE_OF_STRING;
import static io.openbas.utils.JpaUtils.createJoinArrayAggOnId;
import static io.openbas.utils.ResultUtils.computeTargetResults;
import static io.openbas.utils.StringUtils.duplicateString;
import static io.openbas.utils.pagination.SortUtilsCriteriaBuilder.toSortCriteriaBuilder;
import static java.util.Optional.ofNullable;
import static org.springframework.util.CollectionUtils.isEmpty;
Expand All @@ -47,11 +52,24 @@ public class ExerciseService {
@PersistenceContext
private EntityManager entityManager;

private final GrantService grantService;
private final InjectService injectService;
private final InjectDuplicateService injectDuplicateService;
private final VariableService variableService;

private final ArticleRepository articleRepository;
private final ExerciseRepository exerciseRepository;
private final VariableService variableService;

// region properties
@Value("${openbas.mail.imap.enabled}")
private boolean imapEnabled;

@Value("${openbas.mail.imap.username}")
private String imapUsername;

@Resource
private OpenBASConfig openBASConfig;
// endregion

public Page<ExerciseSimple> exercises(Specification<Exercise> specification, Pageable pageable) {
CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
Expand Down Expand Up @@ -169,6 +187,23 @@ private List<ExerciseSimple> execution(TypedQuery<Tuple> query) {
.toList();
}

// -- CREATION --

@Transactional(rollbackOn = Exception.class)
public Exercise createExercise(@NotNull final Exercise exercise){
if (imapEnabled) {
exercise.setFrom(imapUsername);
exercise.setReplyTos(List.of(imapUsername));
} else {
exercise.setFrom(openBASConfig.getDefaultMailer());
exercise.setReplyTos(List.of(openBASConfig.getDefaultReplyTo()));
}
this.grantService.computeGrant(exercise);
return exerciseRepository.save(exercise);
}

// -- DUPLICATION --

@Transactional
public Exercise getDuplicateExercise(@NotBlank String exerciseId) {
Exercise exerciseOrigin = exerciseRepository.findById(exerciseId).orElseThrow();
Expand All @@ -182,7 +217,7 @@ public Exercise getDuplicateExercise(@NotBlank String exerciseId) {

private Exercise copyExercice(Exercise exerciseOrigin) {
Exercise exerciseDuplicate = new Exercise();
exerciseDuplicate.setName(getNewName(exerciseOrigin));
exerciseDuplicate.setName(duplicateString(exerciseOrigin.getName()));
exerciseDuplicate.setCategory(exerciseOrigin.getCategory());
exerciseDuplicate.setDescription(exerciseOrigin.getDescription());
exerciseDuplicate.setFrom(exerciseOrigin.getFrom());
Expand All @@ -204,14 +239,6 @@ private Exercise copyExercice(Exercise exerciseOrigin) {
return exerciseDuplicate;
}

private static String getNewName(Exercise exerciseOrigin) {
String newName = exerciseOrigin.getName() + " (duplicate)";
if (newName.length() > MAX_SIZE_OF_STRING) {
newName = newName.substring(0, (MAX_SIZE_OF_STRING - 1) - " (duplicate)".length());
}
return newName;
}

private void getListOfDuplicatedInjects(Exercise exercise, Exercise exerciseOrigin) {
List<Inject> injectListForExercise = exerciseOrigin.getInjects()
.stream().map(inject -> injectDuplicateService.createInjectForExercise(exercise.getId(), inject.getId(), false)).toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import static io.openbas.rest.exercise.ExerciseApi.EXERCISE_URI;

Expand All @@ -38,7 +38,13 @@ public class ExerciseInjectApi extends RestBehavior {
@PreAuthorize("isExerciseObserver(#exerciseId)")
@Transactional(readOnly = true)
public Iterable<InjectOutput> exerciseInjectsSimple(@PathVariable @NotBlank final String exerciseId) {
return this.injectService.injects(InjectSpecification.fromExercise(exerciseId));
return injectService.injects(InjectSpecification.fromExercise(exerciseId));
}

@DeleteMapping(EXERCISE_URI + "/{exerciseId}/injects")
@PreAuthorize("isExercisePlanner(#exerciseId)")
public void deleteListOfInjectsForExercise(@PathVariable final String exerciseId, @RequestBody List<String> injectIds) {
injectService.deleteAllByIds(injectIds);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public Inject updateInject(
@GetMapping(EXERCISE_URI + "/{exerciseId}/injects")
@PreAuthorize("isExerciseObserver(#exerciseId)")
public Iterable<Inject> exerciseInjects(@PathVariable @NotBlank final String exerciseId) {
return injectRepository.findAll(InjectSpecification.fromExercise(exerciseId))
return injectRepository.findByExerciseId(exerciseId)
.stream()
.sorted(Inject.executionComparator)
.toList();
Expand Down Expand Up @@ -456,7 +456,7 @@ public Inject duplicateInjectForScenario(@PathVariable final String scenarioId,
@GetMapping(SCENARIO_URI + "/{scenarioId}/injects")
@PreAuthorize("isScenarioObserver(#scenarioId)")
public Iterable<Inject> scenarioInjects(@PathVariable @NotBlank final String scenarioId) {
return this.injectRepository.findAll(InjectSpecification.fromScenario(scenarioId))
return this.injectRepository.findByScenarioId(scenarioId)
.stream()
.sorted(Inject.executionComparator)
.toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import static io.openbas.rest.scenario.ScenarioApi.SCENARIO_URI;

Expand All @@ -24,7 +24,13 @@ public class ScenarioInjectApi extends RestBehavior {
@PreAuthorize("isScenarioObserver(#scenarioId)")
@Transactional(readOnly = true)
public Iterable<InjectOutput> scenarioInjectsSimple(@PathVariable @NotBlank final String scenarioId) {
return this.injectService.injects(InjectSpecification.fromScenario(scenarioId));
return injectService.injects(InjectSpecification.fromScenario(scenarioId));
}

@DeleteMapping(SCENARIO_URI + "/{scenarioId}/injects")
@PreAuthorize("isScenarioPlanner(#scenarioId)")
public void deleteListOfInjectsForScenario(@PathVariable final String scenarioId, @RequestBody List<String> injectIds) {
injectService.deleteAllByIds(injectIds);
}

}
72 changes: 5 additions & 67 deletions openbas-api/src/main/java/io/openbas/rest/payload/PayloadApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,17 @@

import io.openbas.database.model.*;
import io.openbas.database.repository.*;
import io.openbas.integrations.PayloadService;
import io.openbas.rest.exception.ElementNotFoundException;
import io.openbas.rest.helper.RestBehavior;
import io.openbas.rest.payload.form.PayloadCreateInput;
import io.openbas.rest.payload.form.PayloadUpdateInput;
import io.openbas.integrations.PayloadService;
import io.openbas.rest.payload.form.PayloadUpsertInput;
import io.openbas.rest.team.form.TeamCreateInput;
import io.openbas.utils.pagination.SearchPaginationInput;
import jakarta.transaction.Transactional;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import org.hibernate.Hibernate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand All @@ -28,16 +26,16 @@

import static io.openbas.database.model.User.ROLE_ADMIN;
import static io.openbas.database.model.User.ROLE_USER;
import static io.openbas.helper.DatabaseHelper.updateRelation;
import static io.openbas.helper.StreamHelper.fromIterable;
import static io.openbas.helper.StreamHelper.iterableToSet;
import static io.openbas.utils.pagination.PaginationUtils.buildPaginationJPA;
import static java.time.Instant.now;

@RestController
@Secured(ROLE_USER)
public class PayloadApi extends RestBehavior {

public static final String PAYLOAD_URI = "/api/payloads";

private PayloadRepository payloadRepository;
private TagRepository tagRepository;
private PayloadService payloadService;
Expand Down Expand Up @@ -194,71 +192,11 @@ public Payload updatePayload(
}
}

@PostMapping("/api/payloads/{payloadId}/duplicate")
@PostMapping(PAYLOAD_URI + "/{payloadId}/duplicate")
@PreAuthorize("isPlanner()")
@Transactional(rollbackOn = Exception.class)
public Payload duplicatePayload(@NotBlank @PathVariable final String payloadId) {
Payload payload = this.payloadRepository.findById(payloadId).orElseThrow();
switch (payload.getType()) {
case "Command":
Command existingCommandPayload = (Command) Hibernate.unproxy(payload);
Command commandPayload = new Command();
// Payload
BeanUtils.copyProperties(existingCommandPayload, commandPayload);
commandPayload.setCollector(null);
commandPayload.setExternalId(null);
commandPayload.setSource("MANUAL");
commandPayload.setStatus("VERIFIED");
commandPayload = payloadRepository.save(commandPayload);
this.payloadService.updateInjectorContractsForPayload(commandPayload);
return commandPayload;
case "Executable":
Executable existingExecutablePayload = (Executable) Hibernate.unproxy(payload);
Executable executablePayload = new Executable();
BeanUtils.copyProperties(existingExecutablePayload, executablePayload);
executablePayload.setCollector(null);
executablePayload.setExternalId(null);
executablePayload.setSource("MANUAL");
executablePayload.setStatus("VERIFIED");
// Executable
executablePayload.setExecutableFile(existingExecutablePayload.getExecutableFile());

executablePayload = payloadRepository.save(executablePayload);
this.payloadService.updateInjectorContractsForPayload(executablePayload);
return executablePayload;
case "FileDrop":
FileDrop existingFileDropPayload = (FileDrop) Hibernate.unproxy(payload);
FileDrop fileDropPayload = new FileDrop();
BeanUtils.copyProperties(existingFileDropPayload, fileDropPayload);
fileDropPayload.setCollector(null);
fileDropPayload.setExternalId(null);
fileDropPayload.setSource("MANUAL");
fileDropPayload.setStatus("VERIFIED");
this.payloadService.updateInjectorContractsForPayload(fileDropPayload);
return fileDropPayload;
case "DnsResolution":
DnsResolution existingDnsResolutionPayload = (DnsResolution) Hibernate.unproxy(payload);
DnsResolution dnsResolutionPayload = new DnsResolution();
BeanUtils.copyProperties(existingDnsResolutionPayload, dnsResolutionPayload);
dnsResolutionPayload.setCollector(null);
dnsResolutionPayload.setExternalId(null);
dnsResolutionPayload.setSource("MANUAL");
dnsResolutionPayload.setStatus("VERIFIED");
this.payloadService.updateInjectorContractsForPayload(dnsResolutionPayload);
return dnsResolutionPayload;
case "NetworkTraffic":
NetworkTraffic existingNetworkTrafficPayload = (NetworkTraffic) Hibernate.unproxy(payload);
NetworkTraffic networkTrafficPayload = new NetworkTraffic();
BeanUtils.copyProperties(existingNetworkTrafficPayload, networkTrafficPayload);
networkTrafficPayload.setCollector(null);
networkTrafficPayload.setExternalId(null);
networkTrafficPayload.setSource("MANUAL");
networkTrafficPayload.setStatus("VERIFIED");
this.payloadService.updateInjectorContractsForPayload(networkTrafficPayload);
return networkTrafficPayload;
default:
throw new UnsupportedOperationException("Payload type " + payload.getType() + " is not supported");
}
return this.payloadService.duplicate(payloadId);
}

@PostMapping("/api/payloads/upsert")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.annotation.Secured;
Expand Down Expand Up @@ -58,13 +57,13 @@ public class ScenarioApi {

@PostMapping(SCENARIO_URI)
public Scenario createScenario(@Valid @RequestBody final ScenarioInput input) {
if (input != null) {
Scenario scenario = new Scenario();
scenario.setUpdateAttributes(input);
scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds())));
return this.scenarioService.createScenario(scenario);
if (input == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Scenario input cannot be null");
}
throw new ResponseStatusException(HttpStatus.BAD_REQUEST);
Scenario scenario = new Scenario();
scenario.setUpdateAttributes(input);
scenario.setTags(iterableToSet(this.tagRepository.findAllById(input.getTagIds())));
return this.scenarioService.createScenario(scenario);
}

@PostMapping(SCENARIO_URI + "/{scenarioId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@
import static io.openbas.helper.StreamHelper.fromIterable;
import static io.openbas.helper.StreamHelper.iterableToSet;
import static io.openbas.utils.AtomicTestingUtils.*;
import static io.openbas.utils.Constants.MAX_SIZE_OF_STRING;
import static io.openbas.utils.JpaUtils.createJoinArrayAggOnId;
import static io.openbas.utils.JpaUtils.createLeftJoin;
import static io.openbas.utils.StringUtils.duplicateString;
import static io.openbas.utils.pagination.PaginationUtils.buildPaginationCriteriaBuilder;
import static io.openbas.utils.pagination.SortUtilsCriteriaBuilder.toSortCriteriaBuilder;

Expand Down Expand Up @@ -196,7 +196,7 @@ public Inject copyInject(@NotNull Inject injectOrigin, boolean isAtomic) {
Inject injectDuplicate = new Inject();
injectDuplicate.setUser(injectOrigin.getUser());
if (isAtomic) {
injectDuplicate.setTitle(getNewTitle(injectOrigin));
injectDuplicate.setTitle(duplicateString(injectOrigin.getTitle()));
} else {
injectDuplicate.setTitle(injectOrigin.getTitle());
}
Expand Down Expand Up @@ -224,15 +224,6 @@ public Inject copyInject(@NotNull Inject injectOrigin, boolean isAtomic) {
return injectDuplicate;
}

@NotNull
private String getNewTitle(@NotNull Inject injectOrigin) {
String newTitle = injectOrigin.getTitle() + " (duplicate)";
if (newTitle.length() > MAX_SIZE_OF_STRING) {
newTitle = newTitle.substring(0, (MAX_SIZE_OF_STRING - 1) - " (duplicate)".length());
}
return newTitle;
}

public InjectResultDTO updateAtomicTestingTags(String injectId, AtomicTestingUpdateTagsInput input) {

Inject inject = injectRepository.findById(injectId).orElseThrow();
Expand Down
Loading

0 comments on commit 66b9041

Please sign in to comment.