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

[backend] Adding swagger doc #2392

Draft
wants to merge 63 commits into
base: improvment/add-settings-api-doc
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
0deef84
[backend] Converting return lines to HTML tags when importing rich te…
Dimfacion Jan 31, 2025
b385212
[all] Release 1.11.5
Filigran-Automation Feb 3, 2025
5cf7b8a
[backend]Add traces for sending emails(#2324)
johanah29 Feb 5, 2025
6d48248
Merge remote-tracking branch 'origin/master' into release/current
guillaumejparis Feb 5, 2025
86b4294
[frontend] migrating from jss to emotion with tss-react (#1821)
guillaumejparis Feb 5, 2025
ce06716
[backend] Fix payloadOutput for inject contracts without payload (#2311)
savacano28 Feb 5, 2025
f4a3245
[Frontend]Correct the replay all of injects tests(#2174)
johanah29 Feb 5, 2025
99e50d6
[frontend] Remove empty css property content from divider (#1821)
savacano28 Feb 5, 2025
e60f2ca
[tool] Update postgres Docker tag to v17
renovate[bot] Feb 6, 2025
58b7e63
[frontend] Correct spacing between papers in endpoint details page (#…
johanah29 Feb 6, 2025
92e79a5
[frontend] Correct color in organizations and players selectors (#2351)
johanah29 Feb 6, 2025
14b5f4c
[backend] Expectation on Manual inject (#1768)
heditar Feb 6, 2025
ca541fe
[frontend] Update dependency mdi-material-ui to v7.9.3
renovate[bot] Feb 6, 2025
f63b63e
[frontend] Update dependency html-react-parser to v5.2.2
renovate[bot] Feb 6, 2025
01db1e4
[frontend] Update dependency express to v4.21.2
renovate[bot] Feb 6, 2025
23d54e6
[frontend] Update dependency vite to v6.1.0
renovate[bot] Feb 6, 2025
58a062f
[frontend] Correct background color in tags selector (#2350)
johanah29 Feb 6, 2025
8c35b03
[backend] Rework executor system (#2372)
RomuDeuxfois Feb 6, 2025
4acded8
[frontend] Update dependency apexcharts to v4.4.0 (release/current)
renovate[bot] Feb 6, 2025
00995ca
[backend] Fix status null on executor
savacano28 Feb 6, 2025
dd8d8eb
[frontend/backend] display traces by agent (#1951)
MarineLeM Feb 6, 2025
a5b619e
[frontend] Correct in scenario lessons learned tab (#1843)
johanah29 Feb 7, 2025
e5ee03a
[frontend] Correct spacing in simulation overview (#2173)
johanah29 Feb 7, 2025
a2ce96d
Add trace status test (#1951)
MarineLeM Feb 7, 2025
f726ebd
[frontend] Update dependency eslint-plugin-react-refresh to v0.4.19
renovate[bot] Feb 10, 2025
20eb5a0
[frontend] Update dependency @vitest/eslint-plugin to v1.1.27
renovate[bot] Feb 10, 2025
0060f49
[frontend] Update eslint monorepo to v9.20.0
renovate[bot] Feb 10, 2025
8d38084
[backend] Update dependency io.opentelemetry:opentelemetry-bom to v1.…
renovate[bot] Feb 10, 2025
7262724
[backend] Update dependency com.rabbitmq:amqp-client to v5.25.0
renovate[bot] Feb 10, 2025
fa189a3
[backend] Add exceptions when articles and challenges are deleted (#1…
johanah29 Feb 10, 2025
dafd7cb
[frontend] Update dependency monocart-reporter to v2.9.13
renovate[bot] Feb 10, 2025
e8d10ac
[frontend] Update dependency esbuild to v0.25.0
renovate[bot] Feb 10, 2025
829ec09
[frontend] Update dependency react-intl to v7.1.6
renovate[bot] Feb 10, 2025
f44ae22
[frontend] Update dependency react-router to v7.1.5
renovate[bot] Feb 10, 2025
ad41bba
Adding Swagger doc on users, tags, settings and teams endpoints
Dimfacion Feb 10, 2025
23f780c
[frontend] Update dependency uuid to v11.0.5
renovate[bot] Feb 10, 2025
f93c7cb
[frontend] Update dependency usehooks-ts to v3.1.1
renovate[bot] Feb 10, 2025
81b03c9
[frontend] Update dependency typescript to v5.7.3
renovate[bot] Feb 10, 2025
98ec186
[frontend] Update dependency swagger-typescript-api to v13.0.23
renovate[bot] Feb 10, 2025
e58a227
[frontend] Update dependency react-hook-form to v7.54.2
renovate[bot] Feb 10, 2025
06e493c
[frontend] Update dependency moment-timezone to v0.5.47
renovate[bot] Feb 10, 2025
d9273c9
[frontend] Sanitize chmod
SamuelHassine Feb 10, 2025
1037180
[frontend/backend] search missing assets for execution details logs
MarineLeM Feb 11, 2025
14e747b
[frontend] Correctly placing label of fields with on-the-fly creation…
johanah29 Feb 11, 2025
90c0557
[frontend] Correct dropdowns background (#2351)
johanah29 Feb 11, 2025
76eeca2
[backend] remove content on manual injects (#2426)
heditar Feb 11, 2025
fb34c4d
[backend] fix openapi annotations to restore compatible api types
antoinemzs Feb 11, 2025
7c39b58
[frontend] Remove color
RomuDeuxfois Feb 11, 2025
09d2611
[frontend] Fix upload documents (#2435)
Dimfacion Feb 11, 2025
4e3dfe5
[backend] fix npe definition tab (#2429)
MarineLeM Feb 11, 2025
b68edb1
[backend] Fix atomic testing in pending with asset group
damgouj Feb 11, 2025
1eb6bc3
[frontend] fix team player count on update (#2431)
antoinemzs Feb 11, 2025
9e05ec2
[frontend] remove option to remove dynamic asset from asset group (#2…
antoinemzs Feb 12, 2025
6586865
[frontend] adapt injectdefinition with new contract of EndpointsList …
antoinemzs Feb 12, 2025
b02dc61
[backend] Adding swagger documentation on User Api endpoints
Dimfacion Jan 20, 2025
633fd35
[backend] Fixes
Dimfacion Feb 5, 2025
b89b65d
[backend] Adding swagger documentation on Team Api endpoints
Dimfacion Jan 20, 2025
da7b051
[backend] Fixes
Dimfacion Feb 5, 2025
a50db8a
[backend] Adding swagger documentation on Tags Api endpoints
Dimfacion Jan 21, 2025
a63e14d
[backend] Fixes
Dimfacion Feb 5, 2025
ed1c0c6
[backend] Adding swagger doc
Dimfacion Feb 6, 2025
89346ed
[backend] Adding swagger doc
Dimfacion Feb 6, 2025
da47d12
Adding swagger doc
Dimfacion Feb 13, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ services:
MINIO_ROOT_PASSWORD: minioadmin
command: [ server, /data ]
- name: pgsql
image: postgres:16-alpine
image: postgres:17-alpine
environment:
POSTGRES_USER: openbas
POSTGRES_PASSWORD: openbas
Expand All @@ -160,7 +160,7 @@ services:
MINIO_ROOT_PASSWORD: minioadmin
command: [ server, /data ]
- name: pgsql-e2e
image: postgres:16-alpine
image: postgres:17-alpine
environment:
POSTGRES_USER: openbas
POSTGRES_PASSWORD: openbas
Expand Down
8 changes: 4 additions & 4 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.11.4</version>
<version>1.11.5</version>
</parent>

<artifactId>openbas-api</artifactId>
Expand All @@ -22,7 +22,7 @@
<springdoc-plugin.version>1.4</springdoc-plugin.version>
<cron-utils.version>9.2.1</cron-utils.version>
<apache-poi.version>5.4.0</apache-poi.version>
<opentelemetry.version>1.46.0</opentelemetry.version>
<opentelemetry.version>1.47.0</opentelemetry.version>
<opentelemetry-semconv.version>1.27.0-alpha</opentelemetry-semconv.version>
</properties>

Expand All @@ -48,12 +48,12 @@
<dependency>
<groupId>io.openbas</groupId>
<artifactId>openbas-framework</artifactId>
<version>1.11.4</version>
<version>1.11.5</version>
</dependency>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.24.0</version>
<version>5.25.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
Expand Down
12 changes: 12 additions & 0 deletions openbas-api/src/main/java/io/openbas/aop/UserRoleDescription.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.openbas.aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserRoleDescription {
boolean needAuthenticated() default true;
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ public class ExecutionExecutorService {
private final OpenBASExecutorContextService openBASExecutorContextService;
private final InjectStatusRepository injectStatusRepository;

public ExecutableInject launchExecutorContext(ExecutableInject executableInject, Inject inject)
throws InterruptedException {
public void launchExecutorContext(Inject inject) {
// First, get the assets of this injects
List<Asset> assets =
Stream.concat(
Expand Down Expand Up @@ -76,8 +75,6 @@ public ExecutableInject launchExecutorContext(ExecutableInject executableInject,
if (!atLeastOneExecution.get()) {
throw new ExecutionExecutorException("No asset executed");
}

return executableInject;
}

private void launchExecutorContextForAsset(Inject inject, Asset asset) {
Expand Down
129 changes: 54 additions & 75 deletions openbas-api/src/main/java/io/openbas/executors/Executor.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
package io.openbas.executors;

import static io.openbas.database.model.ExecutionStatus.EXECUTING;
import static io.openbas.utils.InjectionUtils.isInInjectableRange;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.openbas.asset.QueueService;
import io.openbas.database.model.*;
import io.openbas.database.model.InjectStatus;
import io.openbas.database.model.Injector;
import io.openbas.database.repository.InjectRepository;
import io.openbas.database.repository.InjectStatusRepository;
import io.openbas.database.repository.InjectorRepository;
import io.openbas.execution.ExecutableInject;
import io.openbas.execution.ExecutionExecutorService;
import io.openbas.rest.inject.service.InjectStatusService;
import jakarta.annotation.Resource;
import java.time.Instant;
import java.util.Optional;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@RequiredArgsConstructor
@Component
@RequiredArgsConstructor
public class Executor {

@Resource protected ObjectMapper mapper;
Expand All @@ -32,58 +31,71 @@ public class Executor {

private final InjectorRepository injectorRepository;

private final InjectRepository injectRepository;

private final QueueService queueService;

private final ExecutionExecutorService executionExecutorService;
private final InjectStatusService injectStatusService;

private InjectStatus executeExternal(ExecutableInject executableInject, Inject inject) {
InjectorContract injectorContract =
inject
.getInjectorContract()
.orElseThrow(
() -> new UnsupportedOperationException("Inject does not have a contract"));
private InjectStatus executeExternal(ExecutableInject executableInject, Injector injector)
throws IOException, TimeoutException {
Inject inject = executableInject.getInjection().getInject();
String jsonInject = mapper.writeValueAsString(executableInject);
InjectStatus injectStatus = this.injectStatusRepository.findByInject(inject).orElseThrow();
queueService.publish(injector.getType(), jsonInject);
injectStatus.addInfoTrace(
"The inject has been published and is now waiting to be consumed.",
ExecutionTraceAction.EXECUTION);
return this.injectStatusRepository.save(injectStatus);
}

InjectStatus status = injectStatusRepository.findByInject(inject).orElse(new InjectStatus());
status.setTrackingSentDate(Instant.now());
status.setInject(inject);
try {
String jsonInject = mapper.writeValueAsString(executableInject);
status.setName(ExecutionStatus.PENDING); // FIXME: need to be test with HTTP Collector
status.addTrace(
ExecutionTraceStatus.INFO,
"The inject has been published and is now waiting to be consumed.",
ExecutionTraceAction.EXECUTION,
null);
queueService.publish(injectorContract.getInjector().getType(), jsonInject);
} catch (Exception e) {
status.setName(ExecutionStatus.ERROR);
status.setTrackingEndDate(Instant.now());
status.addErrorTrace(e.getMessage(), ExecutionTraceAction.COMPLETE);
} finally {
return injectStatusRepository.save(status);
}
private InjectStatus executeInternal(ExecutableInject executableInject, Injector injector) {
Inject inject = executableInject.getInjection().getInject();
io.openbas.executors.Injector executor =
this.context.getBean(injector.getType(), io.openbas.executors.Injector.class);
Execution execution = executor.executeInjection(executableInject);
// After execution, expectations are already created
// Injection status is filled after complete execution
// Report inject execution
InjectStatus injectStatus = this.injectStatusRepository.findByInject(inject).orElseThrow();
InjectStatus completeStatus = injectStatusService.fromExecution(execution, injectStatus);
return injectStatusRepository.save(completeStatus);
}

private InjectStatus executeInternal(ExecutableInject executableInject, Inject inject) {
public InjectStatus execute(ExecutableInject executableInject)
throws IOException, TimeoutException {
Inject inject = executableInject.getInjection().getInject();
InjectorContract injectorContract =
inject
.getInjectorContract()
.orElseThrow(
() -> new UnsupportedOperationException("Inject does not have a contract"));

io.openbas.executors.Injector executor =
this.context.getBean(
injectorContract.getInjector().getType(), io.openbas.executors.Injector.class);
Execution execution = executor.executeInjection(executableInject);
Inject executedInject = injectRepository.findById(inject.getId()).orElseThrow();
InjectStatus completeStatus = injectStatusService.fromExecution(execution, executedInject);
return injectStatusRepository.save(completeStatus);
// Depending on injector type (internal or external) execution must be done differently
Injector injector =
injectorRepository
.findByType(injectorContract.getInjector().getType())
.orElseThrow(
() ->
new IllegalStateException(
"Injector not found for type: "
+ injectorContract.getInjector().getType()));

// Status
InjectStatus updatedStatus =
this.injectStatusService.initializeInjectStatus(inject.getId(), EXECUTING);
inject.setStatus(updatedStatus);
if (Boolean.TRUE.equals(injectorContract.getNeedsExecutor())) {
this.executionExecutorService.launchExecutorContext(inject);
}
if (injector.isExternal()) {
return executeExternal(executableInject, injector);
} else {
return executeInternal(executableInject, injector);
}
}

public InjectStatus execute(ExecutableInject executableInject) {
public InjectStatus directExecute(ExecutableInject executableInject)
throws IOException, TimeoutException {
boolean isScheduledInject = !executableInject.isDirect();
// If empty content, inject must be rejected
Inject inject = executableInject.getInjection().getInject();
Expand All @@ -95,39 +107,6 @@ public InjectStatus execute(ExecutableInject executableInject) {
throw new UnsupportedOperationException("Inject is now too old for execution");
}

InjectorContract injectorContract =
inject
.getInjectorContract()
.orElseThrow(
() -> new UnsupportedOperationException("Inject does not have a contract"));

// Depending on injector type (internal or external) execution must be done differently
Optional<Injector> externalInjector =
injectorRepository.findByType(injectorContract.getInjector().getType());

return externalInjector
.map(Injector::isExternal)
.map(
isExternal -> {
ExecutableInject newExecutableInject = executableInject;
if (injectorContract.getNeedsExecutor()) {
try {
newExecutableInject =
this.executionExecutorService.launchExecutorContext(executableInject, inject);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
if (isExternal) {
return executeExternal(newExecutableInject, inject);
} else {
return executeInternal(newExecutableInject, inject);
}
})
.orElseThrow(
() ->
new IllegalStateException(
"External injector not found for type: "
+ injectorContract.getInjector().getType()));
return this.execute(executableInject);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.openbas.injectors.caldera;

import static io.openbas.database.model.Command.COMMAND_TYPE;
import static io.openbas.database.model.ExecutionTraces.getNewErrorTrace;
import static io.openbas.database.model.ExecutionTraces.getNewInfoTrace;
import static io.openbas.database.model.InjectExpectationSignature.*;
Expand Down Expand Up @@ -126,6 +127,9 @@ public ExecutionProcess process(
}
assets.forEach(
(asset, aBoolean) -> {
if (!(asset instanceof Endpoint) || !((Endpoint) asset).getActive()) {
return;
}
try {
Endpoint executionEndpoint =
this.findAndRegisterAssetForExecution(
Expand All @@ -140,6 +144,12 @@ public ExecutionProcess process(
contract,
additionalFields);
if (result.contains("complete")) {
execution.addTrace(
getNewInfoTrace(
"Request to execute the ability sent to Caldera",
ExecutionTraceAction.START,
((Endpoint) asset).getAgents().getFirst(),
List.of()));
ExploitResult exploitResult =
this.calderaService.exploitResult(
executionEndpoint.getAgents().getFirst().getExternalReference(),
Expand All @@ -150,7 +160,7 @@ public ExecutionProcess process(
exploitResult.getCommand(),
ExecutionTraceAction.EXECUTION,
((Endpoint) asset).getAgents().getFirst(),
List.of()));
List.of(exploitResult.getLinkId())));
// Compute expectations
boolean isInGroup =
assets.get(
Expand Down Expand Up @@ -252,8 +262,6 @@ public ExecutionProcess process(
assetGroups.forEach(
(assetGroup -> computeExpectationsForAssetGroup(expectations, content, assetGroup)));

String message = "Caldera executed the ability on " + asyncIds.size() + " asset(s)";
execution.addTrace(getNewInfoTrace(message, ExecutionTraceAction.EXECUTION, asyncIds));
injectExpectationService.buildAndSaveInjectExpectations(injection, expectations);
return new ExecutionProcess(true);
}
Expand Down Expand Up @@ -281,6 +289,9 @@ public StatusPayload getPayloadOutput(String externalId) {
statusPayload.setPayloadCommandBlocks(
Collections.singletonList(payloadCommandBlock));
});
statusPayload.setName(ability.getName());
statusPayload.setType(COMMAND_TYPE);
statusPayload.setDescription(ability.getDescription());
statusPayload.setExternalId(externalId);
}

Expand Down
Loading