Skip to content

Commit

Permalink
Merge branch 'refs/heads/master' into release/1.11.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimfacion committed Jan 2, 2025
2 parents ea7f3b1 + fec6ba7 commit 8713087
Show file tree
Hide file tree
Showing 32 changed files with 507 additions and 470 deletions.
4 changes: 2 additions & 2 deletions .drone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ steps:
- mvn test -q

- name: frontend-tests
image: node:22.11.0-alpine
image: node:22.12.0-alpine
volumes:
- name: cache-node-frontend
path: /drone/src/openbas-front/node_modules
Expand Down Expand Up @@ -65,7 +65,7 @@ steps:
- frontend-tests

- name: frontend-e2e-tests
image: node:22.11.0
image: node:22.12.0
volumes:
- name: cache-node-frontend-e2e
path: /drone/src/openbas-front/node_modules
Expand Down
8 changes: 8 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ assignees: ''

---

## Context

<!--
- Why is this solution needed?
- What value or benefits will the end-users gain from this change?
- Is this change a technical improvement? just for internal use, or does it impact users as well?
-->

## Use case

<!-- Please describe the use case for which you need a solution -->
Expand Down
1 change: 1 addition & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ By doing this, you are actively helping us to improve the quality of the entire
- [ ] I wrote test cases for the relevant uses case
- [ ] I added/update the relevant documentation (either on github or on notion)
- [ ] Where necessary I refactored code to improve the overall quality
- [ ] For bug fix -> I implemented a test that covers the bug

<!-- _NOTE: these things are not required to open a PR and can be done afterwards / while the PR draft is open._ -->
<!-- For completed items, change [ ] to [x]. -->
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:22.11.0-alpine3.20 AS front-builder
FROM node:22.12.0-alpine3.20 AS front-builder

WORKDIR /opt/openbas-build/openbas-front
COPY openbas-front/packages ./packages
Expand Down
4 changes: 2 additions & 2 deletions openbas-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,12 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.12</version>
<version>1.5.15</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.5.12</version>
<version>1.5.15</version>
</dependency>
<dependency>
<groupId>ch.qos.logback.contrib</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io.openbas.rest.challenge.response.ChallengeResult;
import io.openbas.rest.challenge.response.ChallengesReader;
import io.openbas.rest.exception.ElementNotFoundException;
import io.openbas.rest.exception.InputValidationException;
import io.openbas.rest.helper.RestBehavior;
import io.openbas.service.ChallengeService;
import jakarta.transaction.Transactional;
Expand Down Expand Up @@ -133,7 +134,9 @@ public void deleteChallenge(@PathVariable String challengeId) {

@PostMapping("/api/challenges/{challengeId}/try")
public ChallengeResult tryChallenge(
@PathVariable String challengeId, @Valid @RequestBody ChallengeTryInput input) {
@PathVariable String challengeId, @Valid @RequestBody ChallengeTryInput input)
throws InputValidationException {
validateUUID(challengeId);
return challengeService.tryChallenge(challengeId, input);
}

Expand All @@ -143,7 +146,11 @@ public ChallengesReader validateChallenge(
@PathVariable String exerciseId,
@PathVariable String challengeId,
@Valid @RequestBody ChallengeTryInput input,
@RequestParam Optional<String> userId) {
@RequestParam Optional<String> userId)
throws InputValidationException {
validateUUID(exerciseId);
validateUUID(challengeId);

final User user = impersonateUser(userRepository, userId);
if (user.getId().equals(ANONYMOUS)) {
throw new UnsupportedOperationException("User must be logged or dynamic player is required");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,4 +206,12 @@ public void checkOrganizationAccess(UserRepository userRepository, String organi
}
}
}

protected void validateUUID(final String id) throws InputValidationException {
try {
UUID.fromString(id);
} catch (IllegalArgumentException e) {
throw new InputValidationException("id", "The ID is not a valid UUID: " + id);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ public class InjectInput {
@JsonProperty("inject_tags")
private List<String> tagIds = new ArrayList<>();

@JsonProperty("inject_enabled")
private boolean enabled = true;

public Inject toInject(@NotNull final InjectorContract injectorContract) {
Inject inject = new Inject();
inject.setTitle(getTitle());
Expand All @@ -66,6 +69,7 @@ public Inject toInject(@NotNull final InjectorContract injectorContract) {
inject.setAllTeams(isAllTeams());
inject.setCountry(getCountry());
inject.setCity(getCity());
inject.setEnabled(isEnabled());
return inject;
}
}
22 changes: 13 additions & 9 deletions openbas-api/src/main/java/io/openbas/schema/SchemaApi.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package io.openbas.schema;

import static io.openbas.utils.schema.SchemaUtils.isValidClassName;

import io.openbas.rest.helper.RestBehavior;
import io.openbas.schema.model.PropertySchemaDTO;
import io.openbas.utils.schema.PropertySchema;
import io.openbas.utils.schema.SchemaUtils;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
Expand All @@ -21,15 +22,18 @@ public List<PropertySchemaDTO> schemas(
@RequestParam final boolean filterableOnly,
@RequestBody @Valid @NotNull List<String> filterNames)
throws ClassNotFoundException {
String completeClassName = "io.openbas.database.model." + className;
if (filterableOnly) {
return SchemaUtils.schemaWithSubtypes(Class.forName(completeClassName)).stream()
.filter(PropertySchema::isFilterable)
.filter(p -> filterNames.isEmpty() || filterNames.contains(p.getJsonName()))
.map(PropertySchemaDTO::new)
.toList();

final String basePackage = "io.openbas.database.model";

if (!isValidClassName(className)) {
throw new IllegalArgumentException("Class not allowed : " + className);
}
return SchemaUtils.schemaWithSubtypes(Class.forName(completeClassName)).stream()
String completeClassName = basePackage + "." + className;

Class<?> clazz = Class.forName(completeClassName);

return SchemaUtils.schemaWithSubtypes(clazz).stream()
.filter(p -> !filterableOnly || p.isFilterable())
.filter(p -> filterNames.isEmpty() || filterNames.contains(p.getJsonName()))
.map(PropertySchemaDTO::new)
.toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ public Page<FullTextSearchService.FullTextSearchResult> fullTextSearch(
@PathVariable @NotBlank final String clazz,
@RequestBody @Valid SearchPaginationInput searchPaginationInput)
throws ClassNotFoundException {
return this.fullTextSearchService.fullTextSearch(clazz, searchPaginationInput);
if (!this.fullTextSearchService.getAllowedClass().contains(clazz)) {
throw new IllegalArgumentException("Class not allowed : " + clazz);
}

return this.fullTextSearchService.fullTextSearch(Class.forName(clazz), searchPaginationInput);
}

@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ public void init() {
}

public Page<FullTextSearchResult> fullTextSearch(
@NotBlank final String clazz, @NotNull final SearchPaginationInput searchPaginationInput)
throws ClassNotFoundException {
@NotBlank final Class<?> clazz, @NotNull final SearchPaginationInput searchPaginationInput) {
if (!hasText(searchPaginationInput.getTextSearch())) {
Pageable pageable =
PageRequest.of(
Expand All @@ -84,10 +83,9 @@ public Page<FullTextSearchResult> fullTextSearch(
return new PageImpl<>(Collections.emptyList(), pageable, 0);
}

Class<?> clazzUnknown = Class.forName(clazz);
Class<T> clazzT =
this.repositoryMap.keySet().stream()
.filter((k) -> k.isAssignableFrom(clazzUnknown))
.filter(k -> k.isAssignableFrom(clazz))
.findFirst()
.orElseThrow(
() -> new IllegalArgumentException(clazz + " is not handle by full text search"));
Expand Down Expand Up @@ -208,10 +206,14 @@ public Map<Class<T>, FullTextSearchCountResult> fullTextSearch(

private static String getFinalSearchTerm(String searchTerm) {
return Arrays.stream(searchTerm.split(" "))
.map((s) -> "(" + s + ":*)")
.map(s -> "(" + s + ":*)")
.collect(Collectors.joining(" & "));
}

public List<String> getAllowedClass() {
return this.repositoryMap.keySet().stream().map(Class::getName).toList();
}

@AllArgsConstructor
@Data
public static class FullTextSearchCountResult {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ public void testCreateScenario_ValidInput() throws Exception {
@Test
@DisplayName(
"Test to validate existence of 'Add Inject to Scenario' endpoint and validate InjectInput")
public void testCreateInjectForScenario_ValidInput() throws Exception {
public void testCreateInjectForScenario_ValidInput_Additional_param() throws Exception {
// -- PREPARE --
String jsonInput =
"{"
Expand All @@ -174,6 +174,7 @@ public void testCreateInjectForScenario_ValidInput() throws Exception {
+ "\"inject_content\": null, "
+ "\"inject_depends_duration\": 100, "
+ "\"inject_tags\": [\"Tag1\"], "
+ "\"inject_enabled\": false, "
+ "\"inject_additional_param\": \"additional_param\""
+ "}";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class SchemaUtils {
Expand Down Expand Up @@ -213,4 +214,10 @@ public static List<PropertySchema> getFilterableProperties(List<PropertySchema>
public static List<PropertySchema> getSortableProperties(List<PropertySchema> propertySchemas) {
return propertySchemas.stream().filter(PropertySchema::isSortable).collect(Collectors.toList());
}

public static boolean isValidClassName(String className) {
String regex = "^[a-zA-Z_][a-zA-Z0-9_]*$";
Pattern pattern = Pattern.compile(regex);
return pattern.matcher(className).matches();
}
}
38 changes: 19 additions & 19 deletions openbas-front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
"license": "Apache-2.0",
"type": "module",
"dependencies": {
"@ckeditor/ckeditor5-react": "9.3.1",
"@ckeditor/ckeditor5-react": "9.4.0",
"@dagrejs/dagre": "1.1.4",
"@emotion/react": "11.13.3",
"@emotion/styled": "11.13.0",
"@fontsource/geologica": "5.0.6",
"@fontsource/ibm-plex-sans": "5.0.21",
"@emotion/react": "11.14.0",
"@emotion/styled": "11.14.0",
"@fontsource/geologica": "5.1.0",
"@fontsource/ibm-plex-sans": "5.1.0",
"@hookform/resolvers": "3.9.1",
"@microsoft/fetch-event-source": "2.0.1",
"@mui/icons-material": "6.2.0",
Expand All @@ -22,17 +22,17 @@
"@mui/utils": "6.2.0",
"@mui/x-date-pickers": "7.23.1",
"@redux-devtools/extension": "3.3.0",
"@uiw/react-md-editor": "4.0.4",
"@uiw/react-md-editor": "4.0.5",
"@xyflow/react": "12.3.6",
"apexcharts": "4.0.0",
"axios": "1.7.8",
"axios": "1.7.9",
"ckeditor5": "43.3.0",
"classcat": "5.0.5",
"classnames": "2.5.1",
"cronstrue": "2.52.0",
"d3-hierarchy": "3.1.2",
"date-fns": "4.1.0",
"dompurify": "3.1.6",
"dompurify": "3.2.3",
"elkjs": "0.9.3",
"final-form": "4.20.10",
"final-form-arrays": "3.1.0",
Expand Down Expand Up @@ -62,8 +62,8 @@
"react-leaflet": "4.2.1",
"react-markdown": "9.0.1",
"react-redux": "9.2.0",
"react-router": "7.0.1",
"react-syntax-highlighter": "15.5.0",
"react-router": "7.1.1",
"react-syntax-highlighter": "15.6.1",
"redux": "5.0.1",
"redux-thunk": "3.1.0",
"remark-flexible-markers": "1.2.1",
Expand All @@ -74,18 +74,18 @@
"usehooks-ts": "3.1.0",
"uuid": "11.0.3",
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
"zod": "3.23.8",
"zod": "3.24.1",
"zustand": "5.0.1"
},
"devDependencies": {
"@eslint/js": "9.15.0",
"@playwright/test": "1.49.0",
"@stylistic/eslint-plugin": "2.11.0",
"@playwright/test": "1.49.1",
"@stylistic/eslint-plugin": "2.12.1",
"@testing-library/dom": "10.4.0",
"@testing-library/react": "16.1.0",
"@types/d3-hierarchy": "3.1.7",
"@types/eslint__js": "8.42.3",
"@types/node": "22.9.3",
"@types/node": "22.10.2",
"@types/pdfmake": "0.2.9",
"@types/qs": "6",
"@types/react": "18.3.14",
Expand All @@ -94,13 +94,13 @@
"@types/react-syntax-highlighter": "15",
"@types/seamless-immutable": "7.1.19",
"@types/uuid": "10.0.0",
"@typescript-eslint/parser": "8.16.0",
"@typescript-eslint/parser": "8.18.1",
"@vitejs/plugin-react": "4.3.4",
"chokidar": "4.0.1",
"chokidar": "4.0.3",
"cross-env": "7.0.3",
"esbuild": "0.24.0",
"eslint": "9.15.0",
"eslint-import-resolver-oxc": "0.6.0",
"eslint-import-resolver-oxc": "0.7.0",
"eslint-plugin-custom-rules": "link:packages/eslint-plugin-custom-rules",
"eslint-plugin-i18next": "6.1.1",
"eslint-plugin-import": "2.31.0",
Expand All @@ -111,13 +111,13 @@
"eslint-plugin-simple-import-sort": "12.1.1",
"express": "4.21.1",
"fs-extra": "11.2.0",
"globals": "15.13.0",
"globals": "15.14.0",
"jsdom": "25.0.1",
"monocart-coverage-reports": "2.11.3",
"monocart-reporter": "2.9.11",
"swagger-typescript-api": "13.0.22",
"typescript": "5.7.2",
"typescript-eslint": "8.16.0",
"typescript-eslint": "8.18.1",
"vite": "6.0.3",
"vitest": "2.1.1"
},
Expand Down
16 changes: 8 additions & 8 deletions openbas-front/src/admin/components/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ const Dashboard = () => {
name: t('Number of simulations'),
data: exercisesCountByWeekHasValues
? Object.entries<number>(statistics.exercises_count_by_week!).map(([date, value]) => ({
x: date,
y: value,
}))
x: date,
y: value,
}))
: exercisesTimeSeriesFakeData,
},
], [exercisesCountByWeekHasValues, statistics?.exercises_count_by_week]);
Expand Down Expand Up @@ -140,11 +140,11 @@ const Dashboard = () => {
name: t('Number of injects'),
data: injectsCountByAttackPatternHasValues && Object.keys(attackPatternsMap).length
? Object.entries<number>(statistics.injects_count_by_attack_pattern!).map(([attackPatternId, value]) => {
return ({
x: [`[${attackPatternsMap[attackPatternId].attack_pattern_external_id}]`, attackPatternsMap[attackPatternId].attack_pattern_name],
y: value,
});
})
return ({
x: [`[${attackPatternsMap[attackPatternId].attack_pattern_external_id}]`, attackPatternsMap[attackPatternId].attack_pattern_name],
y: value,
});
})
: attackPatternsFakeData,
}],
[statistics?.injects_count_by_attack_pattern, injectsCountByAttackPatternHasValues, attackPatternsMap],
Expand Down
Loading

0 comments on commit 8713087

Please sign in to comment.