diff --git a/src/main/java/build.ps1 b/src/main/java/build.ps1 index e9d5d10..d7d8b83 100644 --- a/src/main/java/build.ps1 +++ b/src/main/java/build.ps1 @@ -10,7 +10,8 @@ $modules = $( "result", "javafx.controls", "javafx.fxml", - "org.apache.commons.cli" + "org.apache.commons.cli", + "com.jcraft.jsch" ) $addModules = $modules -join "," javac --module-path $modulePath --add-modules $addModules .\name\nathanmcrae\numbersstation\*.java -d out diff --git a/src/main/java/name/nathanmcrae/numbersstation/StationSettingsController.java b/src/main/java/name/nathanmcrae/numbersstation/StationSettingsController.java index 55aee29..ca7e072 100644 --- a/src/main/java/name/nathanmcrae/numbersstation/StationSettingsController.java +++ b/src/main/java/name/nathanmcrae/numbersstation/StationSettingsController.java @@ -3,6 +3,9 @@ package name.nathanmcrae.numbersstation; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.dataformat.xml.XmlMapper; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; import java.io.File; import java.io.IOException; import java.time.format.DateTimeFormatter; @@ -11,6 +14,7 @@ import java.time.LocalTime; import java.util.logging.Level; import java.util.logging.Logger; import java.util.Optional; +import javafx.beans.binding.Bindings; import javafx.beans.property.BooleanProperty; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; @@ -27,6 +31,7 @@ import javafx.fxml.FXMLLoader; import javafx.scene.control.Button; import javafx.scene.control.CheckBox; import javafx.scene.control.DatePicker; +import javafx.scene.control.Label; import javafx.scene.control.ListCell; import javafx.scene.control.ListView; import javafx.scene.control.RadioButton; @@ -45,8 +50,14 @@ import javafx.stage.Stage; import javafx.util.Callback; public class StationSettingsController { + public enum ConnectionStatus { + SUCCESS, FAILURE, NEUTRAL + } + private static final Logger logger = Logger.getLogger(Main.class.getName()); + private ObjectProperty connectionTestStatus = new SimpleObjectProperty<>(ConnectionStatus.NEUTRAL); + private StringProperty connectionTestDescription = new SimpleStringProperty(); private IntegerProperty digitsPerGroup = new SimpleIntegerProperty(); private StringProperty externalProgramCommand = new SimpleStringProperty(); private BooleanProperty manageScheduleExternally = new SimpleBooleanProperty(); @@ -61,6 +72,9 @@ public class StationSettingsController { private StringProperty scheduleStartTime = new SimpleStringProperty(); private StringProperty username = new SimpleStringProperty(); + @FXML + private Label connectionTestStatusLabel; + @FXML private TextField stationNameField; @@ -128,6 +142,17 @@ public class StationSettingsController { @FXML private void initialize() { + connectionTestStatusLabel.styleProperty().bind(Bindings.createStringBinding(() -> { + switch (connectionTestStatus.get()) { + case SUCCESS: + return "-fx-text-fill: green;"; + case FAILURE: + return "-fx-text-fill: red;"; + default: + return "-fx-text-fill: black;"; + } + }, connectionTestStatus)); + connectionTestStatusLabel.textProperty().bindBidirectional(connectionTestDescription); externalProgramCommandField.textProperty().bindBidirectional(externalProgramCommand); manageScheduleExternallyCheckBox.selectedProperty().bindBidirectional(manageScheduleExternally); stationNameField.textProperty().bindBidirectional(stationName); @@ -409,6 +434,37 @@ public class StationSettingsController { @FXML private void handleTestConnectionButtonPress() { + if (messageMethod.get() == StationSettings.MessageMethod.SFTP) { + String host = stationAddress.get(); + String user = username.get(); + String pass = password.get(); + + connectionTestDescription.set("Testing connection"); + connectionTestStatus.set(ConnectionStatus.NEUTRAL); + + JSch jsch = new JSch(); + try { + Session session = jsch.getSession(user, host, 22); + session.setPassword(pass); + session.setConfig("StrictHostKeyChecking", "no"); + session.connect(30000); // 30 seconds timeout + + if (session.isConnected()) { + logger.log(Level.INFO, "SFTP connection successful"); + connectionTestDescription.set("Connection succeeded"); + connectionTestStatus.set(ConnectionStatus.SUCCESS); + session.disconnect(); + } else { + connectionTestDescription.set("No error, but not connected"); + connectionTestStatus.set(ConnectionStatus.FAILURE); + logger.log(Level.SEVERE, "SFTP connection failed"); + } + } catch (JSchException e) { + connectionTestDescription.set(e.getMessage()); + connectionTestStatus.set(ConnectionStatus.FAILURE); + logger.log(Level.SEVERE, "SFTP connection failed", e); + } + } } @FXML diff --git a/src/main/java/name/nathanmcrae/numbersstation/StationSettingsView.fxml b/src/main/java/name/nathanmcrae/numbersstation/StationSettingsView.fxml index f138b1e..841ba2f 100644 --- a/src/main/java/name/nathanmcrae/numbersstation/StationSettingsView.fxml +++ b/src/main/java/name/nathanmcrae/numbersstation/StationSettingsView.fxml @@ -98,6 +98,7 @@