/*
* sftp-reader
* Copyright (C) 2020 Memoriav
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package org.memobase
import java.io.Closeable
import java.io.File
import java.net.ConnectException
import java.net.UnknownHostException
import java.util.Properties
import kotlin.system.exitProcess
import net.schmizz.sshj.SSHClient
import net.schmizz.sshj.sftp.FileAttributes
import net.schmizz.sshj.sftp.FileMode
import net.schmizz.sshj.sftp.OpenMode
import net.schmizz.sshj.sftp.RemoteFile
import net.schmizz.sshj.sftp.SFTPClient
import net.schmizz.sshj.userauth.UserAuthException
import org.apache.logging.log4j.LogManager
class SftpClient(sftpSettings: Properties) : Closeable {
private val log = LogManager.getLogger("SftpClient")
private val ssh = SSHClient()
private val instance: SFTPClient
init {
try {
ssh.loadKnownHosts()
ssh.addHostKeyVerifier(sftpSettings.getProperty("fingerprint"))
ssh.connect(sftpSettings.getProperty("host"))
ssh.authPassword(sftpSettings.getProperty("user"), sftpSettings.getProperty("password"))
instance = ssh.newSFTPClient()
} catch (ex: UserAuthException) {
log.error("SFTP User Authentication Error: Invalid user authentication supplied.")
exitProcess(1)
} catch (ex: ConnectException) {
log.error("SFTP Connection Exception: ${ex.message}.")
exitProcess(1)
} catch (ex: UnknownHostException) {
log.error("SFTP Host Not Found: ${ex.message}.")
exitProcess(1)
} catch (ex: Exception) {
ex.printStackTrace()
log.error("SSH Exception: ${ex.localizedMessage}")
exitProcess(1)
}
}
fun listFiles(path: String): List {
return ls(path).filter { fileAttributes(it).mode.type == FileMode.Type.REGULAR }
}
fun open(file: File): RemoteFile {
return instance.open(file.path, setOf(OpenMode.READ))
}
private fun fileAttributes(path: String): FileAttributes {
return instance.lstat(path)
}
private fun ls(path: String): List {
return instance.ls(path).map { it.path }
}
override fun close() {
instance.close()
ssh.disconnect()
}
}