Skip to content

Commit f77eb4e

Browse files
committed
server: fix usernameSignature generation
1 parent 2ab627f commit f77eb4e

File tree

5 files changed

+61
-9
lines changed

5 files changed

+61
-9
lines changed

it/runtime-v2/src/test/java/com/walmartlabs/concord/it/runtime/v2/ConcordConfiguration.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
import java.nio.file.Files;
2828
import java.nio.file.Path;
2929
import java.nio.file.Paths;
30+
import java.security.KeyPair;
31+
import java.security.KeyPairGenerator;
32+
import java.util.Base64;
3033

3134
public final class ConcordConfiguration {
3235

@@ -44,6 +47,8 @@ public static Path sharedDir() {
4447
throw new RuntimeException(e);
4548
}
4649
}
50+
51+
writePrivateKey(sharedDir.resolve("signing.pem"));
4752
}
4853

4954
public static ConcordRule configure() {
@@ -66,6 +71,9 @@ public static ConcordRule configure() {
6671
pollDelay = "250 milliseconds"
6772
}
6873
}
74+
process {
75+
signingKeyPath = "%%sharedDir%%/signing.pem"
76+
}
6977
}
7078
concord-agent {
7179
dependencyResolveTimeout = "30 seconds"
@@ -75,7 +83,7 @@ public static ConcordRule configure() {
7583
enabled = true
7684
}
7785
}
78-
""");
86+
""".replaceAll("%%sharedDir%%", sharedDir().toString()));
7987

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

117+
private static Path writePrivateKey(Path targetFile) {
118+
try {
119+
return Files.writeString(targetFile, generatePkcs8PemPrivateKey());
120+
} catch (Exception e) {
121+
throw new IllegalStateException("Error writing server username signing key.", e);
122+
}
123+
}
124+
125+
private static String generatePkcs8PemPrivateKey() throws Exception {
126+
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
127+
keyGen.initialize(2048);
128+
KeyPair pair = keyGen.generateKeyPair();
129+
byte[] pkcs8 = pair.getPrivate().getEncoded();
130+
String base64 = Base64.getMimeEncoder(64, "\n".getBytes()).encodeToString(pkcs8);
131+
return "-----BEGIN PRIVATE KEY-----\n" + base64 + "\n-----END PRIVATE KEY-----";
132+
}
133+
109134
private ConcordConfiguration() {
110135
}
111136
}

it/runtime-v2/src/test/java/com/walmartlabs/concord/it/runtime/v2/ProcessIT.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,23 @@ public void testArgs() throws Exception {
6161
proc.assertLog(".*Hello, Concord!.*");
6262
}
6363

64+
/**
65+
* Username signature generation.
66+
*/
67+
@Test
68+
public void testUsernameSignature() throws Exception {
69+
Payload payload = new Payload()
70+
.archive(resource("usernameSignature"));
71+
72+
ConcordProcess proc = concord.processes().start(payload);
73+
expectStatus(proc, ProcessEntry.StatusEnum.FINISHED);
74+
75+
// ---
76+
77+
proc.assertNoLog(".*signature: null.*");
78+
proc.assertLog(".*signature: (?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?\\..*");
79+
}
80+
6481
/**
6582
* Groovy script execution.
6683
*/
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
configuration:
2+
runtime: "concord-v2"
3+
4+
flows:
5+
default:
6+
- log: "signature: ${initiator.usernameSignature == null ? 'null' : initiator.usernameSignature}."

server/impl/src/main/java/com/walmartlabs/concord/server/process/pipelines/processors/UserInfoProcessor.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
*/
2222

2323
import com.fasterxml.jackson.databind.ObjectMapper;
24-
import com.fasterxml.jackson.databind.node.ObjectNode;
25-
import com.fasterxml.jackson.databind.node.TextNode;
2624
import com.walmartlabs.concord.server.process.Payload;
2725
import com.walmartlabs.concord.server.process.pipelines.processors.signing.Signing;
2826
import com.walmartlabs.concord.server.sdk.ConcordApplicationException;
@@ -60,11 +58,14 @@ public UserInfoProcessor(String key,
6058
public Payload process(Chain chain, Payload payload) {
6159
var info = userManager.getCurrentUserInfo();
6260

63-
var result = objectMapper.convertValue(info, ObjectNode.class);
6461
if (signing.isEnabled()) {
65-
Optional.ofNullable(info.username())
66-
.map(this::sign)
67-
.ifPresent(signature -> result.set("usernameSignature", signature));
62+
var signature = Optional.ofNullable(info.username())
63+
.map(this::sign);
64+
65+
info = signature.isEmpty() ? info : UserInfoProvider.UserInfo.builder()
66+
.from(info)
67+
.usernameSignature(signature.get())
68+
.build();
6869
}
6970

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

78-
private TextNode sign(String username) {
79+
private String sign(String username) {
7980
try {
80-
return TextNode.valueOf(signing.sign(username));
81+
return signing.sign(username);
8182
} catch (Exception e) {
8283
throw new ConcordApplicationException("Error while singing process data: " + e.getMessage(), e);
8384
}

server/impl/src/main/java/com/walmartlabs/concord/server/user/UserInfoProvider.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,8 @@ static ImmutableUserInfo.Builder builder() {
7777

7878
@Nullable
7979
Map<String, Object> attributes();
80+
81+
@Nullable
82+
String usernameSignature();
8083
}
8184
}

0 commit comments

Comments
 (0)