Skip to content

Commit

Permalink
[ELY-2547] Add Elytron Tool option to overwrite CLI script
Browse files Browse the repository at this point in the history
  • Loading branch information
lvydra committed Jun 12, 2023
1 parent 91b6e9f commit 80307db
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 20 deletions.
1 change: 1 addition & 0 deletions tool/src/main/java/org/wildfly/security/tool/Command.java
Expand Up @@ -498,6 +498,7 @@ class Params {
static final String SILENT_PARAM = "silent";
static final String STORE_LOCATION_PARAM = "location";
static final String SUMMARY_PARAM = "summary";
static final String OVERWRITE_SCRIPT_FILE = "overwrite-script-file";

// Other constants
static final Pattern BOOLEAN_ARG_REGEX = Pattern.compile("(true|false)", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
Expand Down
Expand Up @@ -589,6 +589,9 @@ public interface ElytronToolMessages extends BasicLogger {
@Message(id = NONE, value = "Provides a detailed summary of all operations performed, once the command finishes.")
String cmdFileSystemRealmSummaryDesc();

@Message(id = NONE, value = "Whether the cli script file will be overwritten, if attempting to write to an existing file.")
String cmdFileSystemRealmOverwriteCliScriptFileDesc();

@Message(id = NONE, value = "No users file specified. Please use either --bulk-convert <file> or specify a users file using --users-file <file>")
MissingOptionException missingUsersFile();

Expand Down
Expand Up @@ -17,6 +17,7 @@
*/
package org.wildfly.security.tool;

import static org.wildfly.security.tool.Params.BOOLEAN_PARAM;
import static org.wildfly.security.tool.Params.BULK_CONVERT_PARAM;
import static org.wildfly.security.tool.Params.CREATE_CREDENTIAL_STORE_PARAM;
import static org.wildfly.security.tool.Params.CREDENTIAL_STORE_LOCATION_PARAM;
Expand All @@ -38,6 +39,7 @@
import static org.wildfly.security.tool.Params.LINE_SEPARATOR;
import static org.wildfly.security.tool.Params.NAME_PARAM;
import static org.wildfly.security.tool.Params.OUTPUT_LOCATION_PARAM;
import static org.wildfly.security.tool.Params.OVERWRITE_SCRIPT_FILE;
import static org.wildfly.security.tool.Params.PASSWORD_ENV_PARAM;
import static org.wildfly.security.tool.Params.PASSWORD_PARAM;
import static org.wildfly.security.tool.Params.REALM_NAME_PARAM;
Expand Down Expand Up @@ -173,6 +175,10 @@ class FileSystemEncryptRealmCommand extends Command {
option.setArgName(FILE_PARAM);
options.addOption(option);

option = new Option("w", OVERWRITE_SCRIPT_FILE, true, ElytronToolMessages.msg.cmdFileSystemRealmOverwriteCliScriptFileDesc());
option.setArgName(BOOLEAN_PARAM);
options.addOption(option);

option = Option.builder().longOpt(HELP_PARAM).desc(ElytronToolMessages.msg.cmdLineHelp()).build();
options.addOption(option);

Expand Down Expand Up @@ -205,6 +211,7 @@ private static final class Descriptor {
private Boolean encoded;
private Boolean createCredentialStore;
private Boolean populate;
private Boolean overwriteScriptFile;
Descriptor() {
}

Expand All @@ -227,6 +234,7 @@ private static final class Descriptor {
this.createCredentialStore = descriptor.createCredentialStore;
this.secretKeyAlias = descriptor.secretKeyAlias;
this.populate = descriptor.populate;
this.overwriteScriptFile = descriptor.overwriteScriptFile;
}

public Encoding getHashEncoding() {
Expand Down Expand Up @@ -359,6 +367,14 @@ void setKeyPairAlias(String keyPairAlias) {
this.keyPairAlias = keyPairAlias;
}

public Boolean getOverwriteScriptFile() {
return overwriteScriptFile;
}

public void setOverwriteScriptFile(Boolean overwriteScriptFile) {
this.overwriteScriptFile = overwriteScriptFile;
}

void reset() {
this.inputRealmLocation = null;
this.outputRealmLocation = null;
Expand All @@ -376,6 +392,7 @@ void reset() {
this.encoded = null;
this.levels = null;
this.populate = null;
this.overwriteScriptFile = null;
}
}

Expand Down Expand Up @@ -421,6 +438,7 @@ public void execute(String[] args) throws Exception {
String encodedOption = cmdLine.getOptionValue("f");
String bulkConvert = cmdLine.getOptionValue("b");
String populateOption = cmdLine.getOptionValue("p");
String overwriteScriptFileOption = cmdLine.getOptionValue("w");

if (bulkConvert == null) {
if (realmNameOption == null) {
Expand Down Expand Up @@ -470,6 +488,9 @@ public void execute(String[] args) throws Exception {
} else {
descriptor.setPopulate(Boolean.valueOf(populateOption));
}
if (overwriteScriptFileOption != null) {
descriptor.setOverwriteScriptFile(Boolean.valueOf(overwriteScriptFileOption));
}

if (levelsOption == null) {
descriptor.setLevels(DEFAULT_LEVELS);
Expand Down Expand Up @@ -923,6 +944,7 @@ private void createWildFlyScript() throws Exception {
String keyStoreType = descriptor.getKeyStoreType();
char[] password = descriptor.getPassword();
String keyPairAlias = descriptor.getKeyPairAlias();
Boolean overwriteScript = descriptor.getOverwriteScriptFile();

if (hashCharset == null) {
hashCharset = StandardCharsets.UTF_8;
Expand All @@ -937,17 +959,20 @@ private void createWildFlyScript() throws Exception {

Path scriptPath = Paths.get(String.format("%s/%s.cli", outputRealmLocation, fileSystemRealmName));

if (scriptPath.toFile().exists()) {
createScriptCheck = prompt(
true,
ElytronToolMessages.msg.shouldFileBeOverwritten(scriptPath.toString()),
false,
null
);
if (createScriptCheck.trim().isEmpty()) createScriptCheck = "n";
if (overwriteScript == null) {
if (scriptPath.toFile().exists()) {
createScriptCheck = prompt(
true,
ElytronToolMessages.msg.shouldFileBeOverwritten(scriptPath.toString()),
false,
null
);
if (createScriptCheck.trim().isEmpty()) createScriptCheck = "n";
}

overwriteScript = createScriptCheck.isEmpty() || createScriptCheck.toLowerCase().startsWith("y");
}

boolean overwriteScript = createScriptCheck.isEmpty() || createScriptCheck.toLowerCase().startsWith("y");
if (!overwriteScript) { // Generate a random file for the CLI script
do {
scriptPath = Paths.get(String.format("%s/%s.cli",
Expand Down Expand Up @@ -1001,7 +1026,7 @@ private void createWildFlyScript() throws Exception {
if (overwriteScript) { // Create a new script file, or overwrite the existing one
Files.write(scriptPath, scriptLines, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
} else {
Files.write(scriptPath, scriptLines, StandardOpenOption.APPEND);
Files.write(scriptPath, scriptLines, StandardOpenOption.CREATE);
}
counter++;
}
Expand Down
Expand Up @@ -39,6 +39,7 @@
import static org.wildfly.security.tool.Params.NAME_PARAM;
import static org.wildfly.security.tool.Params.NUMBER_PARAM;
import static org.wildfly.security.tool.Params.OUTPUT_LOCATION_PARAM;
import static org.wildfly.security.tool.Params.OVERWRITE_SCRIPT_FILE;
import static org.wildfly.security.tool.Params.PASSWORD_ENV_PARAM;
import static org.wildfly.security.tool.Params.PASSWORD_PARAM;
import static org.wildfly.security.tool.Params.REALM_NAME_PARAM;
Expand Down Expand Up @@ -157,6 +158,9 @@ public class FileSystemRealmIntegrityCommand extends Command {
options.addOption(Option.builder("b").longOpt(BULK_CONVERT_PARAM).desc(ElytronToolMessages.msg.cmdFileSystemRealmIntegrityBulkConvertDesc())
.hasArg().argName(FILE_PARAM)
.build());
options.addOption(Option.builder("w").longOpt(OVERWRITE_SCRIPT_FILE).desc(ElytronToolMessages.msg.cmdFileSystemRealmOverwriteCliScriptFileDesc())
.hasArg().argName(BOOLEAN_PARAM)
.build());

// General options
options.addOption(Option.builder("h").longOpt(HELP_PARAM).desc(ElytronToolMessages.msg.cmdLineHelp())
Expand Down Expand Up @@ -185,6 +189,7 @@ private static final class Descriptor {
private Encoding hashEncoding;
private Charset hashCharset;
private Boolean encoded;
private Boolean overwriteScriptFile;

private Boolean upgradeInPlace;
private Boolean missingRequiredValue;
Expand Down Expand Up @@ -212,6 +217,7 @@ private static final class Descriptor {
this.hashEncoding = descriptor.hashEncoding;
this.hashCharset = descriptor.hashCharset;
this.encoded = descriptor.encoded;
this.overwriteScriptFile = descriptor.overwriteScriptFile;

this.upgradeInPlace = descriptor.upgradeInPlace;
this.missingRequiredValue = descriptor.missingRequiredValue;
Expand Down Expand Up @@ -322,6 +328,9 @@ public Boolean getMissingRequiredValue() {
public Boolean getRealmUpgraded() {
return realmUpgraded;
}
public Boolean getOverwriteScriptFile() {
return overwriteScriptFile;
}

public void setInputRealmPath(String inputRealmPath) {
setInputRealmPath(Paths.get(inputRealmPath).normalize().toAbsolutePath());
Expand Down Expand Up @@ -410,6 +419,9 @@ public void setMissingRequiredValue() {
public void setRealmUpgraded() {
this.realmUpgraded = true;
}
public void setOverwriteScriptFile(Boolean overwriteScriptFile) {
this.overwriteScriptFile = overwriteScriptFile;
}

void reset(boolean resetMissingValues) {
// Required values are set to null if contents are null, or equal "MISSING"
Expand All @@ -428,6 +440,7 @@ void reset(boolean resetMissingValues) {
hashEncoding = null;
hashCharset = null;
encoded = null;
overwriteScriptFile = null;

upgradeInPlace = false;
realmUpgraded = false;
Expand Down Expand Up @@ -476,6 +489,7 @@ public void execute(String[] args) throws Exception {
String hashCharsetOption = cmdLine.getOptionValue("u");
String encodedOption = cmdLine.getOptionValue("f");
String bulkConvertOption = cmdLine.getOptionValue("b");
String overwriteScriptFileOption = cmdLine.getOptionValue("w");

if (bulkConvertOption == null) {
if (summaryMode) {
Expand Down Expand Up @@ -574,6 +588,10 @@ public void execute(String[] args) throws Exception {
descriptor.setEncoded(Boolean.parseBoolean(encodedOption));
}

if (overwriteScriptFileOption != null) {
descriptor.setOverwriteScriptFile(Boolean.valueOf(overwriteScriptFileOption));
}

descriptors.add(descriptor);
findMissingRequiredValuesAndSetValues(0, descriptor);
} else if (nonBulkConvertOptionSet(inputRealmPathOption, outputRealmPathOption, realmNameOption, keyStorePathOption,
Expand Down Expand Up @@ -950,22 +968,26 @@ private void createWildFlyScript() throws Exception {
String fileSystemRealmName = descriptor.getFileSystemRealmName();
Path outputRealmPath = descriptor.getOutputRealmPath();
boolean upgradeInPlace = descriptor.getUpgradeInPlace();
Boolean overwriteScript = descriptor.getOverwriteScriptFile();

String createScriptCheck = "";
Path scriptPath = Paths.get(String.format("%s/%s.cli", outputRealmPath, fileSystemRealmName));

// Ask to overwrite CLI script, if already exists
if(scriptPath.toFile().exists()) {
createScriptCheck = prompt(
true,
ElytronToolMessages.msg.shouldFileBeOverwritten(scriptPath.toString()),
false,
null
);
if (createScriptCheck.trim().isEmpty()) createScriptCheck = "n";
if (overwriteScript == null) {
// Ask to overwrite CLI script, if already exists
if(scriptPath.toFile().exists()) {
createScriptCheck = prompt(
true,
ElytronToolMessages.msg.shouldFileBeOverwritten(scriptPath.toString()),
false,
null
);
if (createScriptCheck.trim().isEmpty()) createScriptCheck = "n";
}

overwriteScript = createScriptCheck.isEmpty() || createScriptCheck.toLowerCase().startsWith("y");
}

boolean overwriteScript = createScriptCheck.isEmpty() || createScriptCheck.toLowerCase().startsWith("y");
if (!overwriteScript) {
do {
scriptPath = Paths.get(String.format("%s/%s.cli",
Expand Down
Expand Up @@ -17,6 +17,8 @@
*/
package org.wildfly.security.tool;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.wildfly.security.tool.Command.ELYTRON_KS_PASS_PROVIDERS;
Expand Down Expand Up @@ -62,6 +64,12 @@ private void runCommand(String inputLocation, String outputLocation, String file
executeCommandAndCheckStatus(requiredArgs, expectedStatus);
}

private void runCommand(String inputLocation, String outputLocation, String fileSystemRealmName, String encoded, boolean create, int expectedStatus, boolean overwriteScriptFile) {
String[] requiredArgs;
requiredArgs = new String[]{"--input-location", inputLocation, "--output-location", outputLocation, "--realm-name", fileSystemRealmName, "--encoded", encoded, "--create", String.valueOf(create), "--credential-store", CREDENTIAL_STORE_PATH, "--overwrite-script-file", String.valueOf(overwriteScriptFile)};
executeCommandAndCheckStatus(requiredArgs, expectedStatus);
}

private void runCommand(String inputLocation, String outputLocation, String fileSystemRealmName, int levels, String encoded, boolean create, int expectedStatus) {
String[] requiredArgs;
requiredArgs = new String[]{"--input-location", inputLocation, "--output-location", outputLocation, "--realm-name", fileSystemRealmName, "--levels", String.valueOf(levels), "--encoded", encoded, "--create", String.valueOf(create), "--credential-store", CREDENTIAL_STORE_PATH};
Expand Down Expand Up @@ -155,6 +163,48 @@ public void testSingleUser() throws Exception {
}
}

@Test
public void testOverwritingScriptFileTrue() throws Exception {
String outputLocation = RELATIVE_BASE_DIR + "fs-encrypted-realms";
String fileSystemRealmName = "overwrite-script-true";
String file = "target/test-classes/filesystem-encrypt/fs-encrypted-realms/overwrite-script-true.cli";

String inputLocation = RELATIVE_BASE_DIR + "fs-unencrypted-realms/single-user-with-role/";
runCommand(inputLocation, outputLocation, fileSystemRealmName, 3, "false", true, 0);

assertTrue(fileExists(file));
File scriptFile = new File(file);
Long modifiedBefore = scriptFile.lastModified();

inputLocation = RELATIVE_BASE_DIR + "fs-unencrypted-realms/single-user/";
runCommand(inputLocation, outputLocation, fileSystemRealmName, "false", true, 0, true);

Long modifiedAfter = scriptFile.lastModified();

assertNotEquals(modifiedBefore, modifiedAfter);
}

@Test
public void testOverwritingScriptFileFalse() throws Exception {
String outputLocation = RELATIVE_BASE_DIR + "fs-encrypted-realms";
String fileSystemRealmName = "overwrite-script-false";
String file = "target/test-classes/filesystem-encrypt/fs-encrypted-realms/overwrite-script-false.cli";

String inputLocation = RELATIVE_BASE_DIR + "fs-unencrypted-realms/single-user-with-role/";
runCommand(inputLocation, outputLocation, fileSystemRealmName, 3, "false", true, 0);

assertTrue(fileExists(file));
File scriptFile = new File(file);
Long modifiedBefore = scriptFile.lastModified();

inputLocation = RELATIVE_BASE_DIR + "fs-unencrypted-realms/single-user/";
runCommand(inputLocation, outputLocation, fileSystemRealmName, "false", true, 0, false);

Long modifiedAfter = scriptFile.lastModified();

assertEquals(modifiedBefore, modifiedAfter);
}

@Test
public void testSingleUserMissingParam() throws Exception {
String outputLocation = RELATIVE_BASE_DIR + "fs-encrypted-realms";
Expand Down

0 comments on commit 80307db

Please sign in to comment.