Skip to content

Commit ca1acfd

Browse files
authored
Merge pull request #268 from adrienlauer/truststore
Allow to configure truststore separately
2 parents 214e13c + bb93f74 commit ca1acfd

File tree

86 files changed

+954
-733
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+954
-733
lines changed

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
# Version 3.8.6 (2019-07-30)
1+
# Version 3.9.0 (2019-08-12)
22

33
* [new] Introduce the `diag` tool to manually write a diagnostic report to standard output or in a file.
44
* [new] Enable configuration of Undertow error pages for specific HTTP codes or exceptions as well as a default error page (`web.server.errorPages` config).
5+
* [new] SSL truststore can be configured separately from the master keystore (if no configuration it will default to the Java default truststore).
6+
* [new] A custom X509KeyManager can now be configured to allow control of the chosen key material during SSL handshake.
7+
* [brk] Plain file X509 certificates (outside a keystore) can no longer be configured as it is less secure and not so useful.
58

69
# Version 3.8.5 (2019-03-22)
710

cli/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<parent>
1515
<groupId>org.seedstack.seed</groupId>
1616
<artifactId>seed</artifactId>
17-
<version>3.8.6-SNAPSHOT</version>
17+
<version>3.9.0-SNAPSHOT</version>
1818
</parent>
1919

2020
<artifactId>seed-cli</artifactId>

core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<parent>
1515
<groupId>org.seedstack.seed</groupId>
1616
<artifactId>seed</artifactId>
17-
<version>3.8.6-SNAPSHOT</version>
17+
<version>3.9.0-SNAPSHOT</version>
1818
</parent>
1919

2020
<artifactId>seed-core</artifactId>

core/src/main/java/org/seedstack/seed/core/internal/BindingDefinition.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class BindingDefinition<T> extends Bindable<T> {
2323
this.from = from;
2424
}
2525

26-
public void apply(Binder binder) {
26+
void apply(Binder binder) {
2727
if (from != null) {
2828
AnnotatedBindingBuilder<T> bind = binder.bind(from);
2929
if (!from.isAssignableFrom(target)) {

core/src/main/java/org/seedstack/seed/core/internal/CoreModule.java

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,19 @@
1212
import com.google.inject.Module;
1313
import java.util.Collection;
1414
import java.util.Set;
15-
import org.slf4j.Logger;
16-
import org.slf4j.LoggerFactory;
1715

1816
class CoreModule extends AbstractModule {
19-
private final Logger LOGGER = LoggerFactory.getLogger(CoreModule.class);
2017
private final Collection<? extends Module> modules;
2118
private final Set<Bindable> bindings;
22-
private final boolean overriding;
2319

24-
CoreModule(Collection<? extends Module> modules, Set<Bindable> bindings, boolean overriding) {
20+
CoreModule(Collection<? extends Module> modules, Set<Bindable> bindings) {
2521
this.modules = modules;
2622
this.bindings = bindings;
27-
this.overriding = overriding;
2823
}
2924

3025
@Override
3126
protected void configure() {
32-
modules.forEach(module -> {
33-
LOGGER.trace("Installing module {}", module.getClass().getName());
34-
install(module);
35-
});
36-
LOGGER.debug("Installed {}{} module(s)", modules.size(), overriding ? " overriding" : "");
37-
27+
modules.forEach(this::install);
3828
bindings.forEach(binding -> binding.apply(binder()));
39-
LOGGER.debug("Created {}{} binding(s)", bindings.size(), overriding ? " overriding" : "");
4029
}
4130
}

core/src/main/java/org/seedstack/seed/core/internal/CorePlugin.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121
import org.kametic.specifications.Specification;
2222
import org.seedstack.seed.core.internal.utils.SpecificationBuilder;
2323
import org.seedstack.shed.reflect.Classes;
24+
import org.slf4j.Logger;
25+
import org.slf4j.LoggerFactory;
2426

2527
/**
2628
* Core plugin that configures base package roots and detects diagnostic collectors, dependency providers, Guice modules
2729
* and configuration files.
2830
*/
2931
public class CorePlugin extends AbstractSeedPlugin {
32+
private static final Logger LOGGER = LoggerFactory.getLogger(CorePlugin.class);
3033
static final String AUTODETECT_MODULES_KERNEL_PARAM = "seedstack.autodetectModules";
3134
static final String AUTODETECT_BINDINGS_KERNEL_PARAM = "seedstack.autodetectBindings";
3235
private static final String SEEDSTACK_PACKAGE = "org.seedstack";
@@ -82,8 +85,10 @@ private void detectModules(InitContext initContext) {
8285
.forEach(candidate -> InstallResolver.INSTANCE.apply(candidate).ifPresent(annotation -> {
8386
if (annotation.override()) {
8487
overridingModules.add((Class<? extends Module>) candidate);
88+
LOGGER.debug("Overriding module {} detected", candidate.getName());
8589
} else {
8690
modules.add((Class<? extends Module>) candidate);
91+
LOGGER.debug("Module {} detected", candidate.getName());
8792
}
8893
}));
8994
}
@@ -97,11 +102,13 @@ private void detectBindings(InitContext initContext) {
97102
candidate,
98103
(Class<Object>) (annotation.from() == Object.class ? null : annotation.from())
99104
));
105+
LOGGER.debug("Overriding explicit binding for {} detected", candidate.getName());
100106
} else {
101107
bindings.add(new BindingDefinition<>(
102108
candidate,
103109
(Class<Object>) (annotation.from() == Object.class ? null : annotation.from())
104110
));
111+
LOGGER.debug("Explicit binding for {} detected", candidate.getName());
105112
}
106113
}));
107114
}
@@ -122,17 +129,15 @@ private void detectProviders(InitContext initContext) {
122129
public Object nativeUnitModule() {
123130
return new CoreModule(
124131
modules.stream().map(Classes::instantiateDefault).collect(Collectors.toSet()),
125-
bindings,
126-
false
132+
bindings
127133
);
128134
}
129135

130136
@Override
131137
public Object nativeOverridingUnitModule() {
132138
return new CoreModule(
133139
overridingModules.stream().map(Classes::instantiateDefault).collect(Collectors.toSet()),
134-
overridingBindings,
135-
true
140+
overridingBindings
136141
);
137142
}
138143
}

core/src/main/java/org/seedstack/seed/core/internal/command/CommandPlugin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* License, v. 2.0. If a copy of the MPL was not distributed with this
66
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
77
*/
8+
89
package org.seedstack.seed.core.internal.command;
910

1011
import static org.seedstack.shed.reflect.ReflectUtils.makeAccessible;
@@ -66,12 +67,11 @@ public InitState initialize(InitContext initContext) {
6667
}
6768

6869
commandDefinitions.put(commandDefinition.getQualifiedName(), commandDefinition);
69-
LOGGER.trace("Command {} registered with {}", commandDefinition.getQualifiedName(),
70+
LOGGER.debug("Command {} detected, implemented in {}", commandDefinition.getQualifiedName(),
7071
commandDefinition.getCommandActionClass().getCanonicalName());
7172
}
7273
}
7374
}
74-
LOGGER.debug("Registered " + commandDefinitions.size() + " command(s)");
7575

7676
return InitState.INITIALIZED;
7777
}

core/src/main/java/org/seedstack/seed/core/internal/configuration/ConfigurationPlugin.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ public Collection<ClasspathScanRequest> classpathScanRequests() {
103103
@SuppressWarnings("unchecked")
104104
@Override
105105
public InitState init(InitContext initContext) {
106+
Set<String> activeProfiles = ProfileProcessor.activeProfiles();
107+
if (activeProfiles.isEmpty()) {
108+
LOGGER.info("No configuration profile is active");
109+
} else {
110+
LOGGER.info("Active configuration profile(s): {}", String.join(", ", activeProfiles));
111+
}
112+
106113
detectKernelParamConfig(initContext);
107114
detectConfigurationFiles(initContext);
108115

core/src/main/java/org/seedstack/seed/core/internal/configuration/ProfileProcessor.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* License, v. 2.0. If a copy of the MPL was not distributed with this
66
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
77
*/
8+
89
package org.seedstack.seed.core.internal.configuration;
910

1011
import com.google.common.base.Strings;
@@ -29,7 +30,7 @@ public class ProfileProcessor implements ConfigurationProcessor {
2930

3031
@Override
3132
public void process(MapNode configuration) {
32-
Set<String> activeProfiles = parseProfiles(System.getProperty(SEEDSTACK_PROFILES_PROPERTY, ""));
33+
Set<String> activeProfiles = activeProfiles();
3334
Map<MapNode, List<String>> toRemove = new HashMap<>();
3435
Map<TreeNode, Map<String, String>> moves = new HashMap<>();
3536

@@ -59,10 +60,14 @@ public void process(MapNode configuration) {
5960
}
6061
}
6162

62-
private Set<String> parseProfiles(String value) {
63+
private static Set<String> parseProfiles(String value) {
6364
return Arrays.stream(value.split(","))
6465
.map(String::trim)
6566
.filter(notNullOrEmpty)
6667
.collect(Collectors.toSet());
6768
}
69+
70+
static Set<String> activeProfiles() {
71+
return parseProfiles(System.getProperty(SEEDSTACK_PROFILES_PROPERTY, ""));
72+
}
6873
}

core/src/main/java/org/seedstack/seed/core/internal/crypto/CryptTool.java

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
* License, v. 2.0. If a copy of the MPL was not distributed with this
66
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
77
*/
8+
89
package org.seedstack.seed.core.internal.crypto;
910

10-
import com.google.common.base.Strings;
11-
import com.google.common.collect.Lists;
11+
import static org.seedstack.seed.core.internal.crypto.CryptoPlugin.getMasterEncryptionService;
12+
1213
import com.google.common.io.BaseEncoding;
1314
import io.nuun.kernel.api.plugin.InitState;
1415
import io.nuun.kernel.api.plugin.context.InitContext;
1516
import java.nio.charset.Charset;
1617
import java.security.KeyStore;
17-
import java.util.Collection;
1818
import org.seedstack.seed.SeedException;
1919
import org.seedstack.seed.cli.CliArgs;
2020
import org.seedstack.seed.cli.CliOption;
@@ -25,7 +25,7 @@
2525
public class CryptTool extends AbstractSeedTool {
2626
private EncryptionServiceFactory encryptionServiceFactory;
2727
private CryptoConfig.KeyStoreConfig masterKeyStoreConfig;
28-
@CliOption(name = "a", longName = "alias", valueCount = 1, mandatory = true)
28+
@CliOption(name = "a", longName = "alias", valueCount = 1, defaultValues = "master")
2929
private String alias;
3030
@CliOption(name = "e", longName = "encoding", valueCount = 1, defaultValues = "utf-8")
3131
private String encoding;
@@ -38,34 +38,28 @@ public String toolName() {
3838
}
3939

4040
@Override
41-
protected Collection<Class<?>> toolPlugins() {
42-
return Lists.newArrayList(CryptoPlugin.class);
41+
protected InitState initialize(InitContext initContext) {
42+
getConfiguration().getOptional(CryptoConfig.KeyStoreConfig.class, "crypto.keystores.master").ifPresent(cfg -> {
43+
KeyStore keyStore = new KeyStoreLoader().load(CryptoConfig.MASTER_KEY_STORE_NAME, cfg);
44+
encryptionServiceFactory = new EncryptionServiceFactory(keyStore);
45+
masterKeyStoreConfig = cfg;
46+
});
47+
return InitState.INITIALIZED;
4348
}
4449

4550
@Override
46-
protected InitState initialize(InitContext initContext) {
47-
CryptoConfig cryptoConfig = getConfiguration(CryptoConfig.class);
48-
masterKeyStoreConfig = cryptoConfig.masterKeyStore();
49-
if (masterKeyStoreConfig != null) {
50-
KeyStore keyStore = new KeyStoreLoader().load(CryptoConfig.MASTER_KEY_STORE_NAME, masterKeyStoreConfig);
51-
encryptionServiceFactory = new EncryptionServiceFactory(cryptoConfig, keyStore);
52-
} else {
53-
encryptionServiceFactory = null;
54-
}
55-
return InitState.INITIALIZED;
51+
public StartMode startMode() {
52+
return StartMode.MINIMAL;
5653
}
5754

5855
@Override
59-
public Integer call() throws Exception {
56+
public Integer call() {
6057
if (encryptionServiceFactory == null) {
6158
throw SeedException.createNew(CryptoErrorCode.MISSING_MASTER_KEYSTORE);
6259
}
63-
CryptoConfig.KeyStoreConfig.AliasConfig aliasConfig = masterKeyStoreConfig.getAliases().get(alias);
64-
if (aliasConfig == null || Strings.isNullOrEmpty(aliasConfig.getPassword())) {
65-
throw SeedException.createNew(CryptoErrorCode.MISSING_MASTER_KEY_PASSWORD);
66-
}
67-
EncryptionService encryptionService = encryptionServiceFactory.create(alias,
68-
aliasConfig.getPassword().toCharArray());
60+
EncryptionService encryptionService = getMasterEncryptionService(encryptionServiceFactory,
61+
masterKeyStoreConfig,
62+
alias);
6963
System.out.println(
7064
BaseEncoding.base16().encode(
7165
encryptionService.encrypt(

0 commit comments

Comments
 (0)