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 @@ -27,6 +27,9 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.util.Base64;

public final class ConcordConfiguration {

Expand All @@ -44,6 +47,8 @@ public static Path sharedDir() {
throw new RuntimeException(e);
}
}

writePrivateKey(sharedDir.resolve("signing.pem"));
}

public static ConcordRule configure() {
Expand All @@ -66,6 +71,9 @@ public static ConcordRule configure() {
pollDelay = "250 milliseconds"
}
}
process {
signingKeyPath = "%%sharedDir%%/signing.pem"
}
}
concord-agent {
dependencyResolveTimeout = "30 seconds"
Expand All @@ -75,7 +83,7 @@ public static ConcordRule configure() {
enabled = true
}
}
""");
""".replaceAll("%%sharedDir%%", sharedDir().toString()));

boolean localMode = Boolean.parseBoolean(System.getProperty("it.local.mode"));
if (localMode) {
Expand Down Expand Up @@ -106,6 +114,23 @@ public static String getServerUrlForAgent(ConcordRule concord) {
}
}

private static Path writePrivateKey(Path targetFile) {
try {
return Files.writeString(targetFile, generatePkcs8PemPrivateKey());
} catch (Exception e) {
throw new IllegalStateException("Error writing server username signing key.", e);
}
}

private static String generatePkcs8PemPrivateKey() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair pair = keyGen.generateKeyPair();
byte[] pkcs8 = pair.getPrivate().getEncoded();
String base64 = Base64.getMimeEncoder(64, "\n".getBytes()).encodeToString(pkcs8);
return "-----BEGIN PRIVATE KEY-----\n" + base64 + "\n-----END PRIVATE KEY-----";
}

private ConcordConfiguration() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,23 @@ public void testArgs() throws Exception {
proc.assertLog(".*Hello, Concord!.*");
}

/**
* Username signature generation.
*/
@Test
public void testUsernameSignature() throws Exception {
Payload payload = new Payload()
.archive(resource("usernameSignature"));

ConcordProcess proc = concord.processes().start(payload);
expectStatus(proc, ProcessEntry.StatusEnum.FINISHED);

// ---

proc.assertNoLog(".*signature: null.*");
proc.assertLog(".*signature: (?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?\\..*");
}

/**
* Groovy script execution.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
configuration:
runtime: "concord-v2"

flows:
default:
- log: "signature: ${initiator.usernameSignature == null ? 'null' : initiator.usernameSignature}."
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
*/

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.walmartlabs.concord.server.process.Payload;
import com.walmartlabs.concord.server.process.pipelines.processors.signing.Signing;
import com.walmartlabs.concord.server.sdk.ConcordApplicationException;
Expand Down Expand Up @@ -60,11 +58,14 @@ public UserInfoProcessor(String key,
public Payload process(Chain chain, Payload payload) {
var info = userManager.getCurrentUserInfo();

var result = objectMapper.convertValue(info, ObjectNode.class);
if (signing.isEnabled()) {
Optional.ofNullable(info.username())
.map(this::sign)
.ifPresent(signature -> result.set("usernameSignature", signature));
var signature = Optional.ofNullable(info.username())
.map(this::sign);

info = signature.isEmpty() ? info : UserInfoProvider.UserInfo.builder()
.from(info)
.usernameSignature(signature.get())
.build();
}

Map<String, UserInfoProvider.UserInfo> m = new HashMap<>();
Expand All @@ -75,9 +76,9 @@ public Payload process(Chain chain, Payload payload) {
return chain.process(payload);
}

private TextNode sign(String username) {
private String sign(String username) {
try {
return TextNode.valueOf(signing.sign(username));
return signing.sign(username);
} catch (Exception e) {
throw new ConcordApplicationException("Error while singing process data: " + e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,8 @@ static ImmutableUserInfo.Builder builder() {

@Nullable
Map<String, Object> attributes();

@Nullable
String usernameSignature();
}
}