From 42e1929b1c1082355fefcc217742d3fe085b8aa1 Mon Sep 17 00:00:00 2001 From: Mamoudou DIALLO Date: Sat, 24 Aug 2024 13:08:32 -0400 Subject: [PATCH] add possibility to create a product type and update readme --- readme.md | 68 +++++++++++-------- .../scan2dojo/command/S2DCommand.java | 49 ++++++++++--- .../dto/requests/ProductTypeRequest.java | 11 +++ .../dto/responses/ProductTypeResponse.java | 26 +++++++ .../scan2dojo/http/ProductType.java | 64 +++++++++++++++++ .../moudjames23/scan2dojo/http/Scan2Dojo.java | 17 ++++- 6 files changed, 194 insertions(+), 41 deletions(-) create mode 100644 src/main/java/io/github/moudjames23/scan2dojo/dto/requests/ProductTypeRequest.java create mode 100644 src/main/java/io/github/moudjames23/scan2dojo/dto/responses/ProductTypeResponse.java create mode 100644 src/main/java/io/github/moudjames23/scan2dojo/http/ProductType.java diff --git a/readme.md b/readme.md index 2e95cec..cab0d56 100644 --- a/readme.md +++ b/readme.md @@ -6,7 +6,8 @@ ## Features - **Configuration**: Configure the endpoint and API key for integration with DefectDojo. -- **Product Creation**: Create new products in DefectDojo. +- **Product type Creation**: Create new products type in DefectDojo. +- **Product Creation**: Create new products in DefectDojo. - **Creating engagement**: Create new engagement associated with products. - **Scan Import**: Import scan results into DefectDojo with advanced configuration options. @@ -33,17 +34,6 @@ You can use docker to install scan2dojo: curl -L https://github.com/moudjames23/scan2dojo/releases/download/v1.0.0/install.sh | bash - -### Windows - -Download the executable for windows [here](https://github.com/moudjames23/scan2dojo/releases/download/v1.0.0/install.bat) - -Run the script by typing the file name: - - install.bat - - - ## Usage ### Show version @@ -62,54 +52,74 @@ To display the custom help message, use: ### Configure endpoint and API key -Before using `scan2dojo`, you need to configure it to connect to your DefectDojo instance: +This command sets the endpoint and API key that will be used by the application to communicate with the Scan2Dojo service scan2dojo configure --endpoint https://api.example.com --apiKey your-api-key +- --***endpoint***: The url of the defectdojo service endpoint +- --***apiKey***: The api key used to authenticate requests to the endpoint + In interactive mode, you can just type: scan2dojo configure -Then enter the endpoint and apiKey -### Create a product +### Create a new product type +his command allows the user to create a new product type by providing a name, description, and two boolean flags to specify if the product type is critical and/or considered a key type. -To create a new product in DefectDojo: + scan2dojo create:product-type --name Business --description "Product type description" --critical true --key false + +- --***name***: The name of the product type. This is a required parameter provided by the user + +- --***description***: A brief description of the product type. This is a required parameter provided by the user + +- --***critical:*** Flag indicating whether the product type is considered critical. This is an optional parameter with a default value of true +- --***key***: Flag indicating whether the product type is considered a key type or primary feature. This is an optional parameter with a default value of "true + +### Create a new product + +This command allows you to create a new product by providing the necessary details such as the product name, description, type ID, and SLA configuration. If the SLA configuration is set to 0, it will be defaulted to 1. scan2dojo create:product --name "Product Name" --description "Product Description" --typeId 1 --slaConfiguration 1 -- [ ] You will have to reassure yourself of the existence of the - product type before and the **slaConfiguration** is optional +- --***name***: The name of the product. This is a required field. +- --***description***: A brief description of the product. This is a required field. +- --***typeId***: The ID representing the type of the product. This is a required field. +- --***slaConfiguration***: The Service Level Agreement (SLA) configuration ID for the product. The default value is 1 ### Create an engagement -To create a new engagement in DefectDojo: +This command allows the user to create a new engagement by providing necessary details such as the engagement name, description, start and end dates, and the associated product ID. If the start and end dates are not provided, they default to today's date and one year from today, respectively. scan2dojo create:engagement --name "Engagement name" --description "Engagement description" --start "2024-01-01" --end "2024-12-31" --productId 2 -- [ ] ***start*** is optional and by default it will take the current date -- [ ] ***end*** is optional and by default it will take the date in one year -- [ ] ***productId*** is the id of the product to which we want to link this engagement +- --***name*** The name of the engagement. This is a required field. +- --***description*** A brief description of the engagement. This is a required field. +- --***start*** The start date of the engagement in the format yyyy-MM-dd. Defaults to today's date if not provided. +- --***end*** The end date of the engagement in the format yyyy-MM-dd. Defaults to one year from today's date if not provided. +- --***productId*** The ID of the product associated with this engagement. This is a required field. + + ### Import a scan result -To import a scan result into DefectDojo: +This command allows the user to import a scan result into DefectDojo by specifying details such as the scan type, the file containing the scan results, the name of the product, the name of the engagement, and the minimum severity level of vulnerabilities to be included. scan2dojo import --scanType "Trivy Scan" --file /path/to/scan_result.json --productName "Product Name" --engagementName "Engagement Name" --minimumSeverity High -- [ ] ***--scanType*** allows you to define the type of scan supported by defectdojo. You can find the list - [here](https://documentation.defectdojo.com/integrations/parsers/file/) -- [ ] ***--file*** the absolute path of the scan result -- [ ] ***--productName*** product's name -- [ ] ***--engagementName*** engagement's name -- [ ] ***--minimumSeverity*** List of possible values: **Info**, **Low**, **Medium**, **High**, **Critical** +- --***scanType*** The type of the scan. This should correspond to the scanner used. +- --***file*** The path to the scan result file to be imported. +- ***--productName*** The name of the product in DefectDojo to which the scan result belongs. +- ***--engagementName*** The name of the engagement in DefectDojo under which the scan result will be recorded. +- ***--minimumSeverity*** The minimum severity of findings to be imported. Possible values are **Info**, **Low**, **Medium**, **High** + and **Critical** ## CI/CD integration diff --git a/src/main/java/io/github/moudjames23/scan2dojo/command/S2DCommand.java b/src/main/java/io/github/moudjames23/scan2dojo/command/S2DCommand.java index d2e0101..c56252b 100644 --- a/src/main/java/io/github/moudjames23/scan2dojo/command/S2DCommand.java +++ b/src/main/java/io/github/moudjames23/scan2dojo/command/S2DCommand.java @@ -3,6 +3,7 @@ import io.github.moudjames23.scan2dojo.dto.requests.EngagementRequest; import io.github.moudjames23.scan2dojo.dto.requests.ImportRequest; import io.github.moudjames23.scan2dojo.dto.requests.ProductRequest; +import io.github.moudjames23.scan2dojo.dto.requests.ProductTypeRequest; import io.github.moudjames23.scan2dojo.http.Scan2Dojo; import io.github.moudjames23.scan2dojo.util.DateUtil; import org.springframework.beans.factory.annotation.Value; @@ -49,18 +50,21 @@ public String displayHelp() { " $ scan2dojo version\n\n" + " # Configure endpoint and API key\n" + " $ scan2dojo configure --endpoint https://api.example.com --apiKey your-api-key\n\n" + + " # Create a new product type in DefectDojo\n" + + " $ scan2dojo create:product-type --name 'Type Name' --description 'Type description' --critical true --key true\n\n" + " # Create a new product in DefectDojo\n" + " $ scan2dojo create:product --name 'My Product' --description 'Product description' --typeId 1 --slaConfiguration 1\n\n" + " # Import a scan result to DefectDojo\n" + " $ scan2dojo import --scanType 'Trivy Scan' --file /path/to/scan_result.json --productName 'My Product' --engagementName 'Release Engagement' --minimumSeverity High\n\n" + "Scanning Commands:\n" + - " configure Configure endpoint and API key\n" + - " create:product Create new product\n" + - " create:engagement Create new engagement\n" + - " import Import scan result to DefectDojo\n\n" + + " configure Configure endpoint and API key\n" + + " create:product Create new product\n" + + " create:product-type Create new product type\n" + + " create:engagement Create new engagement\n" + + " import Import scan result to DefectDojo\n\n" + "Utility Commands:\n" + - " version Show the current version of scan2dojo\n" + - " help Display this custom help message\n\n"; + " version Show the current version of scan2dojo\n" + + " help Display this custom help message\n\n"; } @@ -87,6 +91,35 @@ public void configure( } + /** + * Shell command to create a new product type. + * + * @ShellMethod(key = "create:product-type", value = "Create a new product type") + * This command allows the user to create a new product type by providing a name, + * description, and two boolean flags to specify if the product type is critical + * and/or considered a key type. + * + * @param name The name of the product type. This is a required parameter provided by the user. + * @param description A brief description of the product type. This is a required parameter provided by the user. + * @param critical Flag indicating whether the product type is considered critical. This is an optional parameter + * with a default value of "true". + * @param key Flag indicating whether the product type is considered a key type or primary feature. This is an optional + * parameter with a default value of "true". + * @throws IOException This method may throw an IOException if there is an input/output issue + * during the creation of the product type. + */ + @ShellMethod(key = "create:product-type", value = "create new product type") + public void createProductType( + @ShellOption(help = "The name of the product type") String name, + @ShellOption(help = "A brief description of the product type.") String description, + @ShellOption(help = "The ID representing the type of the product.", defaultValue = "true") boolean critical, + @ShellOption(help = "The ID representing the type of the product.", defaultValue = "true") boolean key + ) throws IOException { + ProductTypeRequest productTypeRequest = new ProductTypeRequest(name, description, critical, key); + + this.scan2Dojo.createProductType(productTypeRequest); + } + /** * Shell command to create a new product in the defectdojo. @@ -108,12 +141,10 @@ public void createProduct( @ShellOption(help = "The name of the product.") String name, @ShellOption(help = "A brief description of the product.") String description, @ShellOption(help = "The ID representing the type of the product.") int typeId, - @ShellOption(help = "The Service Level Agreement (SLA) configuration ID for the product. Defaults to 1 if set to 0.") int slaConfiguration + @ShellOption(help = "The Service Level Agreement (SLA) configuration ID for the product. Defaults to 1 if set to 0.", defaultValue = "1") int slaConfiguration ) throws IOException { - if (slaConfiguration == 0) slaConfiguration = 1; - ProductRequest productRequest = new ProductRequest(name, description, typeId, slaConfiguration); this.scan2Dojo.createProduct(productRequest); diff --git a/src/main/java/io/github/moudjames23/scan2dojo/dto/requests/ProductTypeRequest.java b/src/main/java/io/github/moudjames23/scan2dojo/dto/requests/ProductTypeRequest.java new file mode 100644 index 0000000..b73e23a --- /dev/null +++ b/src/main/java/io/github/moudjames23/scan2dojo/dto/requests/ProductTypeRequest.java @@ -0,0 +1,11 @@ +package io.github.moudjames23.scan2dojo.dto.requests; + +public record ProductTypeRequest ( + String name, + + String description, + + boolean criticalProduct, + + boolean keyProduct +){} diff --git a/src/main/java/io/github/moudjames23/scan2dojo/dto/responses/ProductTypeResponse.java b/src/main/java/io/github/moudjames23/scan2dojo/dto/responses/ProductTypeResponse.java new file mode 100644 index 0000000..586861c --- /dev/null +++ b/src/main/java/io/github/moudjames23/scan2dojo/dto/responses/ProductTypeResponse.java @@ -0,0 +1,26 @@ +package io.github.moudjames23.scan2dojo.dto.responses; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.io.Serializable; + +@JsonIgnoreProperties(ignoreUnknown = true) +public record ProductTypeResponse ( + + int id, + String name, + + String description, + + @JsonProperty("critical_product") + boolean criticalProduct, + + @JsonProperty("key_product") + boolean keyProduct +)implements ResponseMessage, Serializable { + @Override + public String success() { + return "Product type created \uD83C\uDF89\uD83C\uDF89\uD83C\uDF89 \nId: " + this.id+ "\nName: " +this.name; + } +} \ No newline at end of file diff --git a/src/main/java/io/github/moudjames23/scan2dojo/http/ProductType.java b/src/main/java/io/github/moudjames23/scan2dojo/http/ProductType.java new file mode 100644 index 0000000..e639c02 --- /dev/null +++ b/src/main/java/io/github/moudjames23/scan2dojo/http/ProductType.java @@ -0,0 +1,64 @@ +package io.github.moudjames23.scan2dojo.http; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import io.github.moudjames23.scan2dojo.dto.Configuration; +import io.github.moudjames23.scan2dojo.dto.requests.ProductTypeRequest; +import io.github.moudjames23.scan2dojo.enums.HttpMethod; +import okhttp3.Headers; +import okhttp3.MediaType; +import okhttp3.RequestBody; + +import java.util.HashMap; +import java.util.Map; + +public class ProductType implements Request{ + + private final Configuration config; + private final ProductTypeRequest productTypeRequest; + + public ProductType(Configuration config, ProductTypeRequest productRequest) { + this.config = config; + this.productTypeRequest = productRequest; + } + + + @Override + public HttpMethod getMethod() { + return HttpMethod.POST; + } + + @Override + public Headers getHeaders() { + return new Headers.Builder() + .add(getAuthorization(), BEARER.concat(this.config.getApiKey())) + .add("Content-Type", APPLICATION_JSON) + .build(); + } + + @Override + public String getUri() { + return config.getEndpoint().concat("/api/v2/product_types/"); + } + + @Override + public RequestBody getBody() { + RequestBody requestBody; + + Map data = new HashMap<>(); + + data.put("name", productTypeRequest.name()); + data.put("description", productTypeRequest.description()); + data.put("critical_product", productTypeRequest.criticalProduct()); + data.put("key_product", productTypeRequest.keyProduct()); + + + try { + String json = new ObjectMapper().writeValueAsString(data); + requestBody = RequestBody.create(json, MediaType.parse(APPLICATION_JSON)); + } catch (JsonProcessingException e) { + throw new RuntimeException("Les données fournies sont incorrectes"); + } + return requestBody; + } +} diff --git a/src/main/java/io/github/moudjames23/scan2dojo/http/Scan2Dojo.java b/src/main/java/io/github/moudjames23/scan2dojo/http/Scan2Dojo.java index f354771..5978372 100644 --- a/src/main/java/io/github/moudjames23/scan2dojo/http/Scan2Dojo.java +++ b/src/main/java/io/github/moudjames23/scan2dojo/http/Scan2Dojo.java @@ -3,10 +3,12 @@ import io.github.moudjames23.scan2dojo.dto.requests.EngagementRequest; import io.github.moudjames23.scan2dojo.dto.requests.ImportRequest; import io.github.moudjames23.scan2dojo.dto.requests.ProductRequest; +import io.github.moudjames23.scan2dojo.dto.requests.ProductTypeRequest; import io.github.moudjames23.scan2dojo.dto.responses.EngagementResponse; import io.github.moudjames23.scan2dojo.dto.responses.ImportResponse; import io.github.moudjames23.scan2dojo.dto.responses.ProductResponse; import io.github.moudjames23.scan2dojo.dto.Configuration; +import io.github.moudjames23.scan2dojo.dto.responses.ProductTypeResponse; import io.github.moudjames23.scan2dojo.enums.ScanType; import io.github.moudjames23.scan2dojo.enums.Severity; import io.github.moudjames23.scan2dojo.util.EnumUtil; @@ -18,6 +20,7 @@ import java.net.URISyntaxException; import static io.github.moudjames23.scan2dojo.util.MessageUtil.*; +import static io.github.moudjames23.scan2dojo.util.RequestUtil.*; @Service public class Scan2Dojo { @@ -44,12 +47,20 @@ public void configure(String endpoint, String apiKey) throws IOException, URISyn } + public void createProductType(ProductTypeRequest productTypeRequest) throws IOException { + + configuration.load(); + + ProductType product = new ProductType(configuration, productTypeRequest); + executeRequest(product, ProductTypeResponse.class); + } + public void createProduct(ProductRequest productRequest) throws IOException { configuration.load(); Product product = new Product(configuration, productRequest); - RequestUtil.executeRequest(product, ProductResponse.class); + executeRequest(product, ProductResponse.class); } public void createEngagement(EngagementRequest engagementRequest) throws IOException { @@ -57,7 +68,7 @@ public void createEngagement(EngagementRequest engagementRequest) throws IOExcep configuration.load(); Engagement engagement = new Engagement(configuration, engagementRequest); - RequestUtil.executeRequest(engagement, EngagementResponse.class); + executeRequest(engagement, EngagementResponse.class); } public void importScan(ImportRequest importRequest) throws IOException { @@ -74,7 +85,7 @@ public void importScan(ImportRequest importRequest) throws IOException { } Import importer = new Import(configuration, importRequest); - RequestUtil.executeRequest(importer, ImportResponse.class); + executeRequest(importer, ImportResponse.class); }