diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java index 7657b5a55..122ea7842 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java +++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CommandletManagerImpl.java @@ -30,6 +30,7 @@ import com.devonfw.tools.ide.tool.sonar.Sonar; import com.devonfw.tools.ide.tool.terraform.Terraform; import com.devonfw.tools.ide.tool.vscode.Vscode; +import com.devonfw.tools.ide.tool.jasypt.Jasypt; /** * Implementation of {@link CommandletManager}. @@ -88,6 +89,7 @@ public CommandletManagerImpl(IdeContext context) { add(new Aws(context)); add(new Cobigen(context)); add(new Jmc(context)); + add(new Jasypt(context)); add(new Docker(context)); add(new Sonar(context)); } diff --git a/cli/src/main/java/com/devonfw/tools/ide/common/Tag.java b/cli/src/main/java/com/devonfw/tools/ide/common/Tag.java index d7ef85640..1eda29dcf 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/common/Tag.java +++ b/cli/src/main/java/com/devonfw/tools/ide/common/Tag.java @@ -293,6 +293,7 @@ public final class Tag { /** {@link #Tag} for github. */ public static final Tag GITHUB = create("github", GIT); + /** {@link #Tag} for diff (tools that compare files and determine the difference). */ public static final Tag DIFF = create("diff", CONFIG_MANAGEMENT, false, "patch"); @@ -311,6 +312,12 @@ public final class Tag { /** {@link #Tag} for Linux. */ public static final Tag LINUX = create("linux", OS, false); + /** {@link #getParent() Parent} for cryptography. */ + public static final Tag CRYPTO = create("cryptography", ROOT, false, "crypto"); + + /** {@link #Tag} for encryption. */ + public static final Tag ENCRYPTION = create("encryption", CRYPTO); + private final String id; private final Tag parent; diff --git a/cli/src/main/java/com/devonfw/tools/ide/environment/AbstractEnvironmentVariables.java b/cli/src/main/java/com/devonfw/tools/ide/environment/AbstractEnvironmentVariables.java index 4b8bd6551..99bf6d1fe 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/environment/AbstractEnvironmentVariables.java +++ b/cli/src/main/java/com/devonfw/tools/ide/environment/AbstractEnvironmentVariables.java @@ -270,7 +270,7 @@ protected String getValue(String name) { if (!name.equals(key)) { value = this.parent.get(key); } - if (value != null) { + if (value == null) { value = var.getDefaultValueAsString(this.context); } } diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/PasswordProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/PasswordProperty.java new file mode 100644 index 000000000..a418a12b6 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/property/PasswordProperty.java @@ -0,0 +1,20 @@ +package com.devonfw.tools.ide.property; + +/** + * {@link Property} with {@link #getValueType() value type} {@link String} representing a password. + */ +public class PasswordProperty extends StringProperty { + + /** + * The constructor. + * + * @param name the {@link #getName() property name}. + * @param required the {@link #isRequired() required flag}. + * @param alias the {@link #getAlias() property alias}. + */ + public PasswordProperty(String name, boolean required, String alias) { + + super(name, required, alias); + } + +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/jasypt/Jasypt.java b/cli/src/main/java/com/devonfw/tools/ide/tool/jasypt/Jasypt.java new file mode 100644 index 000000000..a6f7aff99 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/jasypt/Jasypt.java @@ -0,0 +1,103 @@ +package com.devonfw.tools.ide.tool.jasypt; + +import com.devonfw.tools.ide.common.Tag; +import com.devonfw.tools.ide.context.IdeContext; +import com.devonfw.tools.ide.property.EnumProperty; +import com.devonfw.tools.ide.property.PasswordProperty; +import com.devonfw.tools.ide.tool.LocalToolCommandlet; +import com.devonfw.tools.ide.tool.ToolCommandlet; +import com.devonfw.tools.ide.tool.java.Java; + +import java.nio.file.Path; +import java.util.Set; + +/** + * {@link ToolCommandlet} for Jasypt, The java library which allows to add basic + * encryption capabilities with minimum effort. + */ +public class Jasypt extends LocalToolCommandlet { + + public final EnumProperty command; + + public final PasswordProperty masterPassword; + + public final PasswordProperty secret; + + private static final String CLASS_NAME_ENCRYPTION = "org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI"; + + private static final String CLASS_NAME_DECRYPTION = "org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI"; + + /** + * The constructor. + * + * @param context the {@link IdeContext}. + */ + public Jasypt(IdeContext context) { + + super(context, "jasypt", Set.of(Tag.JAVA, Tag.ENCRYPTION)); + + this.command = add(new EnumProperty<>("", true, "command", JasyptCommand.class)); + this.masterPassword = add(new PasswordProperty("", true, "masterPassword")); + this.secret = add(new PasswordProperty("", true, "secret")); + } + + @Override + protected void initProperties() { + + // Empty on purpose + } + + @Override + public boolean doInstall(boolean silent) { + + getCommandlet(Java.class).install(); + + return super.doInstall(silent); + } + + @Override + protected boolean isExtract() { + + return false; + } + + @Override + public void run() { + + Path toolPath = getToolPath(); + if (!toolPath.toFile().exists()) { + super.install(true); + } + + JasyptCommand command = this.command.getValue(); + switch (command) { + case ENCRYPT: + runJasypt(CLASS_NAME_ENCRYPTION); + break; + case DECRYPT: + runJasypt(CLASS_NAME_DECRYPTION); + break; + + default: + } + } + + private void runJasypt(String className) { + + Java java = getCommandlet(Java.class); + + String[] jasyptOptions = this.context.getVariables().get("JASYPT_OPTS").split(" "); + String algorithm = jasyptOptions[0]; + String generatorClassName = jasyptOptions[1]; + + java.runTool(null, "-cp", resolveJasyptJarPath().toString(), className, algorithm, generatorClassName, + "password=" + this.masterPassword.getValue(), "input=" + this.secret.getValue()); + } + + private Path resolveJasyptJarPath() { + + Path toolPath = this.getToolPath(); + String installedVersion = getInstalledVersion().toString(); + return toolPath.resolve("jasypt-" + installedVersion + ".jar"); + } +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/jasypt/JasyptCommand.java b/cli/src/main/java/com/devonfw/tools/ide/tool/jasypt/JasyptCommand.java new file mode 100644 index 000000000..9aa914dd5 --- /dev/null +++ b/cli/src/main/java/com/devonfw/tools/ide/tool/jasypt/JasyptCommand.java @@ -0,0 +1,8 @@ +package com.devonfw.tools.ide.tool.jasypt; + +/** + * Represents commands for controlling a jasypt operation in The{@link Jasypt} Tool. + */ +public enum JasyptCommand { + ENCRYPT, DECRYPT +} diff --git a/cli/src/main/java/com/devonfw/tools/ide/variable/IdeVariables.java b/cli/src/main/java/com/devonfw/tools/ide/variable/IdeVariables.java index c6d6d9fa2..4d2f9a48f 100644 --- a/cli/src/main/java/com/devonfw/tools/ide/variable/IdeVariables.java +++ b/cli/src/main/java/com/devonfw/tools/ide/variable/IdeVariables.java @@ -49,9 +49,13 @@ public interface IdeVariables { /** {@link VariableDefinition} for {@link com.devonfw.tools.ide.context.IdeContext#getWorkspaceName() WORKSPACE}. */ VariableDefinitionString GRAALVM_EDITION = new VariableDefinitionString("GRAALVM_EDITION", null, c -> "community"); + /** {@link VariableDefinition} for options of jasypt */ + VariableDefinitionString JASYPT_OPTS = new VariableDefinitionString("JASYPT_OPTS", null, + c -> "algorithm=PBEWITHHMACSHA512ANDAES_256 ivGeneratorClassName=org.jasypt.iv.RandomIvGenerator"); + /** A {@link Collection} with all pre-defined {@link VariableDefinition}s. */ Collection> VARIABLES = List.of(PATH, HOME, WORKSPACE_PATH, IDE_HOME, IDE_ROOT, WORKSPACE, - IDE_TOOLS, CREATE_START_SCRIPTS, IDE_MIN_VERSION, MVN_VERSION, DOCKER_EDITION, GRAALVM_EDITION); + IDE_TOOLS, CREATE_START_SCRIPTS, IDE_MIN_VERSION, MVN_VERSION, DOCKER_EDITION, GRAALVM_EDITION, JASYPT_OPTS); /** * @param name the name of the requested {@link VariableDefinition}. diff --git a/cli/src/main/resources/nls/Ide.properties b/cli/src/main/resources/nls/Ide.properties index cf9d8c4e5..1715ce61a 100644 --- a/cli/src/main/resources/nls/Ide.properties +++ b/cli/src/main/resources/nls/Ide.properties @@ -34,10 +34,14 @@ cmd-shell=Commandlet to start built-in shell with advanced auto-completion. cmd-terraform=Tool commandlet for Terraform cmd-vscode=Tool commandlet for Visual Studio Code (IDE) cmd-cobigen=Tool commandlet for Cobigen +cmd-jasypt=Tool commandlet for Jasypt cmd-sonar=Tool commandlet for SonarQube val-args=The commandline arguments to pass to the tool. val-edition=The tool edition. val-sonar-command=START|STOP|ANALYZE +val-jasypt-command=encrypt | decrypt +val-jasypt-masterPassword=master password +val-jasypt-secret=The secret to be encrypted or decrypted val-tool=The tool commandlet to select. val-version=The tool version val-set-version-version=The tool version to set. diff --git a/cli/src/main/resources/nls/Ide_de.properties b/cli/src/main/resources/nls/Ide_de.properties index 6523f9f18..2d80f673e 100644 --- a/cli/src/main/resources/nls/Ide_de.properties +++ b/cli/src/main/resources/nls/Ide_de.properties @@ -31,6 +31,7 @@ cmd-set-version=Setzt die Version des selektierten Werkzeugs. cmd-terraform=Werkzeug Kommando für Terraform. cmd-vscode=Werkzeug Kommando für Visual Studio Code (IDE) cmd-cobigen=Werkzeug Kommando für Cobigen. +cmd-jasypt=Werkzeug Kommando für Jasypt cmd-sonar=Werkzeug Kommando für SonarQube. val-args=Die Kommandozeilen-Argumente zur Übergabe an das Werkzeug. val-edition=Die Werkzeug Edition. diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/jasypt/JasyptTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/jasypt/JasyptTest.java new file mode 100644 index 000000000..32eb612af --- /dev/null +++ b/cli/src/test/java/com/devonfw/tools/ide/tool/jasypt/JasyptTest.java @@ -0,0 +1,75 @@ +package com.devonfw.tools.ide.tool.jasypt; + +import com.devonfw.tools.ide.commandlet.InstallCommandlet; +import com.devonfw.tools.ide.context.AbstractIdeContextTest; +import com.devonfw.tools.ide.context.IdeTestContext; +import com.devonfw.tools.ide.log.IdeLogLevel; +import org.junit.jupiter.api.Test; + +/** + * Integration test of {@link Jasypt}. + */ +public class JasyptTest extends AbstractIdeContextTest { + + private static final String PROJECT_JASYPT = "jasypt"; + + @Test + public void testJasyptInstallCommandlet() { + + // arrange + IdeTestContext context = newContext(PROJECT_JASYPT); + InstallCommandlet install = context.getCommandletManager().getCommandlet(InstallCommandlet.class); + install.tool.setValueAsString("jasypt", context); + // act + install.run(); + + // assert + checkInstallation(context); + } + + @Test + public void testJasyptInstall() { + + // arrange + IdeTestContext context = newContext(PROJECT_JASYPT); + + Jasypt commandlet = new Jasypt(context); + + // act + commandlet.install(); + + // assert + checkInstallation(context); + } + + @Test + public void testJasyptRun() { + + // arrange + IdeTestContext context = newContext(PROJECT_JASYPT); + Jasypt commandlet = new Jasypt(context); + + commandlet.command.setValue(JasyptCommand.ENCRYPT); + commandlet.masterPassword.setValue("password"); + commandlet.secret.setValue("input"); + + // act + commandlet.run(); + + // assert + assertLogMessage(context, IdeLogLevel.INFO, "executing java:"); + assertLogMessage(context, IdeLogLevel.INFO, "This is a jar file."); + checkInstallation(context); + } + + private void checkInstallation(IdeTestContext context) { + + // install - java + assertThat(context.getSoftwarePath().resolve("java/bin/java")).exists(); + + // commandlet - jasypt + assertThat(context.getSoftwarePath().resolve("jasypt/jasypt-1.9.3.jar")).hasContent("This is a jar file."); + assertThat(context.getSoftwarePath().resolve("jasypt/.ide.software.version")).exists().hasContent("1.9.3"); + assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully installed jasypt in version 1.9.3"); + } +} diff --git a/cli/src/test/resources/ide-projects/jasypt/_ide/urls/readme b/cli/src/test/resources/ide-projects/jasypt/_ide/urls/readme new file mode 100644 index 000000000..befcdfa75 --- /dev/null +++ b/cli/src/test/resources/ide-projects/jasypt/_ide/urls/readme @@ -0,0 +1 @@ +this is the download metadata \ No newline at end of file diff --git a/cli/src/test/resources/ide-projects/jasypt/project/home/.ide/ide.properties b/cli/src/test/resources/ide-projects/jasypt/project/home/.ide/ide.properties new file mode 100644 index 000000000..e69de29bb diff --git a/cli/src/test/resources/ide-projects/jasypt/project/home/readme b/cli/src/test/resources/ide-projects/jasypt/project/home/readme new file mode 100644 index 000000000..5e8bc178c --- /dev/null +++ b/cli/src/test/resources/ide-projects/jasypt/project/home/readme @@ -0,0 +1 @@ +this is the users HOME directory \ No newline at end of file diff --git a/cli/src/test/resources/ide-projects/jasypt/project/readme b/cli/src/test/resources/ide-projects/jasypt/project/readme new file mode 100644 index 000000000..256f5732c --- /dev/null +++ b/cli/src/test/resources/ide-projects/jasypt/project/readme @@ -0,0 +1 @@ +this is the IDE_HOME directory \ No newline at end of file diff --git a/cli/src/test/resources/ide-projects/jasypt/project/settings/ide.properties b/cli/src/test/resources/ide-projects/jasypt/project/settings/ide.properties new file mode 100644 index 000000000..29faea4db --- /dev/null +++ b/cli/src/test/resources/ide-projects/jasypt/project/settings/ide.properties @@ -0,0 +1,2 @@ +JAVA_VERSION=17.0.10_7 +JASYPT_VERSION=1.9.3 \ No newline at end of file diff --git a/cli/src/test/resources/ide-projects/jasypt/project/workspaces/main/readme b/cli/src/test/resources/ide-projects/jasypt/project/workspaces/main/readme new file mode 100644 index 000000000..f04b5be39 --- /dev/null +++ b/cli/src/test/resources/ide-projects/jasypt/project/workspaces/main/readme @@ -0,0 +1 @@ +this is the main workspace of jmc test case \ No newline at end of file diff --git a/cli/src/test/resources/ide-projects/jasypt/readme b/cli/src/test/resources/ide-projects/jasypt/readme new file mode 100644 index 000000000..15b91829e --- /dev/null +++ b/cli/src/test/resources/ide-projects/jasypt/readme @@ -0,0 +1 @@ +this is the IDE_ROOT directory \ No newline at end of file diff --git a/cli/src/test/resources/ide-projects/jasypt/repository/jasypt/jasypt/default/jasypt-1.9.3.jar b/cli/src/test/resources/ide-projects/jasypt/repository/jasypt/jasypt/default/jasypt-1.9.3.jar new file mode 100644 index 000000000..16f4318e4 --- /dev/null +++ b/cli/src/test/resources/ide-projects/jasypt/repository/jasypt/jasypt/default/jasypt-1.9.3.jar @@ -0,0 +1 @@ +This is a jar file. diff --git a/cli/src/test/resources/ide-projects/jasypt/repository/java/java/default/bin/java b/cli/src/test/resources/ide-projects/jasypt/repository/java/java/default/bin/java new file mode 100755 index 000000000..655040e33 --- /dev/null +++ b/cli/src/test/resources/ide-projects/jasypt/repository/java/java/default/bin/java @@ -0,0 +1,3 @@ +#!/bin/bash +echo "executing java:" +cat $2 # .jar file \ No newline at end of file