001package com.quorum.tessera.config.migration;
002
003import com.moandjiezana.toml.Toml;
004import com.quorum.tessera.config.ArgonOptions;
005import com.quorum.tessera.config.SslAuthenticationMode;
006import com.quorum.tessera.config.builder.ConfigBuilder;
007import com.quorum.tessera.config.builder.JdbcConfigFactory;
008import com.quorum.tessera.config.builder.KeyDataBuilder;
009import com.quorum.tessera.config.builder.SslTrustModeFactory;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013import java.io.InputStream;
014import java.net.MalformedURLException;
015import java.net.URL;
016import java.util.List;
017import java.util.Objects;
018import java.util.Optional;
019
020import static java.util.Collections.emptyList;
021
022public class TomlConfigFactory {
023
024    private static final Logger LOGGER = LoggerFactory.getLogger(TomlConfigFactory.class);
025
026    public ConfigBuilder create(InputStream configData, ArgonOptions options, String... filenames) {
027        Objects.requireNonNull(configData, "No config data provided. ");
028        if (filenames.length != 0) {
029            throw new UnsupportedOperationException("keyConfigData arg is not implemented for TomlConfigFactory");
030        }
031
032        Toml toml = new Toml().read(configData);
033        toml.toMap().forEach((key, value) -> LOGGER.debug("Found entry in toml file : {} {}", key, value));
034
035        final String urlWithoutPort = Optional
036            .ofNullable(toml.getString("url"))
037            .map(url -> {
038                try {
039                    return new URL(url);
040                } catch (final MalformedURLException e) {
041                    throw new RuntimeException("Bad server url given: " + e.getMessage());
042                }
043            }).map(uri -> uri.getProtocol() + "://" + uri.getHost())
044            .orElse(null);
045
046        final Integer port = Optional.ofNullable(toml.getLong("port")).map(Long::intValue).orElse(0);
047
048        final String workdir = toml.getString("workdir", "");
049        final String socket = toml.getString("socket");
050
051        final String tls = toml.getString("tls", "off").toUpperCase();
052
053        final List<String> othernodes = toml.getList("othernodes", emptyList());
054
055        final List<String> alwaysSendToKeyPaths = toml.getList("alwayssendto", emptyList());
056
057        final String storage = toml.getString("storage", "memory");
058
059        final List<String> ipwhitelist = toml.getList("ipwhitelist", emptyList());
060        final boolean useWhiteList = !ipwhitelist.isEmpty();
061
062        // Server side
063        final String tlsservertrust = toml.getString("tlsservertrust", "tofu");
064        final Optional<String> tlsserverkey = Optional.ofNullable(toml.getString("tlsserverkey"));
065        final Optional<String> tlsservercert = Optional.ofNullable(toml.getString("tlsservercert"));
066        final Optional<List<String>> tlsserverchainnames = Optional.of(toml.getList("tlsserverchain", emptyList()));
067        final Optional<String> tlsknownclients = Optional.ofNullable(toml.getString("tlsknownclients"));
068
069        // Client side
070        final String tlsclienttrust = toml.getString("tlsclienttrust", "tofu");
071        final Optional<String> tlsclientkey = Optional.ofNullable(toml.getString("tlsclientkey"));
072        final Optional<String> tlsclientcert = Optional.ofNullable(toml.getString("tlsclientcert"));
073        final Optional<List<String>> tlsclientchainnames = Optional.of(toml.getList("tlsclientchain", emptyList()));
074        final Optional<String> tlsknownservers = Optional.ofNullable(toml.getString("tlsknownservers"));
075
076        ConfigBuilder configBuilder = ConfigBuilder.create()
077            .serverPort(port)
078            .serverHostname(urlWithoutPort)
079            .unixSocketFile(socket)
080            .sslAuthenticationMode(SslAuthenticationMode.valueOf(tls))
081            .sslServerTrustMode(SslTrustModeFactory.resolveByLegacyValue(tlsservertrust))
082            .sslClientTrustMode(SslTrustModeFactory.resolveByLegacyValue(tlsclienttrust))
083            .peers(othernodes)
084            .alwaysSendTo(alwaysSendToKeyPaths)
085            .useWhiteList(useWhiteList)
086            .workdir(workdir);
087
088        tlsserverkey.ifPresent(configBuilder::sslServerTlsKeyPath);
089        tlsservercert.ifPresent(configBuilder::sslServerTlsCertificatePath);
090        tlsserverchainnames.ifPresent(configBuilder::sslServerTrustCertificates);
091        tlsknownclients.ifPresent(configBuilder::sslKnownClientsFile);
092        tlsclientkey.ifPresent(configBuilder::sslClientTlsKeyPath);
093        tlsclientcert.ifPresent(configBuilder::sslClientTlsCertificatePath);
094        tlsclientchainnames.ifPresent(configBuilder::sslClientTrustCertificates);
095        tlsknownservers.ifPresent(configBuilder::sslKnownServersFile);
096
097        Optional.ofNullable(storage)
098            .map(JdbcConfigFactory::fromLegacyStorageString)
099            .ifPresent(configBuilder::jdbcConfig);
100
101        return configBuilder;
102    }
103
104    KeyDataBuilder createKeyDataBuilder(InputStream configData) {
105        final Toml toml = new Toml().read(configData);
106
107        final List<String> publicKeyList = toml.getList("publickeys", emptyList());
108
109        final List<String> privateKeyList = toml.getList("privatekeys", emptyList());
110
111        final String pwd = toml.getString("passwords");
112
113        final String workdir = toml.getString("workdir");
114
115        return KeyDataBuilder.create()
116            .withPublicKeys(publicKeyList)
117            .withPrivateKeys(privateKeyList)
118            .withPrivateKeyPasswordFile(pwd)
119            .withWorkingDirectory(workdir);
120    }
121}