package com.lordofthejars.nosqlunit.vault;
import com.lordofthejars.nosqlunit.core.FailureHandler;
import org.yaml.snakeyaml.Yaml;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import static com.lordofthejars.nosqlunit.util.DeepEquals.deepEquals;
public class VaultAssertion {
private static final String TOKENS = "tokens";
public static void strictAssertEquals(final InputStream dataset, final VaultConnection vault) {
final Yaml yaml = new Yaml();
final Object load = yaml.load(dataset);
if (areOnlySecrets(load)) {
final List<Map<String, Map<String, Object>>> secrets = (List) load;
checkSecretsRegisteredByTokens(secrets, vault);
assertSecrets(secrets, vault);
}
}
private static void checkSecretsRegisteredByTokens(List<Map<String, Map<String, Object>>> data, VaultConnection vault) {
final Optional<Map.Entry<String, Map<String, Object>>> tokens = data.stream()
.flatMap(e -> e.entrySet().stream())
.filter(e -> TOKENS.equals(e.getKey()))
.findFirst();
if (tokens.isPresent()) {
final List<Map<String, Object>> tokenDefinitions = (List<Map<String, Object>>) tokens.get().getValue();
for (final Map<String, Object> tokenDefinition : tokenDefinitions) {
if (tokenDefinition.containsKey("uuid")) {
final String uuid = asString(tokenDefinition, "uuid");
if (tokenDefinition.containsKey("secrets")) {
List<Map<String, Map<String, Object>>> secrets = (List<Map<String, Map<String, Object>>>) tokenDefinition.get("secrets");
try {
vault.updateToken(uuid);
assertSecrets(secrets, vault);
} finally {
vault.reconnectToOriginal();
}
}
}
}
}
}
private static void assertSecrets(List<Map<String, Map<String, Object>>> expectedSecrets, VaultConnection vaultConnection) {
for (Map<String, Map<String, Object>> secret : expectedSecrets) {
final Set<Map.Entry<String, Map<String, Object>>> entries = secret.entrySet();
for (Map.Entry<String, Map<String, Object>> entry : entries) {
String backend = entry.getKey();
if (! TOKENS.equals(backend)) {
final Map<String, String> real = vaultConnection.readLogical(backend);
final Map<String, String> expected = toStringMap(entry.getValue());
if (!deepEquals(real, expected)) {
throw FailureHandler.createFailure(
"Expected element # %s # is not found but # %s # was found.",
expected, real);
}
}
}
}
}
private static boolean areOnlySecrets(Object load) {
return load instanceof List;
}
private static String asString(Map<String, Object> elements, String key) {
if (elements.containsKey(key)) {
return (String) elements.get(key);
}
return null;
}
private static Map<String, String> toStringMap(Map<String, Object> elements) {
return elements.entrySet()
.stream()
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().toString()));
}
}