Export users throws Disabled option: '--users' (#32126)
Fixes #31515 Signed-off-by: Martin Bartoš <mabartos@redhat.com>
This commit is contained in:
parent
3fda9f447d
commit
94fb762f8e
4 changed files with 38 additions and 2 deletions
|
@ -29,9 +29,9 @@ import io.smallrye.config.SmallRyeConfig;
|
||||||
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
|
import org.eclipse.microprofile.config.spi.ConfigProviderResolver;
|
||||||
import org.eclipse.microprofile.config.spi.ConfigSource;
|
import org.eclipse.microprofile.config.spi.ConfigSource;
|
||||||
import org.keycloak.config.Option;
|
import org.keycloak.config.Option;
|
||||||
import org.keycloak.quarkus.runtime.Environment;
|
|
||||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper;
|
||||||
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
|
||||||
|
import org.keycloak.utils.StringUtil;
|
||||||
|
|
||||||
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
import static org.keycloak.quarkus.runtime.configuration.MicroProfileConfigProvider.NS_KEYCLOAK_PREFIX;
|
||||||
|
|
||||||
|
@ -56,6 +56,12 @@ public final class Configuration {
|
||||||
return getOptionalBooleanValue(propertyName).orElse(false);
|
return getOptionalBooleanValue(propertyName).orElse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isBlank(Option<String> option) {
|
||||||
|
return getOptionalKcValue(option.getKey())
|
||||||
|
.map(StringUtil::isBlank)
|
||||||
|
.orElse(true);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean contains(Option<?> option, String value) {
|
public static boolean contains(Option<?> option, String value) {
|
||||||
return getOptionalValue(NS_KEYCLOAK_PREFIX + option.getKey())
|
return getOptionalValue(NS_KEYCLOAK_PREFIX + option.getKey())
|
||||||
.filter(f -> f.contains(value))
|
.filter(f -> f.contains(value))
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.keycloak.config.ExportOptions;
|
||||||
import org.keycloak.config.Option;
|
import org.keycloak.config.Option;
|
||||||
import org.keycloak.config.OptionBuilder;
|
import org.keycloak.config.OptionBuilder;
|
||||||
import org.keycloak.config.OptionCategory;
|
import org.keycloak.config.OptionCategory;
|
||||||
|
import org.keycloak.exportimport.UsersExportStrategy;
|
||||||
import org.keycloak.quarkus.runtime.cli.PropertyException;
|
import org.keycloak.quarkus.runtime.cli.PropertyException;
|
||||||
import org.keycloak.quarkus.runtime.configuration.Configuration;
|
import org.keycloak.quarkus.runtime.configuration.Configuration;
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ import java.util.Optional;
|
||||||
|
|
||||||
import static org.keycloak.exportimport.ExportImportConfig.PROVIDER;
|
import static org.keycloak.exportimport.ExportImportConfig.PROVIDER;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue;
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.getOptionalValue;
|
||||||
|
import static org.keycloak.quarkus.runtime.configuration.Configuration.isBlank;
|
||||||
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
|
import static org.keycloak.quarkus.runtime.configuration.mappers.PropertyMapper.fromOption;
|
||||||
|
|
||||||
public final class ExportPropertyMappers {
|
public final class ExportPropertyMappers {
|
||||||
|
@ -67,7 +69,7 @@ public final class ExportPropertyMappers {
|
||||||
.build(),
|
.build(),
|
||||||
fromOption(ExportOptions.USERS)
|
fromOption(ExportOptions.USERS)
|
||||||
.to("kc.spi-export-dir-users-export-strategy")
|
.to("kc.spi-export-dir-users-export-strategy")
|
||||||
.isEnabled(ExportPropertyMappers::isDirProvider)
|
.validator(ExportPropertyMappers::validateUsersUsage)
|
||||||
.paramLabel("strategy")
|
.paramLabel("strategy")
|
||||||
.build(),
|
.build(),
|
||||||
fromOption(ExportOptions.USERS_PER_FILE)
|
fromOption(ExportOptions.USERS_PER_FILE)
|
||||||
|
@ -78,6 +80,18 @@ public final class ExportPropertyMappers {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void validateUsersUsage(PropertyMapper<?> mapper, ConfigValue value) {
|
||||||
|
mapper.validateExpectedValues(value, mapper::validateSingleValue);
|
||||||
|
|
||||||
|
if (!isBlank(ExportOptions.FILE) && isBlank(ExportOptions.DIR)) {
|
||||||
|
var sameFileIsSpecified = UsersExportStrategy.SAME_FILE.toString().toLowerCase().equals(value.getValue());
|
||||||
|
|
||||||
|
if (!sameFileIsSpecified) {
|
||||||
|
throw new PropertyException("Property '--users' can be used only when exporting to a directory, or value set to 'same_file' when exporting to a file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void validateConfig() {
|
public static void validateConfig() {
|
||||||
if (getOptionalValue(EXPORTER_PROPERTY).isEmpty() && System.getProperty(PROVIDER) == null) {
|
if (getOptionalValue(EXPORTER_PROPERTY).isEmpty() && System.getProperty(PROVIDER) == null) {
|
||||||
throw new PropertyException("Must specify either --dir or --file options.");
|
throw new PropertyException("Must specify either --dir or --file options.");
|
||||||
|
|
|
@ -39,5 +39,16 @@ public class ExportDistTest {
|
||||||
|
|
||||||
cliResult = dist.run("export", "--realm=master");
|
cliResult = dist.run("export", "--realm=master");
|
||||||
cliResult.assertError("Must specify either --dir or --file options.");
|
cliResult.assertError("Must specify either --dir or --file options.");
|
||||||
|
|
||||||
|
cliResult = dist.run("export", "--file=master", "--users=skip");
|
||||||
|
cliResult.assertError("Property '--users' can be used only when exporting to a directory, or value set to 'same_file' when exporting to a file.");
|
||||||
|
|
||||||
|
cliResult = dist.run("export", "--file=some-file", "--users=same_file");
|
||||||
|
cliResult.assertNoError("Property '--users' can be used only when exporting to a directory, or value set to 'same_file' when exporting to a file.");
|
||||||
|
cliResult.assertMessage("Exporting model into file");
|
||||||
|
|
||||||
|
cliResult = dist.run("export", "--dir=some-dir", "--users=skip");
|
||||||
|
cliResult.assertMessage("Realm 'master' - data exported");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,6 +79,11 @@ public interface CLIResult extends LaunchResult {
|
||||||
() -> "The Error Output:\n " + getErrorOutput() + "\ndoesn't contains " + msg);
|
() -> "The Error Output:\n " + getErrorOutput() + "\ndoesn't contains " + msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void assertNoError(String msg) {
|
||||||
|
assertFalse(getErrorOutput().contains(msg),
|
||||||
|
() -> "The Error Output:\n " + getErrorOutput() + "\n contains " + msg);
|
||||||
|
}
|
||||||
|
|
||||||
default void assertMessage(String message) {
|
default void assertMessage(String message) {
|
||||||
assertThat(getOutput(), containsString(message));
|
assertThat(getOutput(), containsString(message));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue