forked from smallrye/smallrye-config
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
269 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<artifactId>smallrye-config-parent</artifactId> | ||
<groupId>io.smallrye.config</groupId> | ||
<version>2.12.2-SNAPSHOT</version> | ||
<relativePath>../../pom.xml</relativePath> | ||
</parent> | ||
|
||
<artifactId>smallrye-config-source-keystore</artifactId> | ||
|
||
<name>SmallRye: MicroProfile Config Source - KeyStore</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>io.smallrye.config</groupId> | ||
<artifactId>smallrye-config</artifactId> | ||
</dependency> | ||
|
||
<!-- Test --> | ||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>io.smallrye.testing</groupId> | ||
<artifactId>smallrye-testing-utilities</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>jakarta.annotation</groupId> | ||
<artifactId>jakarta.annotation-api</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
31 changes: 31 additions & 0 deletions
31
sources/keystore/src/main/java/io/smallrye/config/source/keystore/KeyStoreConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package io.smallrye.config.source.keystore; | ||
|
||
import io.smallrye.config.ConfigMapping; | ||
import io.smallrye.config.WithDefault; | ||
import io.smallrye.config.WithParentName; | ||
|
||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
@ConfigMapping(prefix = "io.smallrye.config.source.keystore") | ||
public interface KeyStoreConfig { | ||
@WithParentName | ||
Map<String, KeyStore> keystores(); | ||
|
||
interface KeyStore { | ||
String path(); | ||
|
||
@WithDefault("PKCS12") | ||
String type(); | ||
|
||
String password(); | ||
|
||
Map<String, Alias> aliases(); | ||
|
||
interface Alias { | ||
Optional<String> name(); | ||
|
||
Optional<String> password(); | ||
} | ||
} | ||
} |
161 changes: 161 additions & 0 deletions
161
...eystore/src/main/java/io/smallrye/config/source/keystore/KeyStoreConfigSourceFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
package io.smallrye.config.source.keystore; | ||
|
||
import io.smallrye.config.AbstractLocationConfigSourceFactory; | ||
import io.smallrye.config.ConfigSourceContext; | ||
import io.smallrye.config.ConfigSourceFactory; | ||
import io.smallrye.config.ConfigValue; | ||
import io.smallrye.config.ConfigurableConfigSource; | ||
import io.smallrye.config.PropertiesConfigSource; | ||
import io.smallrye.config.SmallRyeConfig; | ||
import io.smallrye.config.SmallRyeConfigBuilder; | ||
import io.smallrye.config.source.keystore.KeyStoreConfig.KeyStore.Alias; | ||
import org.eclipse.microprofile.config.spi.ConfigSource; | ||
|
||
import java.io.IOException; | ||
import java.net.URL; | ||
import java.security.Key; | ||
import java.security.KeyStore; | ||
import java.security.KeyStoreException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.security.UnrecoverableKeyException; | ||
import java.security.cert.CertificateException; | ||
import java.util.ArrayList; | ||
import java.util.Enumeration; | ||
import java.util.HashMap; | ||
import java.util.HashSet; | ||
import java.util.Iterator; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
|
||
import static java.nio.charset.StandardCharsets.UTF_8; | ||
|
||
public class KeyStoreConfigSourceFactory implements ConfigSourceFactory { | ||
@Override | ||
public Iterable<ConfigSource> getConfigSources(final ConfigSourceContext context) { | ||
SmallRyeConfig config = new SmallRyeConfigBuilder() | ||
.withSources(new ContextConfigSource(context)) | ||
.withMapping(KeyStoreConfig.class) | ||
.build(); | ||
|
||
KeyStoreConfig keyStoreConfig = config.getConfigMapping(KeyStoreConfig.class); | ||
|
||
List<ConfigSource> keyStoreSources = new ArrayList<>(); | ||
for (Map.Entry<String, KeyStoreConfig.KeyStore> keyStoreEntry : keyStoreConfig.keystores().entrySet()) { | ||
KeyStoreConfig.KeyStore keyStore = keyStoreEntry.getValue(); | ||
|
||
keyStoreSources.add(new ConfigurableConfigSource(new AbstractLocationConfigSourceFactory() { | ||
@Override | ||
protected String[] getFileExtensions() { | ||
return new String[0]; | ||
} | ||
|
||
@Override | ||
protected ConfigSource loadConfigSource(final URL url, final int ordinal) { | ||
return new UrlKeyStoreConfigSource(url, ordinal).loadKeyStore(keyStore); | ||
} | ||
|
||
@Override | ||
public Iterable<ConfigSource> getConfigSources(final ConfigSourceContext context) { | ||
return loadConfigSources(keyStore.path(), 100); | ||
} | ||
})); | ||
} | ||
|
||
return keyStoreSources; | ||
} | ||
|
||
private static class ContextConfigSource implements ConfigSource { | ||
private final ConfigSourceContext context; | ||
|
||
public ContextConfigSource(final ConfigSourceContext context) { | ||
this.context = context; | ||
} | ||
|
||
@Override | ||
public Set<String> getPropertyNames() { | ||
Set<String> names = new HashSet<>(); | ||
Iterator<String> namesIterator = context.iterateNames(); | ||
while (namesIterator.hasNext()) { | ||
names.add(namesIterator.next()); | ||
} | ||
return names; | ||
} | ||
|
||
@Override | ||
public String getValue(final String propertyName) { | ||
ConfigValue value = context.getValue(propertyName); | ||
return value != null && value.getValue() != null ? value.getValue() : null; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return ContextConfigSource.class.getName(); | ||
} | ||
} | ||
|
||
private static class UrlKeyStoreConfigSource implements ConfigSource { | ||
private final URL url; | ||
private final int ordinal; | ||
|
||
UrlKeyStoreConfigSource(final URL url, final int ordinal) { | ||
this.url = url; | ||
this.ordinal = ordinal; | ||
} | ||
|
||
ConfigSource loadKeyStore(KeyStoreConfig.KeyStore keyStoreConfig) { | ||
try { | ||
KeyStore keyStore = KeyStore.getInstance(keyStoreConfig.type()); | ||
keyStore.load(url.openStream(), keyStoreConfig.password().toCharArray()); | ||
|
||
Map<String, String> properties = new HashMap<>(); | ||
Enumeration<String> aliases = keyStore.aliases(); | ||
while (aliases.hasMoreElements()) { | ||
String alias = aliases.nextElement(); | ||
Alias aliasConfig = keyStoreConfig.aliases().getOrDefault(alias, new Alias() { | ||
@Override | ||
public Optional<String> name() { | ||
return Optional.of(alias); | ||
} | ||
|
||
@Override | ||
public Optional<String> password() { | ||
return Optional.of(keyStoreConfig.password()); | ||
} | ||
}); | ||
|
||
if (keyStore.isKeyEntry(alias)) { | ||
Key key = keyStore.getKey(alias, aliasConfig.password().orElse(keyStoreConfig.password()).toCharArray()); | ||
properties.put(aliasConfig.name().orElse(alias), new String(key.getEncoded(), UTF_8)); | ||
} else if (keyStore.isCertificateEntry(alias)) { | ||
// TODO | ||
} | ||
} | ||
return new PropertiesConfigSource(properties, this.getName(), this.getOrdinal()); | ||
} catch (KeyStoreException | CertificateException | IOException | NoSuchAlgorithmException | UnrecoverableKeyException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public int getOrdinal() { | ||
return ordinal; | ||
} | ||
|
||
@Override | ||
public Set<String> getPropertyNames() { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
@Override | ||
public String getValue(final String propertyName) { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return "KeyStoreConfigSource[source=" + url.toString() + "]"; | ||
} | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
sources/keystore/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceFactory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
io.smallrye.config.source.keystore.KeyStoreConfigSourceFactory |
31 changes: 31 additions & 0 deletions
31
...s/keystore/src/test/java/io/smallrye/config/source/keystore/KeyStoreConfigSourceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package io.smallrye.config.source.keystore; | ||
|
||
import io.smallrye.config.ConfigValue; | ||
import io.smallrye.config.PropertiesConfigSource; | ||
import io.smallrye.config.SmallRyeConfig; | ||
import io.smallrye.config.SmallRyeConfigBuilder; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
|
||
class KeyStoreConfigSourceTest { | ||
@Test | ||
void keystore() throws Exception { | ||
Map<String, String> properties = new HashMap<>(); | ||
// keytool -importpass -alias my.secret -keystore keystore -storepass secret -storetype PKCS12 -v | ||
properties.put("io.smallrye.config.source.keystore.test.path", "keystore"); | ||
properties.put("io.smallrye.config.source.keystore.test.password", "secret"); | ||
|
||
SmallRyeConfig config = new SmallRyeConfigBuilder() | ||
.addDefaultInterceptors() | ||
.addDiscoveredSources() | ||
.withSources(new PropertiesConfigSource(properties, "", 0)) | ||
.build(); | ||
|
||
ConfigValue secret = config.getConfigValue("my.secret"); | ||
assertEquals("secret", secret.getValue()); | ||
} | ||
} |
Binary file not shown.