diff --git a/cli/src/main/java/de/hsadmin/jscli/ScriptClient.java b/cli/src/main/java/de/hsadmin/jscli/ScriptClient.java index fa3bc53..fb0625d 100644 --- a/cli/src/main/java/de/hsadmin/jscli/ScriptClient.java +++ b/cli/src/main/java/de/hsadmin/jscli/ScriptClient.java @@ -12,6 +12,7 @@ import javax.script.ScriptEngineManager; import javax.script.ScriptException; import de.hsadmin.common.error.TechnicalException; +import de.hsadmin.jscli.console.CommandShell; import de.hsadmin.jscli.console.ConsoleWrapper; import de.hsadmin.jscli.exception.JSCliException; import de.hsadmin.login.cas.TicketProviderFactory; @@ -23,14 +24,18 @@ public class ScriptClient { public ScriptClient(final ConsoleWrapper console, final String user, final String runAs, final String... arguments) throws JSCliException { final RpcClient rpcClient = new RpcClient(); + final CommandShell commandShell = new CommandShell(); try { engine = new ScriptEngineManager().getEngineByName("js"); engine.put("casgrantingticket", TicketProviderFactory.getInstance(console, user, runAs)); engine.put("xmlrpcclient", rpcClient); engine.put("xmlrpcLastResult", null); + engine.put("commandshell", commandShell); completionStrings = new HashSet(); completionStrings.add("set"); completionStrings.add("where"); + completionStrings.add("commandshell"); + completionStrings.add("commandshell.execute"); considerArguments(arguments); try { final ClassLoader classLoader = getClass().getClassLoader(); diff --git a/cli/src/main/java/de/hsadmin/jscli/console/CommandShell.java b/cli/src/main/java/de/hsadmin/jscli/console/CommandShell.java new file mode 100644 index 0000000..30f99d0 --- /dev/null +++ b/cli/src/main/java/de/hsadmin/jscli/console/CommandShell.java @@ -0,0 +1,61 @@ +package de.hsadmin.jscli.console; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintWriter; + +import de.hsadmin.jscli.exception.ShellException; + +public class CommandShell { + + public String execute(String command) throws ShellException { + return execute(command, null); + } + + public String execute(String command, String stdInput) throws ShellException { + Process backend = null; + String callOutput = null; + int exitCode = 0; + try { + String[] cmdArray = { "/bin/bash", "-c", command }; + backend = Runtime.getRuntime().exec(cmdArray); + if (stdInput != null) { + OutputStream stdInputStream = backend.getOutputStream(); + PrintWriter stdInputWriter = new PrintWriter(stdInputStream); + stdInputWriter.print(stdInput); + stdInputWriter.close(); + stdInputStream.close(); + } + callOutput = readProcessStream(backend.getInputStream()); + exitCode = backend.waitFor(); + if (exitCode != 0) { + String aErr = readProcessStream(backend.getErrorStream()); + throw new ShellException(aErr); + } + } catch (IOException e) { + throw new ShellException(e); + } catch (InterruptedException e) { + throw new ShellException(e); + } + if (callOutput != null) { + return callOutput.trim(); + } + return null; + } + + private static String readProcessStream(InputStream stream) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + StringBuffer textBuff = new StringBuffer(); + String textLine = reader.readLine(); + while (textLine != null) { + textBuff.append(textLine); + textBuff.append('\n'); + textLine = reader.readLine(); + } + reader.close(); + return textBuff.toString(); + } +} diff --git a/cli/src/main/java/de/hsadmin/jscli/exception/ShellException.java b/cli/src/main/java/de/hsadmin/jscli/exception/ShellException.java new file mode 100644 index 0000000..4df7bf6 --- /dev/null +++ b/cli/src/main/java/de/hsadmin/jscli/exception/ShellException.java @@ -0,0 +1,14 @@ +package de.hsadmin.jscli.exception; + +public class ShellException extends Exception { + + private static final long serialVersionUID = 5499293305075489652L; + + public ShellException(String message) { + super(message); + } + + public ShellException(Throwable e) { + super(e); + } +} diff --git a/cli/src/main/resources/js/functions.js b/cli/src/main/resources/js/functions.js index f11ba61..7986435 100644 --- a/cli/src/main/resources/js/functions.js +++ b/cli/src/main/resources/js/functions.js @@ -22,7 +22,7 @@ function hsaParseParam(val) { function hsaParseParamArray(o) { var lst = new JArrayList(); var val = ''; - for (var idx=0; idx < o.length; idx++) { + for (var idx = 0; idx < o.length; idx++) { val = o[idx]; if (typeof val === 'object' && val.constructor === Array) { val = hsaParseParamArray(val); @@ -55,8 +55,8 @@ function hsaParseParamObject(o) { function hsaToNativeJSObject(val) { if (val instanceof java.util.List) { var res = []; - for (var i = 0; i < val.size(); i++) { - res[i] = hsaToNativeJSObject(val.get(i)); + for (var idx = 0; idx < val.size(); idx++) { + res[idx] = hsaToNativeJSObject(val.get(idx)); } return res; } @@ -88,3 +88,14 @@ function hsaModuleCall(mod, fct, json) { xmlrpcLastResult = xmlrpcclient.execute(mod + "." + fct, params); return hsaToNativeJSObject(xmlrpcLastResult); } + +function pwGen() { + var chars = "0123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz_#%&$+-!?.*="; + var pwLength = 14; + var randomstring = ''; + for (var idx = 0; idx < pwLength; idx++) { + var rnum = Math.floor(Math.random() * chars.length); + randomstring += chars.substring(rnum,rnum+1); + } + return randomstring; +} \ No newline at end of file diff --git a/web/src/main/java/de/hsadmin/web/BinaryPathEditor.java b/web/src/main/java/de/hsadmin/web/BinaryPathEditor.java index 351d066..56c8d8d 100644 --- a/web/src/main/java/de/hsadmin/web/BinaryPathEditor.java +++ b/web/src/main/java/de/hsadmin/web/BinaryPathEditor.java @@ -1,5 +1,7 @@ package de.hsadmin.web; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -39,11 +41,13 @@ public class BinaryPathEditor extends CustomComponent implements IHSEditor { "/usr/lib/cgi-bin/php8.0", "/usr/lib/cgi-bin/php8.1", "/usr/lib/cgi-bin/php8.2", + "/usr/lib/cgi-bin/php8.3", "/usr/lib/cgi-bin/php" }; - private PropertyInfo propertyInfo; private I18N i18n; + private PropertyInfo propertyInfo; + private String[] selectablePathValues; private HorizontalLayout layout; private NativeSelect isManagedInstallationSelect; private NativeSelect managedPathSelect; @@ -52,6 +56,7 @@ public class BinaryPathEditor extends CustomComponent implements IHSEditor { public BinaryPathEditor(final I18N i18n, final PropertyInfo propertyInfo, final String[] values) { this.propertyInfo = propertyInfo; this.i18n = i18n; + this.selectablePathValues = values; this.setCaption(i18n.getText(propertyInfo.getName())); layout = new HorizontalLayout(); layout.setSpacing(true); @@ -73,10 +78,10 @@ public class BinaryPathEditor extends CustomComponent implements IHSEditor { defaultPath = path; } managedPathSelect.setValue(defaultPath); - managedPathSelect.setWidth("400px"); + managedPathSelect.setWidth("436px"); layout.addComponent(managedPathSelect); pathField = new TextField(); - pathField.setWidth("400px"); + pathField.setWidth("436px"); pathField.setVisible(false); layout.addComponent(pathField); isManagedInstallationSelect.setImmediate(true); @@ -102,7 +107,7 @@ public class BinaryPathEditor extends CustomComponent implements IHSEditor { if (value == null) value = ""; if (!(value instanceof String)) value = ""; String text = (String) value; - if (text.isEmpty() || text.startsWith("/usr/bin/") || text.startsWith("/usr/lib/")) { + if (text.isEmpty() || Arrays.asList(selectablePathValues).contains(text)) { isManagedInstallationSelect.setValue(i18n.getText("patheditor.managed")); managedPathSelect.setValue(text); } else { diff --git a/web/src/main/resources/de/hsadmin/web/main.properties b/web/src/main/resources/de/hsadmin/web/main.properties index e5d67ad..5ca238a 100644 --- a/web/src/main/resources/de/hsadmin/web/main.properties +++ b/web/src/main/resources/de/hsadmin/web/main.properties @@ -194,7 +194,7 @@ pac.basepac=Packet type pac.hive=Packet server pac.curinetaddr=IPv4 address patheditor.managed=provided (/usr/bin/..) -patheditor.userspace=Userspace (/home/..) +patheditor.userspace=custom (/home/..) passengerpython=passenger python binary passengernodejs=passenger node binary passengerruby=passenger ruby binary diff --git a/web/src/main/resources/de/hsadmin/web/main_de.properties b/web/src/main/resources/de/hsadmin/web/main_de.properties index 00fb30e..e7c3508 100644 --- a/web/src/main/resources/de/hsadmin/web/main_de.properties +++ b/web/src/main/resources/de/hsadmin/web/main_de.properties @@ -48,10 +48,10 @@ domainoption.backupmxforexternalmx=Backup-MX f domainoption.letsencrypt=Let's Encrypt-Zertifikat domainoption.autoconfig=E-Mail Auto-Konfiguration domainoption.dkim=Domain Key - DKIM -domainoption.cgi=CGI-Funktion aktiv -domainoption.fastcgi=FastCGI-Funktion aktiv -domainoption.passenger=Passenger-Modul aktiv -domainoption.passengerfriendlyerrorpages=Passenger Debug-Modus aktiv +domainoption.cgi=CGI-Funktion +domainoption.fastcgi=FastCGI-Funktion +domainoption.passenger=Passenger-Modul +domainoption.passengerfriendlyerrorpages=Passenger Debug-Modus mysqluser.name=MySQL-Benutzer mysqluser.instance=Datenbanksystem mysqluser.pac=Web-Paket @@ -189,7 +189,7 @@ pac.basepac=Paket-Typ pac.hive=Server/Hive pac.curinetaddr=Netzwerk-Adresse (IPv4) patheditor.managed=vorinstalliert (/usr/bin/..) -patheditor.userspace=Userspace (/home/..) +patheditor.userspace=individuell (/home/..) passengerpython=Passenger Python-Interpreter passengernodejs=Passenger Node-Interpreter passengerruby=Passenger Ruby-Interpreter