Skip to content
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,6 +18,7 @@

import jakarta.enterprise.context.ApplicationScoped;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.spi.PropertiesComponent;
import org.eclipse.microprofile.config.inject.ConfigProperty;

@ApplicationScoped
Expand All @@ -40,12 +41,12 @@ public class CyberArkRoutes extends RouteBuilder {
public void configure() throws Exception {

from("direct:createSecret")
.toF("cyberark-vault:secret?operation=createSecret&secretId=BotApp/secretVar&url=%s&account=%s&username=%s&apiKey=%s",
.toF("cyberark-vault:secret?operation=createSecret&url=%s&account=%s&username=%s&apiKey=%s",
url, account, writeUsername, writeApiKey)
.log("Secret created/updated");

from("direct:createSecretUnauthorized")
.toF("cyberark-vault:secret?operation=createSecret&secretId=BotApp/secretVar&url=%s&account=%s&username=%s&apiKey=%s",
.toF("cyberark-vault:secret?operation=createSecret&url=%s&account=%s&username=%s&apiKey=%s",
url, account, readUsername, readApiKey)
.log("Secret created/updated");

Expand All @@ -54,5 +55,22 @@ public void configure() throws Exception {
url, account, readUsername, readApiKey)
.log("Retrieved secret: ${body}");

from("direct:getSecretByHeader")
.toF("cyberark-vault:secret?url=%s&account=%s&username=%s&apiKey=%s",
url, account, readUsername, readApiKey);

from("direct:getSecretVersion")
.toF("cyberark-vault:secret?secretId=BotApp/versionVar&url=%s&account=%s&username=%s&apiKey=%s",
url, account, readUsername, readApiKey);

// Programmatic equivalent of {{cyberark:BotApp/secretVar}} placeholder — resolved at runtime since the secret doesn't exist at route build time
from("direct:propertyPlaceholder")
.process(exchange -> {
PropertiesComponent component = exchange.getContext().getPropertiesComponent();
component.resolveProperty("cyberark:BotApp/secretVar").ifPresent(value -> {
exchange.getMessage().setBody(value);
});
});

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.camel.quarkus.component.cyberark.vault.it;

import java.util.Map;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.Consumes;
Expand All @@ -27,6 +29,7 @@
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.component.cyberark.vault.CyberArkVaultConstants;
import org.jboss.logging.Logger;

@Path("/cyberark-vault")
Expand All @@ -38,12 +41,15 @@ public class CyberarkVaultResource {
@Inject
ProducerTemplate producerTemplate;

@Path("/createSecret/{authorized}")
@Path("/createSecret/{authorized}/{policy}/{secret}")
@POST
@Consumes(MediaType.TEXT_PLAIN)
public Response createSecret(String secret, @PathParam("authorized") boolean authorized) {
public Response createSecret(String body, @PathParam("authorized") boolean authorized,
@PathParam("policy") String policy, @PathParam("secret") String secret) {
try {
producerTemplate.requestBody("direct:createSecret" + (authorized ? "" : "Unauthorized"), secret, String.class);
producerTemplate.requestBodyAndHeader(
"direct:createSecret" + (authorized ? "" : "Unauthorized"), body,
CyberArkVaultConstants.SECRET_ID, policy + "/" + secret, String.class);
} catch (RuntimeException e) {
return Response.serverError().entity(e.getCause().getCause().getMessage()).build();
}
Expand All @@ -56,4 +62,29 @@ public Response createSecret(String secret, @PathParam("authorized") boolean aut
public String getSecret() {
return producerTemplate.requestBody("direct:getSecret", "", String.class);
}

@Path("/getSecretByHeader/{policy}/{secret}")
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getSecretByHeader(@PathParam("policy") String policy, @PathParam("secret") String secret) {
return producerTemplate.requestBodyAndHeader(
"direct:getSecretByHeader", "", CyberArkVaultConstants.SECRET_ID, policy + "/" + secret, String.class);
}

@Path("/getSecretVersion/{version}")
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getSecretVersion(@PathParam("version") int version) {
return producerTemplate.requestBodyAndHeaders(
"direct:getSecretVersion", "",
Map.of(CyberArkVaultConstants.SECRET_VERSION, version),
String.class);
}

@Path("/propertyPlaceholder")
@GET
@Produces(MediaType.TEXT_PLAIN)
public String propertyPlaceholder() {
return producerTemplate.requestBody("direct:propertyPlaceholder", "", String.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ void testRetrieveSecret() {
//create secret
RestAssured.given()
.body(secret)
.post("/cyberark-vault/createSecret/false")
.post("/cyberark-vault/createSecret/false/BotApp/secretVar")
.then()
.statusCode(500)
.body(containsString("403"));

//create secret
RestAssured.given()
.body(secret)
.post("/cyberark-vault/createSecret/true")
.post("/cyberark-vault/createSecret/true/BotApp/secretVar")
.then()
.statusCode(200);

Expand All @@ -60,4 +60,68 @@ void testRetrieveSecret() {
.statusCode(200)
.body(is(secret));
}

@Test
void testPropertyPlaceholder() {
String secret = UUID.randomUUID().toString();

RestAssured.given()
.body(secret)
.post("/cyberark-vault/createSecret/true/BotApp/secretVar")
.then()
.statusCode(200);

RestAssured
.get("/cyberark-vault/propertyPlaceholder")
.then()
.statusCode(200)
.body(is(secret));
}

@Test
void testGetSecretByHeader() {
String secret = UUID.randomUUID().toString();

RestAssured.given()
.body(secret)
.post("/cyberark-vault/createSecret/true/BotApp/secretVar")
.then()
.statusCode(200);

RestAssured
.get("/cyberark-vault/getSecretByHeader/BotApp/secretVar")
.then()
.statusCode(200)
.body(is(secret));
}

@Test
void testGetSecretVersion() {
String secretV1 = UUID.randomUUID().toString();
String secretV2 = UUID.randomUUID().toString();

RestAssured.given()
.body(secretV1)
.post("/cyberark-vault/createSecret/true/BotApp/versionVar")
.then()
.statusCode(200);

RestAssured.given()
.body(secretV2)
.post("/cyberark-vault/createSecret/true/BotApp/versionVar")
.then()
.statusCode(200);

RestAssured
.get("/cyberark-vault/getSecretVersion/1")
.then()
.statusCode(200)
.body(is(secretV1));

RestAssured
.get("/cyberark-vault/getSecretVersion/2")
.then()
.statusCode(200)
.body(is(secretV2));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,15 @@ public Map<String, String> start() {
throw new RuntimeException("Failed to start Conjur test environment", e);
}

String conjurUrl = "http://localhost:" + conjurContainer.getMappedPort(80);

result.put("conjur.account", CONJUR_ACCOUNT);
result.put("conjur.url", "http://localhost:" + conjurContainer.getMappedPort(80));
result.put("conjur.url", conjurUrl);

result.put("camel.vault.cyberark.url", conjurUrl);
result.put("camel.vault.cyberark.account", CONJUR_ACCOUNT);
result.put("camel.vault.cyberark.username", result.get("conjur.read.username"));
result.put("camel.vault.cyberark.apiKey", result.get("conjur.read.apiKey"));

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
- !user Dave
- !host myDemoApp
- !variable secretVar
- !variable versionVar
- !permit
# Give permissions to the human user to update the secret and fetch the secret.
role: !user Dave
Expand All @@ -32,3 +33,11 @@
role: !host myDemoApp
privileges: [read, execute]
resource: !variable secretVar
- !permit
role: !user Dave
privileges: [read, update, execute]
resource: !variable versionVar
- !permit
role: !host myDemoApp
privileges: [read, execute]
resource: !variable versionVar
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@
<couchdb.container.image>mirror.gcr.io/couchdb:3.5.0</couchdb.container.image>
<cyberark-conjur.container.image>mirror.gcr.io/cyberark/conjur:1.24.0</cyberark-conjur.container.image>
<cyberark-conjur-cli.container.image>mirror.gcr.io/cyberark/conjur-cli:9</cyberark-conjur-cli.container.image>
<cyberark-nginx.container.image>mirror.gcr.io/nginx:1.29.4-alpine3.23-perl</cyberark-nginx.container.image>
<cyberark-nginx.container.image>mirror.gcr.io/nginx:1.30.3-alpine3.23-perl</cyberark-nginx.container.image>
<db2.container.image>icr.io/db2_community/db2:12.1.0.0</db2.container.image>
<docling.container.image>quay.io/docling-project/docling-serve:v1.9.0</docling.container.image>
<eclipse-mosquitto.container.image>mirror.gcr.io/eclipse-mosquitto:2.0.18</eclipse-mosquitto.container.image>
Expand Down
Loading