Skip to content

Commit

Permalink
[backend/frontend] Support custom injector contracts
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelHassine committed Apr 24, 2024
1 parent b7eef6a commit 0a4febe
Show file tree
Hide file tree
Showing 33 changed files with 462 additions and 153 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ChallengeInjector {
@Autowired
public ChallengeInjector(InjectorService injectorService, ChallengeContract contract) {
try {
injectorService.register(CHALLENGE_INJECTOR_ID, CHALLENGE_INJECTOR_NAME, contract);
injectorService.register(CHALLENGE_INJECTOR_ID, CHALLENGE_INJECTOR_NAME, contract, false);
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ChannelInjector {
@Autowired
public ChannelInjector(InjectorService injectorService, ChannelContract contract) {
try {
injectorService.register(CHANNEL_INJECTOR_ID, CHANNEL_INJECTOR_NAME, contract);
injectorService.register(CHANNEL_INJECTOR_ID, CHANNEL_INJECTOR_NAME, contract, false);
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class EmailInjector {
@Autowired
public EmailInjector(InjectorService injectorService, EmailContract contract) {
try {
injectorService.register(EMAIL_INJECTOR_ID, EMAIL_INJECTOR_NAME, contract);
injectorService.register(EMAIL_INJECTOR_ID, EMAIL_INJECTOR_NAME, contract, false);
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ManualInjector {
@Autowired
public ManualInjector(InjectorService injectorService, ManualContract contract) {
try {
injectorService.register(MANUAL_INJECTOR_ID, MANUAL_INJECTOR_NAME, contract);
injectorService.register(MANUAL_INJECTOR_ID, MANUAL_INJECTOR_NAME, contract, true);
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.openbas.migration;

import org.flywaydb.core.api.migration.BaseJavaMigration;
import org.flywaydb.core.api.migration.Context;
import org.springframework.stereotype.Component;

import java.sql.Statement;

@Component
public class V2_91__Custom_inject_contracts extends BaseJavaMigration {

@Override
public void migrate(Context context) throws Exception {
Statement select = context.getConnection().createStatement();
// Exercise

select.execute("ALTER TABLE injectors_contracts ADD injector_contract_custom bool default false;");
select.execute("ALTER TABLE injectors DROP injector_contract_template;");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@
import io.openbas.rest.injector.response.InjectorRegistration;
import io.openbas.rest.injector_contract.form.InjectorContractInput;
import io.openbas.service.FileService;
import io.openbas.utils.pagination.SearchPaginationInput;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.MediaType;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.*;
Expand All @@ -39,7 +35,6 @@
import static io.openbas.helper.StreamHelper.fromIterable;
import static io.openbas.service.QueueService.EXCHANGE_KEY;
import static io.openbas.service.QueueService.ROUTING_KEY;
import static io.openbas.utils.pagination.PaginationUtils.buildPaginationJPA;

@RestController
public class InjectorApi extends RestBehavior {
Expand Down Expand Up @@ -114,12 +109,11 @@ private InjectorContract convertInjectorFromInput(InjectorContractInput in, Inje
return injectorContract;
}

private Injector updateInjector(Injector injector, String name, List<InjectorContractInput> contracts, Boolean customContracts, String contractTemplate) {
private Injector updateInjector(Injector injector, String name, List<InjectorContractInput> contracts, Boolean customContracts) {
injector.setUpdatedAt(Instant.now());
injector.setName(name);
injector.setExternal(true);
injector.setCustomContracts(customContracts);
injector.setContractTemplate(contractTemplate);
List<String> existing = new ArrayList<>();
List<String> toDeletes = new ArrayList<>();
injector.getContracts().forEach(contract -> {
Expand All @@ -137,7 +131,7 @@ private Injector updateInjector(Injector injector, String name, List<InjectorCon
} else {
contract.setAttackPatterns(new ArrayList<>());
}
} else {
} else if( !contract.getCustom() ) {
toDeletes.add(contract.getId());
}
});
Expand All @@ -153,7 +147,7 @@ private Injector updateInjector(Injector injector, String name, List<InjectorCon
@PutMapping("/api/injectors/{injectorId}")
public Injector updateInjector(@PathVariable String injectorId, @Valid @RequestBody InjectorUpdateInput input) {
Injector injector = injectorRepository.findById(injectorId).orElseThrow();
return updateInjector(injector, input.getName(), input.getContracts(), input.getCustomContracts(), input.getContractTemplate());
return updateInjector(injector, input.getName(), input.getContracts(), input.getCustomContracts());
}

@Secured(ROLE_ADMIN)
Expand Down Expand Up @@ -193,7 +187,7 @@ public InjectorRegistration registerInjector(@Valid @RequestPart("input") Inject
// We need to support upsert for registration
Injector injector = injectorRepository.findById(input.getId()).orElse(null);
if (injector != null) {
updateInjector(injector, input.getName(), input.getContracts(), input.getCustomContracts(), input.getContractTemplate());
updateInjector(injector, input.getName(), input.getContracts(), input.getCustomContracts());
} else {
// save the injector
Injector newInjector = new Injector();
Expand All @@ -202,7 +196,6 @@ public InjectorRegistration registerInjector(@Valid @RequestPart("input") Inject
newInjector.setName(input.getName());
newInjector.setType(input.getType());
newInjector.setCustomContracts(input.getCustomContracts());
newInjector.setContractTemplate(input.getContractTemplate());
Injector savedInjector = injectorRepository.save(newInjector);
// Save the contracts
List<InjectorContract> injectorContracts = input.getContracts().stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ public class InjectorCreateInput {
@JsonProperty("injector_custom_contracts")
private Boolean customContracts = false;

@JsonProperty("injector_contract_template")
private String contractTemplate;

public String getId() {
return id;
}
Expand Down Expand Up @@ -70,12 +67,4 @@ public Boolean getCustomContracts() {
public void setCustomContracts(Boolean customContracts) {
this.customContracts = customContracts;
}

public String getContractTemplate() {
return contractTemplate;
}

public void setContractTemplate(String contractTemplate) {
this.contractTemplate = contractTemplate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,4 @@ public class InjectorUpdateInput {

@JsonProperty("injector_custom_contracts")
private Boolean customContracts = false;

@JsonProperty("injector_contract_template")
private String contractTemplate;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import io.openbas.config.OpenBASConfig;
import io.openbas.database.model.AttackPattern;
import io.openbas.database.model.InjectorContract;
import io.openbas.database.repository.AttackPatternRepository;
import io.openbas.database.repository.InjectorContractRepository;
import io.openbas.database.repository.InjectorRepository;
import io.openbas.rest.helper.RestBehavior;
import io.openbas.rest.injector.form.InjectorContractUpdateInput;
import io.openbas.rest.injector_contract.form.InjectorContractAddInput;
import io.openbas.rest.injector_contract.form.InjectorContractUpdateInput;
import io.openbas.rest.injector_contract.form.InjectorContractUpdateMappingInput;
import io.openbas.utils.pagination.SearchPaginationInput;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
Expand Down Expand Up @@ -82,8 +82,13 @@ public InjectorContract injectorContract(@PathVariable String injectorContractId
@PostMapping("/api/injector_contracts")
public InjectorContract createInjectorContract(@Valid @RequestBody InjectorContractAddInput input) {
InjectorContract injectorContract = new InjectorContract();
injectorContract.setCustom(true);
injectorContract.setUpdateAttributes(input);
injectorContract.setAttackPatterns(fromIterable(attackPatternRepository.findAllByExternalIdInIgnoreCase(input.getAttackPatternsExternalIds())));
if (!input.getAttackPatternsExternalIds().isEmpty()) {
injectorContract.setAttackPatterns(fromIterable(attackPatternRepository.findAllByExternalIdInIgnoreCase(input.getAttackPatternsExternalIds())));
} else if (!input.getAttackPatternsIds().isEmpty()) {
injectorContract.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
}
injectorContract.setInjector(updateRelation(input.getInjectorId(), injectorContract.getInjector(), injectorRepository));
return injectorContractRepository.save(injectorContract);
}
Expand All @@ -93,6 +98,16 @@ public InjectorContract createInjectorContract(@Valid @RequestBody InjectorContr
public InjectorContract updateInjectorContract(@PathVariable String injectorContractId, @Valid @RequestBody InjectorContractUpdateInput input) {
InjectorContract injectorContract = injectorContractRepository.findById(injectorContractId).orElseThrow();
injectorContract.setUpdateAttributes(input);
injectorContract.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
injectorContract.setUpdatedAt(Instant.now());
return injectorContractRepository.save(injectorContract);
}

@Secured(ROLE_ADMIN)
@PutMapping("/api/injector_contracts/{injectorContractId}/mapping")
public InjectorContract updateInjectorContractMapping(@PathVariable String injectorContractId, @Valid @RequestBody InjectorContractUpdateMappingInput input) {
InjectorContract injectorContract = injectorContractRepository.findById(injectorContractId).orElseThrow();
injectorContract.setAttackPatterns(fromIterable(attackPatternRepository.findAllById(input.getAttackPatternsIds())));
injectorContract.setUpdatedAt(Instant.now());
return injectorContractRepository.save(injectorContract);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public class InjectorContractAddInput {
@JsonProperty("contract_labels")
private Map<String, String> labels;

@Getter
@JsonProperty("contract_attack_patterns_ids")
private List<String> attackPatternsIds = new ArrayList<>();

@Getter
@JsonProperty("contract_attack_patterns_external_ids")
private List<String> attackPatternsExternalIds = new ArrayList<>();
Expand Down Expand Up @@ -75,6 +79,14 @@ public void setLabels(Map<String, String> labels) {
this.labels = labels;
}

public List<String> getAttackPatternsIds() {
return attackPatternsIds;
}

public void setAttackPatternsIds(List<String> attackPatternsIds) {
this.attackPatternsIds = attackPatternsIds;
}

public List<String> getAttackPatternsExternalIds() {
return attackPatternsExternalIds;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.openbas.rest.injector.form;
package io.openbas.rest.injector_contract.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
Expand All @@ -23,8 +23,8 @@ public class InjectorContractUpdateInput {
private Map<String, String> labels;

@Getter
@JsonProperty("contract_attack_patterns_external_ids")
private List<String> attackPatternsExternalIds = new ArrayList<>();
@JsonProperty("contract_attack_patterns_ids")
private List<String> attackPatternsIds = new ArrayList<>();

@Getter
@NotBlank(message = MANDATORY_MESSAGE)
Expand All @@ -42,8 +42,8 @@ public void setLabels(Map<String, String> labels) {
this.labels = labels;
}

public void setAttackPatternsExternalIds(List<String> attackPatternsExternalIds) {
this.attackPatternsExternalIds = attackPatternsExternalIds;
public void setAttackPatternsIds(List<String> attackPatternsIds) {
this.attackPatternsIds = attackPatternsIds;
}

public void setContent(String content) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.openbas.rest.injector_contract.form;

import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter;
import lombok.Setter;

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

import static io.openbas.config.AppConfig.MANDATORY_MESSAGE;

@Getter
@Setter
public class InjectorContractUpdateMappingInput {
@Getter
@JsonProperty("contract_attack_patterns_ids")
private List<String> attackPatternsIds = new ArrayList<>();

public List<String> getAttackPatternsIds() {
return attackPatternsIds;
}

public void setAttackPatternsIds(List<String> attackPatternsIds) {
this.attackPatternsIds = attackPatternsIds;
}
}
2 changes: 1 addition & 1 deletion openbas-collectors
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public void setInjectorContractRepository(InjectorContractRepository injectorCon
}

@Transactional
public void register(String id, String name, Contractor contractor) throws Exception {
public void register(String id, String name, Contractor contractor, Boolean isCustomizable) throws Exception {
if(!contractor.isExpose()) {
return;
}
Expand All @@ -76,6 +76,7 @@ public void register(String id, String name, Contractor contractor) throws Excep
injector.setId(id);
injector.setName(name);
injector.setExternal(false);
injector.setCustomContracts(isCustomizable);
injector.setType(contractor.getType());
List<String> existing = new ArrayList<>();
List<InjectorContract> toUpdates = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ public class Contract {
@JsonProperty("contract_attack_patterns_external_ids")
private List<String> attackPatternsExternalIds = new ArrayList<>();

private final Map<String, String> data = new HashMap<>();

@Setter
@JsonProperty("is_atomic_testing")
private boolean isAtomicTesting = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ public class ContractField {

private boolean mandatory;

private boolean readOnly;

private ContractCardinality cardinality;

ContractField(String name, ContractType type, ContractCardinality cardinality, Boolean mandatory) {
ContractField(String name, ContractType type, ContractCardinality cardinality, Boolean mandatory, Boolean readOnly) {
this.name = name;
this.type = type;
this.cardinality = cardinality;
this.mandatory = mandatory;
this.readOnly = readOnly;
}

public String getName() {
Expand Down Expand Up @@ -48,4 +51,12 @@ public boolean isMandatory() {
public void setMandatory(boolean mandatory) {
this.mandatory = mandatory;
}

public boolean isReadOnly() {
return readOnly;
}

public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ public enum ContractType {
Asset,
@JsonProperty("asset-group")
AssetGroup,
@JsonProperty("payload")
Payload,
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public abstract class ContractElement {
private String label;

private boolean mandatory = true;

private boolean readOnly = false;

private List<String> mandatoryGroups;

private List<LinkedFieldModel> linkedFields = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.openbas.contract.fields;

import io.openbas.contract.ContractCardinality;
import io.openbas.contract.ContractType;

public class ContractPayload extends ContractCardinalityElement {

public ContractPayload(String key, String label, ContractCardinality cardinality) {
super(key, label, cardinality);
}

public static ContractPayload payloadField(String key, String label, ContractCardinality cardinality) {
return new ContractPayload(key, label, cardinality);
}

@Override
public ContractType getType() {
return ContractType.Payload;
}
}
Loading

0 comments on commit 0a4febe

Please sign in to comment.