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

Support customizable welcome message to display on login page #4131

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
*/
package org.dependencytrack.model;

import alpine.model.IConfigProperty;
import alpine.model.IConfigProperty.PropertyType;
import org.apache.commons.lang3.SystemUtils;

import java.util.Arrays;

public enum ConfigPropertyConstants {

GENERAL_BASE_URL("general", "base.url", null, PropertyType.URL, "URL used to construct links back to Dependency-Track from external systems"),
Expand Down Expand Up @@ -111,20 +114,41 @@ public enum ConfigPropertyConstants {
SEARCH_INDEXES_CONSISTENCY_CHECK_DELTA_THRESHOLD("search-indexes", "consistency.check.delta.threshold", "20", PropertyType.INTEGER, "Threshold used to trigger an index rebuild when comparing database table and corresponding lucene index (in percentage). It must be an integer between 1 and 100"),
BOM_VALIDATION_MODE("artifact", "bom.validation.mode", BomValidationMode.ENABLED.name(), PropertyType.STRING, "Flag to control the BOM validation mode"),
BOM_VALIDATION_TAGS_INCLUSIVE("artifact", "bom.validation.tags.inclusive", "[]", PropertyType.STRING, "JSON array of tags for which BOM validation shall be performed"),
BOM_VALIDATION_TAGS_EXCLUSIVE("artifact", "bom.validation.tags.exclusive", "[]", PropertyType.STRING, "JSON array of tags for which BOM validation shall NOT be performed");
BOM_VALIDATION_TAGS_EXCLUSIVE("artifact", "bom.validation.tags.exclusive", "[]", PropertyType.STRING, "JSON array of tags for which BOM validation shall NOT be performed"),
WELCOME_MESSAGE("general", "welcome.message.html", "%20%3Chtml%3E%3Ch1%3EYour%20Welcome%20Message%3C%2Fh1%3E%3C%2Fhtml%3E", PropertyType.STRING, "Custom HTML Code that is displayed before login", true),
IS_WELCOME_MESSAGE("general", "welcome.message.enabled", "false", PropertyType.BOOLEAN, "Bool that says wheter to show the welcome message or not", true);

private final String groupName;
private final String propertyName;
private final String defaultPropertyValue;
private final PropertyType propertyType;
private final String description;
private final Boolean isPublic;


ConfigPropertyConstants(String groupName, String propertyName, String defaultPropertyValue, PropertyType propertyType, String description) {
ConfigPropertyConstants(String groupName, String propertyName, String defaultPropertyValue, PropertyType propertyType, String description) {
this.groupName = groupName;
this.propertyName = propertyName;
this.defaultPropertyValue = defaultPropertyValue;
this.propertyType = propertyType;
this.description = description;
this.isPublic = false;
}

ConfigPropertyConstants(String groupName, String propertyName, String defaultPropertyValue, PropertyType propertyType, String description, Boolean isPublic) {
this.groupName = groupName;
this.propertyName = propertyName;
this.defaultPropertyValue = defaultPropertyValue;
this.propertyType = propertyType;
this.description = description;
this.isPublic = isPublic;
}

public static ConfigPropertyConstants ofProperty(final IConfigProperty property) {
return Arrays.stream(values())
.filter(value -> value.groupName.equals(property.getGroupName()) && value.propertyName.equals(property.getPropertyName()))
.findFirst()
.orElse(null);
}

public String getGroupName() {
Expand All @@ -147,4 +171,7 @@ public String getDescription() {
return description;
}

public Boolean getIsPublic() {
return isPublic;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
package org.dependencytrack.resources.v1;

import alpine.model.ConfigProperty;
import alpine.server.auth.AuthenticationNotRequired;
import alpine.server.auth.PermissionRequired;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
Expand All @@ -30,13 +32,15 @@
import io.swagger.v3.oas.annotations.security.SecurityRequirements;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.dependencytrack.auth.Permissions;
import org.dependencytrack.model.ConfigPropertyConstants;
import org.dependencytrack.persistence.QueryManager;

import jakarta.validation.Validator;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
Expand Down Expand Up @@ -156,5 +160,28 @@ public Response updateConfigProperty(List<ConfigProperty> list) {
return Response.ok(returnList).build();
}


@GET
@Path("/public/{groupName}/{propertyName}")
@Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "Returns a public ConfigProperty", description = "<p></p>")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "Public ConfigProperty returned", content = @Content(schema = @Schema(implementation = ConfigProperty.class))),
@ApiResponse(responseCode = "403", description = "This is not a public visible ConfigProperty")
})
@AuthenticationNotRequired
public Response getPublicConfigProperty(
@Parameter(description = "The group name of the value to retrieve", required = true) @PathParam("groupName") String groupName,
@Parameter(description = "The property name of the value to retrieve", required = true) @PathParam("propertyName") String propertyName) {
ConfigProperty sampleProperty = new ConfigProperty();
sampleProperty.setGroupName(groupName);
sampleProperty.setPropertyName(propertyName);
ConfigPropertyConstants publicConfigProperty = ConfigPropertyConstants.ofProperty(sampleProperty);
if (!publicConfigProperty.getIsPublic()) {
return Response.status(Response.Status.FORBIDDEN).build();
}
try (QueryManager qm = new QueryManager(getAlpineRequest())) {
ConfigProperty property = qm.getConfigProperty(groupName, propertyName);
return Response.ok(property).build();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@

import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;

public class ConfigPropertyResourceTest extends ResourceTest {

Expand Down Expand Up @@ -383,4 +384,23 @@ public void updateConfigPropertyBomValidationTagsInclusiveTest() {
assertThat(getPlainTextBody(response)).isEqualTo("Value must be a valid JSON array of strings");
}

@Test
public void getPublicAllPropertiesTest() {
for (ConfigPropertyConstants configProperty : ConfigPropertyConstants.values()) {
String groupName = configProperty.getGroupName();
String propertyName = configProperty.getPropertyName();
qm.createConfigProperty(
groupName,
propertyName,
configProperty.getDefaultPropertyValue(),
configProperty.getPropertyType(),
configProperty.getDescription());

Response response = jersey.target(V1_CONFIG_PROPERTY + "/public/" + groupName + "/" + propertyName)
.request()
.header(X_API_KEY, apiKey).get();
int status = configProperty.getIsPublic() ? 200 : 403;
assertEquals(status, response.getStatus());
}
}
}
Loading