diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/BisqElectrumPlugin.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/BisqElectrumPlugin.kt index 7fdf575c53..25b91185e0 100644 --- a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/BisqElectrumPlugin.kt +++ b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/BisqElectrumPlugin.kt @@ -1,83 +1,23 @@ package bisq.gradle.electrum -import bisq.gradle.electrum.tasks.DownloadElectrumBinariesTask -import bisq.gradle.electrum.tasks.ExtractElectrumAppFromDmgFile -import bisq.gradle.electrum.tasks.VerifyElectrumBinariesTask import org.gradle.api.Plugin import org.gradle.api.Project -import org.gradle.api.file.Directory -import org.gradle.api.provider.Provider -import org.gradle.api.tasks.TaskProvider -import org.gradle.api.tasks.bundling.Zip import org.gradle.kotlin.dsl.create -import org.gradle.kotlin.dsl.register -import java.util.* class BisqElectrumPlugin : Plugin { companion object { - private const val DATA_DIR = "electrum_binaries" - private const val DOWNLOADS_DIR = "$DATA_DIR/downloads" - private const val BINARIES_DIR = "$DATA_DIR/binaries" + const val DATA_DIR = "electrum_binaries" } override fun apply(project: Project) { val extension = project.extensions.create("electrum") - val downloadTask: TaskProvider = - project.tasks.register("downloadElectrumBinaries") { - electrumVersion.set(extension.version) + val electrumBinaryDownloader = ElectrumBinaryDownloader(project, extension) + electrumBinaryDownloader.registerTasks() - binaryHashes.appImageHash.set(extension.appImageHash) - binaryHashes.dmgHash.set(extension.dmgHash) - binaryHashes.exeHash.set(extension.exeHash) - - outputDir.set(project.layout.buildDirectory.dir(DOWNLOADS_DIR)) - } - - val verifyElectrumBinariesTask: TaskProvider = - project.tasks.register("verifyElectrumBinaries") { - electrumVersion.set(extension.version) - - val downloadsDirectory: Provider = downloadTask.flatMap { it.outputDir } - inputDirectory.set(downloadsDirectory) - - outputDirectory.set(project.layout.buildDirectory.dir(BINARIES_DIR)) - } - - var extractElectrumAppFromDmgFileTask: TaskProvider? = null - if (isMacOs()) { - extractElectrumAppFromDmgFileTask = - project.tasks.register("extractElectrumAppFromDmgFile") { - electrumVersion.set(extension.version) - inputDirectory.set(verifyElectrumBinariesTask.flatMap { it.inputDirectory }) - outputDirectory.set(project.layout.buildDirectory.dir(BINARIES_DIR)) - } - } - - val packageElectrumBinariesTask: TaskProvider = - project.tasks.register("packageElectrumBinaries") { - - if (isMacOs()) { - dependsOn(extractElectrumAppFromDmgFileTask) - } - - archiveFileName.set("electrum-binaries.zip") - destinationDirectory.set(project.layout.buildDirectory.dir("generated/src/main/resources")) - - val binariesDir: Provider = verifyElectrumBinariesTask.flatMap { it.outputDirectory } - from(binariesDir) - } - - val processResourcesTask = project.tasks.named("processResources") - processResourcesTask.configure { - dependsOn(packageElectrumBinariesTask) - } - } - - private fun isMacOs(): Boolean { - val osName: String = System.getProperty("os.name").toLowerCase(Locale.US) - return osName.contains("mac") || osName.contains("darwin") + val electrumBinaryPackager = ElectrumBinaryPackager(project, electrumBinaryDownloader) + electrumBinaryPackager.registerTasks() } } \ No newline at end of file diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/ElectrumBinaryDownloader.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/ElectrumBinaryDownloader.kt new file mode 100644 index 0000000000..e349a958ca --- /dev/null +++ b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/ElectrumBinaryDownloader.kt @@ -0,0 +1,101 @@ +package bisq.gradle.electrum + +import bisq.gradle.electrum.tasks.DownloadTask +import bisq.gradle.electrum.tasks.FileVerificationTask +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.file.Directory +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.TaskProvider +import org.gradle.kotlin.dsl.register + +class ElectrumBinaryDownloader( + private val project: Project, + private val pluginExtension: BisqElectrumPluginExtension +) { + + companion object { + private const val ELECTRUM_WEBSITE_URL = "https://download.electrum.org" + private const val DOWNLOADS_DIR = "${BisqElectrumPlugin.DATA_DIR}/downloads" + } + + private val taskDownloadDirectory: Provider = project.layout.buildDirectory.dir(DOWNLOADS_DIR) + + val binaryFile: RegularFile + get() = taskDownloadDirectory.get().file(getBinaryFileName()) + + lateinit var lastTask: TaskProvider + + fun registerTasks() { + val binaryDownloadTask: TaskProvider = + project.tasks.register("downloadElectrumBinary") { + downloadUrl.set(getBinaryDownloadUrl()) + sha256hash.set(getBinaryHash()) + downloadDirectory.set(taskDownloadDirectory) + } + + val signatureDownloadTask: TaskProvider = + project.tasks.register("downloadElectrumSignature") { + downloadUrl.set(getSignatureDownloadUrl()) + downloadDirectory.set(taskDownloadDirectory) + } + + lastTask = project.tasks.register("verifyElectrumBinary") { + dependsOn(binaryDownloadTask, signatureDownloadTask) + + fileToVerify.set(binaryDownloadTask.flatMap { it.outputFile }) + detachedSignatureFile.set(signatureDownloadTask.flatMap { it.outputFile }) + publicKeyUrls.set(getPublicKeyUrls()) + publicKeyFingerprints.set(getPublicKeyFingerprints()) + } + } + + private fun getBinaryFileName(): String { + val electrumVersion: String = pluginExtension.version.get() + return when (getOS()) { + OS.LINUX -> "electrum-$electrumVersion-x86_64.AppImage" + OS.MAC_OS -> "electrum-$electrumVersion.dmg" + OS.WINDOWS -> "electrum-$electrumVersion.exe" + } + } + + private fun getBinaryDownloadUrl(): String = "$ELECTRUM_WEBSITE_URL/${pluginExtension.version.get()}/" + getBinaryFileName() + + private fun getSignatureDownloadUrl(): String = "${getBinaryDownloadUrl()}.asc" + + private fun getBinaryHash(): Property { + return when (getOS()) { + OS.LINUX -> pluginExtension.appImageHash + OS.MAC_OS -> pluginExtension.dmgHash + OS.WINDOWS -> pluginExtension.exeHash + } + } + + private fun getPublicKeyUrls() = + setOf( + this::class.java.getResource("/ThomasV.asc")!!, + + // Why failing signature check? + // this::class.java.getResource("/Emzy.asc")!! + + this::class.java.getResource("/SomberNight.asc")!! + ) + + private fun getPublicKeyFingerprints(): Set { + val fingerprints = setOf( + // ThomasV + "6694 D8DE 7BE8 EE56 31BE D950 2BD5 824B 7F94 70E6", + // Emzy + "9EDA FF80 E080 6596 04F4 A76B 2EBB 056F D847 F8A7", + // SomberNight + "0EED CFD5 CAFB 4590 6734 9B23 CA9E EEC4 3DF9 11DC" + ) + + return fingerprints.map { fingerprint -> + fingerprint.filterNot { it.isWhitespace() } // Remove all spaces + .toLowerCase() + }.toSet() + } +} \ No newline at end of file diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/ElectrumBinaryPackager.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/ElectrumBinaryPackager.kt new file mode 100644 index 0000000000..4ba3efd487 --- /dev/null +++ b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/ElectrumBinaryPackager.kt @@ -0,0 +1,64 @@ +package bisq.gradle.electrum + +import bisq.gradle.electrum.tasks.ExtractElectrumAppFromDmgFile +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.file.Directory +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Copy +import org.gradle.api.tasks.TaskProvider +import org.gradle.api.tasks.bundling.Zip +import org.gradle.kotlin.dsl.register + +class ElectrumBinaryPackager( + private val project: Project, + private val binaryDownloader: ElectrumBinaryDownloader, +) { + companion object { + private const val BINARIES_DIR = "${BisqElectrumPlugin.DATA_DIR}/binaries" + } + + private val binariesDir: Provider = project.layout.buildDirectory.dir(BINARIES_DIR) + + fun registerTasks() { + val extractDmgOrCopyTask: TaskProvider = + if (isMacOS()) { + registerDmgExtractionTask() + } else { + registerVerifiedElectrumBinary() + } + + extractDmgOrCopyTask.configure { + dependsOn(binaryDownloader.lastTask) + } + + val packageElectrumBinariesTask: TaskProvider = + project.tasks.register("packageElectrumBinaries") { + dependsOn(extractDmgOrCopyTask) + + archiveFileName.set("electrum-binaries.zip") + destinationDirectory.set(project.layout.buildDirectory.dir("generated/src/main/resources")) + + from(binariesDir) + } + + val processResourcesTask = project.tasks.named("processResources") + processResourcesTask.configure { + dependsOn(packageElectrumBinariesTask) + } + } + + private fun isMacOS() = getOS() == OS.MAC_OS + + private fun registerDmgExtractionTask(): TaskProvider = + project.tasks.register("extractElectrumAppFromDmgFile") { + dmgFile.set(binaryDownloader.binaryFile) + outputDirectory.set(binariesDir) + } + + private fun registerVerifiedElectrumBinary(): TaskProvider = + project.tasks.register("copyVerifiedElectrumBinary") { + from(binaryDownloader.binaryFile.asFile.absolutePath) + into(binariesDir.get().asFile.absolutePath) + } +} \ No newline at end of file diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/OS.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/OS.kt new file mode 100644 index 0000000000..2241817466 --- /dev/null +++ b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/OS.kt @@ -0,0 +1,32 @@ +package bisq.gradle.electrum + +import java.util.* + +enum class OS { + LINUX, MAC_OS, WINDOWS +} + +fun getOS(): OS { + val osName = System.getProperty("os.name").toLowerCase(Locale.US) + if (isLinux(osName)) { + return OS.LINUX + } else if (isMacOs(osName)) { + return OS.MAC_OS + } else if (isWindows(osName)) { + return OS.WINDOWS + } + + throw IllegalStateException("Running on unsupported OS: $osName") +} + +private fun isLinux(osName: String): Boolean { + return osName.contains("linux") +} + +private fun isMacOs(osName: String): Boolean { + return osName.contains("mac") || osName.contains("darwin") +} + +private fun isWindows(osName: String): Boolean { + return osName.contains("win") +} \ No newline at end of file diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/SignatureVerifier.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/SignatureVerifier.kt index 9562835826..a628c19ff5 100644 --- a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/SignatureVerifier.kt +++ b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/SignatureVerifier.kt @@ -20,8 +20,8 @@ class SignatureVerifier( ) { fun verifySignature( + fileToVerify: File, signatureFile: File, - fileToVerify: File ): Boolean { Security.addProvider(BouncyCastleProvider()) diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/DownloadElectrumBinariesTask.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/DownloadElectrumBinariesTask.kt deleted file mode 100644 index 43a178ea8e..0000000000 --- a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/DownloadElectrumBinariesTask.kt +++ /dev/null @@ -1,89 +0,0 @@ -package bisq.gradle.electrum.tasks - -import bisq.gradle.electrum.ElectrumBinaryHashes -import bisq.gradle.electrum.Sha256 -import org.gradle.api.DefaultTask -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Nested -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction -import java.io.File -import java.io.FileOutputStream -import java.net.URL -import java.nio.channels.Channels - -abstract class DownloadElectrumBinariesTask : DefaultTask() { - - companion object { - private const val ELECTRUM_WEBSITE_URL = "https://download.electrum.org" - - fun getBinaryNames(electrumVersion: String): Set { - return setOf( - "electrum-$electrumVersion.dmg", - "electrum-$electrumVersion.exe", - "electrum-$electrumVersion-x86_64.AppImage" - ) - } - } - - @get:Input - abstract val electrumVersion: Property - - @get:Nested - abstract val binaryHashes: ElectrumBinaryHashes - - @get:OutputDirectory - abstract val outputDir: DirectoryProperty - - @TaskAction - fun run() { - val binaryUrls: Set = getBinaryDownloadUrls(electrumVersion.get()) - for (url in binaryUrls) { - if (isFileAlreadyPresent(url)) { - continue - } - - downloadFile(url) - downloadFile("$url.asc") - } - } - - private fun getBinaryDownloadUrls(electrumVersion: String): Set { - val urlPrefix = "$ELECTRUM_WEBSITE_URL/${electrumVersion}" - return getBinaryNames(electrumVersion) - .map { filename -> "$urlPrefix/$filename" } - .toSet() - } - - private fun isFileAlreadyPresent(url: String): Boolean { - val outputFile: File = getOutputFileForUrl(url) - if (outputFile.exists()) { - val hash: String = Sha256.hashFile(outputFile) - val expectedHash = binaryHashes.getHashPropertyForBinary(outputFile).get() - return hash == expectedHash - } - return false - } - - private fun downloadFile(url: String) { - URL(url).openStream().use { inputStream -> - Channels.newChannel(inputStream).use { readableByteChannel -> - println("Downloading: $url") - - val outputFilePath: File = getOutputFileForUrl(url) - FileOutputStream(outputFilePath).use { fileOutputStream -> - fileOutputStream.channel - .transferFrom(readableByteChannel, 0, Long.MAX_VALUE) - } - } - } - } - - private fun getOutputFileForUrl(url: String): File { - val outputDir: File = outputDir.get().asFile - val outputFileName = url.split("/").last() - return outputDir.resolve(outputFileName) - } -} \ No newline at end of file diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/DownloadTask.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/DownloadTask.kt new file mode 100644 index 0000000000..98136599b0 --- /dev/null +++ b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/DownloadTask.kt @@ -0,0 +1,76 @@ +package bisq.gradle.electrum.tasks + +import bisq.gradle.electrum.Sha256 +import org.gradle.api.DefaultTask +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import java.io.FileOutputStream +import java.net.URL +import java.nio.channels.Channels + +abstract class DownloadTask : DefaultTask() { + + @get:Input + abstract val downloadUrl: Property + + @get:Input + abstract val sha256hash: Property + + @get:OutputDirectory + abstract val downloadDirectory: DirectoryProperty + + @get:OutputFile + val outputFile: Provider + get() = downloadDirectory.file(fileName) + + private val fileName: String + get() = downloadUrl.get().split("/").last() + + init { + sha256hash.convention("") + } + + @TaskAction + fun download() { + if (isFileAlreadyPresent()) { + return + } + downloadFile() + } + + private fun isFileAlreadyPresent(): Boolean { + if (outputFile.get().asFile.exists()) { + if (sha256hash.get().isNotEmpty()) { + return verifySha256Hash() + } + return true + } + return false + } + + private fun downloadFile() { + val url = downloadUrl.get() + URL(url).openStream().use { inputStream -> + Channels.newChannel(inputStream).use { readableByteChannel -> + println("Downloading: $url") + + FileOutputStream(outputFile.get().asFile).use { fileOutputStream -> + fileOutputStream.channel + .transferFrom(readableByteChannel, 0, Long.MAX_VALUE) + } + } + } + } + + private fun verifySha256Hash(): Boolean { + val hash: String = Sha256.hashFile(outputFile.get().asFile) + val expectedHash = sha256hash.get() + return hash == expectedHash + } +} \ No newline at end of file diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/ExtractElectrumAppFromDmgFile.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/ExtractElectrumAppFromDmgFile.kt index 7d99fb7dc1..fe6ae21e59 100644 --- a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/ExtractElectrumAppFromDmgFile.kt +++ b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/ExtractElectrumAppFromDmgFile.kt @@ -2,12 +2,12 @@ package bisq.gradle.electrum.tasks import org.gradle.api.DefaultTask import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory +import org.gradle.api.file.RegularFile +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.InputFile import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction -import java.io.File import java.util.concurrent.TimeUnit @@ -19,24 +19,23 @@ abstract class ExtractElectrumAppFromDmgFile : DefaultTask() { private const val MOUNTED_ELECTRUM_APP_PATH = "$MOUNT_DIR/$ELECTRUM_APP" private const val CMD_TIMEOUT: Long = 25 - } - - @get:Input - abstract val electrumVersion: Property + private const val ELECTRUM_BINARY_PATH_IN_APP_FILE = "Contents/MacOS/run_electrum" + } - @get:InputDirectory - abstract val inputDirectory: DirectoryProperty + @get:InputFile + abstract val dmgFile: RegularFileProperty @get:OutputDirectory abstract val outputDirectory: DirectoryProperty - private val electrumAppDestinationFile: File - get() = outputDirectory.get().asFile.resolve(ELECTRUM_APP) + @get:OutputDirectory + val electrumAppDestinationFile: Provider + get() = outputDirectory.file(ELECTRUM_APP) @TaskAction fun extract() { - if (electrumAppDestinationFile.exists()) { + if (electrumAppDestinationFile.get().asFile.resolve(ELECTRUM_BINARY_PATH_IN_APP_FILE).exists()) { return } @@ -46,8 +45,7 @@ abstract class ExtractElectrumAppFromDmgFile : DefaultTask() { } private fun attachDmgFile() { - val dmgFile = inputDirectory.get().asFile.resolve("electrum-${electrumVersion.get()}.dmg") - val attachDmgFile: Process = ProcessBuilder("hdiutil", "attach", dmgFile.absolutePath).start() + val attachDmgFile: Process = ProcessBuilder("hdiutil", "attach", dmgFile.get().asFile.absolutePath).start() val isSuccess: Boolean = attachDmgFile.waitFor(CMD_TIMEOUT, TimeUnit.SECONDS) if (!isSuccess) { throw IllegalStateException("Could not attach DMG file.") @@ -55,7 +53,7 @@ abstract class ExtractElectrumAppFromDmgFile : DefaultTask() { } private fun copyElectrumAppToOutputDirectory() { - val destinationDir = electrumAppDestinationFile.absolutePath + val destinationDir = outputDirectory.get().asFile.absolutePath val copyProcess: Process = ProcessBuilder( "cp", "-r", MOUNTED_ELECTRUM_APP_PATH, destinationDir ).start() diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/FileVerificationTask.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/FileVerificationTask.kt new file mode 100644 index 0000000000..bf50576a15 --- /dev/null +++ b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/FileVerificationTask.kt @@ -0,0 +1,45 @@ +package bisq.gradle.electrum.tasks + +import bisq.gradle.electrum.SignatureVerifier +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.SetProperty +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.TaskAction +import java.net.URL + +abstract class FileVerificationTask : DefaultTask() { + + @get:InputFile + abstract val fileToVerify: RegularFileProperty + + @get:InputFile + abstract val detachedSignatureFile: RegularFileProperty + + @get:Input + abstract val publicKeyUrls: SetProperty + + @get:Input + abstract val publicKeyFingerprints: SetProperty + + @TaskAction + fun verify() { + val signatureVerifier = SignatureVerifier( + allPublicKeyUrls = publicKeyUrls.get(), + publicKeyFingerprints = publicKeyFingerprints.get() + ) + + val isSignatureValid = signatureVerifier.verifySignature( + signatureFile = detachedSignatureFile.get().asFile, + fileToVerify = fileToVerify.get().asFile + ) + + if (!isSignatureValid) { + throw GradleException( + "Signature verification failed for ${fileToVerify.get().asFile.absolutePath}." + ) + } + } +} \ No newline at end of file diff --git a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/VerifyElectrumBinariesTask.kt b/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/VerifyElectrumBinariesTask.kt deleted file mode 100644 index 399e258a56..0000000000 --- a/build-logic/electrum-binaries/src/main/kotlin/bisq/gradle/electrum/tasks/VerifyElectrumBinariesTask.kt +++ /dev/null @@ -1,84 +0,0 @@ -package bisq.gradle.electrum.tasks - -import bisq.gradle.electrum.SignatureVerifier -import org.gradle.api.DefaultTask -import org.gradle.api.GradleException -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction -import java.io.File -import java.nio.file.Files -import java.nio.file.StandardCopyOption - - -abstract class VerifyElectrumBinariesTask : DefaultTask() { - - @get:Input - abstract val electrumVersion: Property - - @get:InputDirectory - abstract val inputDirectory: DirectoryProperty - - @get:OutputDirectory - abstract val outputDirectory: DirectoryProperty - - private val signatureVerifier = SignatureVerifier( - allPublicKeyUrls = getPublicKeyUrls(), - publicKeyFingerprints = getPublicKeyFingerprints() - ) - - @TaskAction - fun run() { - val binaryNames: Set = DownloadElectrumBinariesTask.getBinaryNames(electrumVersion.get()) - val downloadsDirectory = inputDirectory.asFile.get() - val outputDir: File = outputDirectory.asFile.get() - - for (filename in binaryNames) { - println("Verifying: $filename") - val fileToVerify: File = downloadsDirectory.resolve(filename) - val isSignatureValid = signatureVerifier.verifySignature( - signatureFile = downloadsDirectory.resolve("$filename.asc"), - fileToVerify = fileToVerify - ) - - if (!isSignatureValid) { - throw GradleException("Signature verification failed for $filename.") - } - - if (!filename.endsWith(".dmg")) { - val targetPath = outputDir.resolve(filename).toPath() - Files.move(fileToVerify.toPath(), targetPath, StandardCopyOption.REPLACE_EXISTING) - } - } - } - - private fun getPublicKeyUrls() = - setOf( - this::class.java.getResource("/ThomasV.asc")!!, - - // Why failing signature check? - // this::class.java.getResource("/Emzy.asc")!! - - this::class.java.getResource("/SomberNight.asc")!! - ) - - private fun getPublicKeyFingerprints(): Set { - val fingerprints = setOf( - // ThomasV - "6694 D8DE 7BE8 EE56 31BE D950 2BD5 824B 7F94 70E6", - // Emzy - "9EDA FF80 E080 6596 04F4 A76B 2EBB 056F D847 F8A7", - // SomberNight - "0EED CFD5 CAFB 4590 6734 9B23 CA9E EEC4 3DF9 11DC" - ) - - return fingerprints.map { fingerprint -> - fingerprint.filterNot { it.isWhitespace() } // Remove all spaces - .toLowerCase() - }.toSet() - } - -} \ No newline at end of file diff --git a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java index e0235d82d9..a71a0df09e 100644 --- a/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java +++ b/wallets/electrum/src/main/java/bisq/wallets/electrum/ElectrumProcess.java @@ -110,7 +110,7 @@ public Optional getElectrumVersion() { return Optional.empty(); } - private String getBinarySuffix() { + public static String getBinarySuffix() { if (OsUtils.isLinux()) { return ElectrumBinaryExtractor.LINUX_BINARY_SUFFIX; } else if (OsUtils.isOSX()) { diff --git a/wallets/electrum/src/test/java/bisq/wallets/electrum/ElectrumBinaryExtractorTest.java b/wallets/electrum/src/test/java/bisq/wallets/electrum/ElectrumBinaryExtractorTest.java index ccb761d05d..36b2c54011 100644 --- a/wallets/electrum/src/test/java/bisq/wallets/electrum/ElectrumBinaryExtractorTest.java +++ b/wallets/electrum/src/test/java/bisq/wallets/electrum/ElectrumBinaryExtractorTest.java @@ -18,8 +18,7 @@ package bisq.wallets.electrum; import bisq.common.util.FileUtils; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; +import org.junit.jupiter.api.Test; import java.io.File; import java.io.IOException; @@ -35,12 +34,9 @@ public ElectrumBinaryExtractorTest() throws IOException { binaryExtractor = new ElectrumBinaryExtractor(destDirPath); } - @ParameterizedTest - @ValueSource(strings = { - ElectrumBinaryExtractor.LINUX_BINARY_SUFFIX, - ElectrumBinaryExtractor.WINDOWS_BINARY_SUFFIX - }) - void extractBinaries(String binarySuffix) { + @Test + void extractBinaries() { + String binarySuffix = ElectrumProcess.getBinarySuffix(); Path electrumBinaryPath = binaryExtractor.extractFileWithSuffix(binarySuffix); File electrumBinary = electrumBinaryPath.toFile();