-
Notifications
You must be signed in to change notification settings - Fork 87
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[backend/frontend] First bunch of work on TTPs (#506)
- Loading branch information
1 parent
6592b24
commit 143bd4c
Showing
19 changed files
with
750 additions
and
32 deletions.
There are no files selected for viewing
78 changes: 78 additions & 0 deletions
78
openex-api/src/main/java/io/openex/migration/V2_66__Attack_patterns.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package io.openex.migration; | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import org.flywaydb.core.api.migration.BaseJavaMigration; | ||
import org.flywaydb.core.api.migration.Context; | ||
import org.springframework.stereotype.Component; | ||
|
||
import java.sql.Connection; | ||
import java.sql.PreparedStatement; | ||
import java.sql.ResultSet; | ||
import java.sql.Statement; | ||
|
||
@Component | ||
public class V2_66__Attack_patterns extends BaseJavaMigration { | ||
|
||
@Override | ||
public void migrate(Context context) throws Exception { | ||
Connection connection = context.getConnection(); | ||
Statement select = connection.createStatement(); | ||
// Kill chain phases | ||
select.execute(""" | ||
CREATE TABLE kill_chain_phases ( | ||
phase_id varchar(255) not null constraint kill_chain_phases_pkey primary key, | ||
phase_created_at timestamp not null default now(), | ||
phase_updated_at timestamp not null default now(), | ||
phase_name varchar(255) not null, | ||
phase_kill_chain_name varchar(255) not null, | ||
phase_order bigint not null | ||
); | ||
CREATE INDEX idx_kill_chain_phases on kill_chain_phases (phase_id); | ||
CREATE UNIQUE INDEX kill_chain_phases_unique on kill_chain_phases (phase_name, phase_kill_chain_name); | ||
"""); | ||
// Attack patterns | ||
select.execute(""" | ||
CREATE TABLE attack_patterns ( | ||
attack_pattern_id varchar(255) not null constraint attack_patterns_pkey primary key, | ||
attack_pattern_created_at timestamp not null default now(), | ||
attack_pattern_updated_at timestamp not null default now(), | ||
attack_pattern_name varchar(255) not null, | ||
attack_pattern_description text, | ||
attack_pattern_external_id varchar(255) not null, | ||
attack_pattern_platforms text[], | ||
attack_pattern_permissions_required text[], | ||
attack_pattern_parent varchar(255) | ||
constraint attack_pattern_parent_fk | ||
references attack_patterns | ||
on delete cascade | ||
); | ||
CREATE INDEX idx_attack_patterns on attack_patterns (attack_pattern_id); | ||
CREATE UNIQUE INDEX attack_patterns_unique on attack_patterns (attack_pattern_external_id); | ||
"""); | ||
select.execute(""" | ||
CREATE TABLE attack_patterns_kill_chain_phases ( | ||
attack_pattern_id varchar(255) not null | ||
constraint attack_pattern_id_fk | ||
references attack_patterns | ||
on delete cascade, | ||
phase_id varchar(255) not null | ||
constraint phase_id_fk | ||
references kill_chain_phases | ||
on delete cascade, | ||
primary key (attack_pattern_id, phase_id) | ||
); | ||
CREATE INDEX idx_attack_patterns_kill_chain_phases_attack_pattern on attack_patterns_kill_chain_phases (attack_pattern_id); | ||
CREATE INDEX idx_attack_patterns_kill_chain_phases_kill_chain_phase on attack_patterns_kill_chain_phases (phase_id); | ||
"""); | ||
// Cleanup a bit indexes | ||
select.execute(""" | ||
CREATE INDEX idx_teams on teams (team_id); | ||
ALTER INDEX idx_medias RENAME TO idx_channels; | ||
ALTER INDEX idx_4e039727729413d0 RENAME TO idx_comchecks; | ||
ALTER INDEX idx_article_media_exercise RENAME TO idx_articles_channel_exercise; | ||
ALTER INDEX idx_1483a5e941221f7e RENAME TO idx_users_organization; | ||
ALTER INDEX idx_cfb417fca76ed395 RENAME TO idx_users_teams_user; | ||
ALTER INDEX idx_cfb417fccb0ca5a3 RENAME TO idx_users_teams_team; | ||
"""); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
openex-api/src/main/java/io/openex/rest/attack_pattern/AttackPatternApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package io.openex.rest.attack_pattern; | ||
|
||
import io.openex.database.model.AttackPattern; | ||
import io.openex.database.repository.AttackPatternRepository; | ||
import io.openex.rest.attack_pattern.form.AttackPatternCreateInput; | ||
import io.openex.rest.helper.RestBehavior; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import javax.annotation.security.RolesAllowed; | ||
import javax.validation.Valid; | ||
|
||
import static io.openex.database.model.User.ROLE_ADMIN; | ||
import static io.openex.database.model.User.ROLE_USER; | ||
|
||
@RestController | ||
@RolesAllowed(ROLE_USER) | ||
public class AttackPatternApi extends RestBehavior { | ||
|
||
private AttackPatternRepository attackPatternRepository; | ||
|
||
@Autowired | ||
public void setAttackPatternRepository(AttackPatternRepository attackPatternRepository) { | ||
this.attackPatternRepository = attackPatternRepository; | ||
} | ||
|
||
@GetMapping("/api/attack_patterns") | ||
public Iterable<AttackPattern> attackPatterns() { | ||
return attackPatternRepository.findAll(); | ||
} | ||
|
||
@GetMapping("/api/attack_patterns/{attackPatternId}") | ||
public AttackPattern attackPattern(@PathVariable String attackPatternId) { | ||
return attackPatternRepository.findById(attackPatternId).orElseThrow(); | ||
} | ||
|
||
@RolesAllowed(ROLE_ADMIN) | ||
@PostMapping("/api/attack_patterns") | ||
public AttackPattern createAttackPattern(@Valid @RequestBody AttackPatternCreateInput input) { | ||
AttackPattern attackPattern = new AttackPattern(); | ||
attackPattern.setUpdateAttributes(input); | ||
attackPattern.setParent(attackPatternRepository.findById(input.getParentId()).orElseThrow()); | ||
return attackPatternRepository.save(attackPattern); | ||
} | ||
|
||
@RolesAllowed(ROLE_ADMIN) | ||
@DeleteMapping("/api/attack_patterns/{attackPatternId}") | ||
public void deleteAttackPattern(@PathVariable String attackPatternId) { | ||
attackPatternRepository.deleteById(attackPatternId); | ||
} | ||
} |
82 changes: 82 additions & 0 deletions
82
openex-api/src/main/java/io/openex/rest/attack_pattern/form/AttackPatternCreateInput.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package io.openex.rest.attack_pattern.form; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import lombok.Getter; | ||
|
||
import javax.validation.constraints.NotBlank; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import static io.openex.config.AppConfig.MANDATORY_MESSAGE; | ||
|
||
@Getter | ||
public class AttackPatternCreateInput { | ||
|
||
@NotBlank(message = MANDATORY_MESSAGE) | ||
@JsonProperty("attack_pattern_name") | ||
private String name; | ||
|
||
@JsonProperty("attack_pattern_description") | ||
private String description; | ||
|
||
@NotBlank(message = MANDATORY_MESSAGE) | ||
@JsonProperty("attack_pattern_external_id") | ||
private String externalId; | ||
|
||
@JsonProperty("attack_pattern_platforms") | ||
private List<String> platforms = new ArrayList<>(); | ||
|
||
@JsonProperty("attack_pattern_permissions_required") | ||
private List<String> permissionsRequired = new ArrayList<>(); | ||
|
||
@JsonProperty("attack_pattern_parent") | ||
private String parentId; | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getDescription() { | ||
return description; | ||
} | ||
|
||
public void setDescription(String description) { | ||
this.description = description; | ||
} | ||
|
||
public String getExternalId() { | ||
return externalId; | ||
} | ||
|
||
public void setExternalId(String externalId) { | ||
this.externalId = externalId; | ||
} | ||
|
||
public List<String> getPlatforms() { | ||
return platforms; | ||
} | ||
|
||
public void setPlatforms(List<String> platforms) { | ||
this.platforms = platforms; | ||
} | ||
|
||
public List<String> getPermissionsRequired() { | ||
return permissionsRequired; | ||
} | ||
|
||
public void setPermissionsRequired(List<String> permissionsRequired) { | ||
this.permissionsRequired = permissionsRequired; | ||
} | ||
|
||
public String getParentId() { | ||
return parentId; | ||
} | ||
|
||
public void setParentId(String parentId) { | ||
this.parentId = parentId; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
openex-api/src/main/java/io/openex/rest/kill_chain_phase/KillChainPhaseApi.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package io.openex.rest.kill_chain_phase; | ||
|
||
import io.openex.database.model.KillChainPhase; | ||
import io.openex.database.repository.KillChainPhaseRepository; | ||
import io.openex.rest.helper.RestBehavior; | ||
import io.openex.rest.kill_chain_phase.form.KillChainPhaseCreateInput; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import javax.annotation.security.RolesAllowed; | ||
import javax.validation.Valid; | ||
|
||
import static io.openex.database.model.User.ROLE_ADMIN; | ||
import static io.openex.database.model.User.ROLE_USER; | ||
|
||
@RestController | ||
@RolesAllowed(ROLE_USER) | ||
public class KillChainPhaseApi extends RestBehavior { | ||
|
||
private KillChainPhaseRepository killChainPhaseRepository; | ||
|
||
@Autowired | ||
public void setKillChainPhaseRepository(KillChainPhaseRepository killChainPhaseRepository) { | ||
this.killChainPhaseRepository = killChainPhaseRepository; | ||
} | ||
|
||
@GetMapping("/api/kill_chain_phases") | ||
public Iterable<KillChainPhase> killChainPhases() { | ||
return killChainPhaseRepository.findAll(); | ||
} | ||
|
||
@GetMapping("/api/kill_chain_phases/{killChainPhaseId}") | ||
public KillChainPhase killChainPhase(@PathVariable String killChainPhaseId) { | ||
return killChainPhaseRepository.findById(killChainPhaseId).orElseThrow(); | ||
} | ||
|
||
@RolesAllowed(ROLE_ADMIN) | ||
@PostMapping("/api/kill_chain_phases") | ||
public KillChainPhase createKillChainPhase(@Valid @RequestBody KillChainPhaseCreateInput input) { | ||
KillChainPhase killChainPhase = new KillChainPhase(); | ||
killChainPhase.setUpdateAttributes(input); | ||
return killChainPhaseRepository.save(killChainPhase); | ||
} | ||
|
||
@RolesAllowed(ROLE_ADMIN) | ||
@DeleteMapping("/api/kill_chain_phases/{killChainPhaseId}") | ||
public void deleteKillChainPhase(@PathVariable String killChainPhaseId) { | ||
killChainPhaseRepository.deleteById(killChainPhaseId); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
openex-api/src/main/java/io/openex/rest/kill_chain_phase/form/KillChainPhaseCreateInput.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package io.openex.rest.kill_chain_phase.form; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import lombok.Getter; | ||
|
||
import javax.validation.constraints.NotBlank; | ||
|
||
import static io.openex.config.AppConfig.MANDATORY_MESSAGE; | ||
|
||
@Getter | ||
public class KillChainPhaseCreateInput { | ||
|
||
@NotBlank(message = MANDATORY_MESSAGE) | ||
@JsonProperty("phase_name") | ||
private String name; | ||
|
||
@JsonProperty("phase_kill_chain_name") | ||
private String killChainName; | ||
|
||
@JsonProperty("phase_order") | ||
private Long order; | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
public String getKillChainName() { | ||
return killChainName; | ||
} | ||
|
||
public void setKillChainName(String killChainName) { | ||
this.killChainName = killChainName; | ||
} | ||
|
||
public Long getOrder() { | ||
return order; | ||
} | ||
|
||
public void setOrder(Long order) { | ||
this.order = order; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.