From 479bc8cd8d652025c00559ce7ecc9702f0c6c7a6 Mon Sep 17 00:00:00 2001 From: az Date: Sun, 30 Apr 2023 20:25:30 +0200 Subject: [PATCH] fix installation gopass bridge and gopass-jsonapi --- .../provs/desktop/domain/DesktopService.kt | 2 +- .../desktop/infrastructure/GopassBridge.kt | 62 ++++++++++--------- .../ubuntu/filesystem/base/Filesystem.kt | 2 +- .../infrastructure/GopassBridgeKtTest.kt | 12 ++-- .../desktop/infrastructure/GopassKtTest.kt | 4 +- 5 files changed, 43 insertions(+), 39 deletions(-) diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopService.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopService.kt index 1f4cced..ea0a4df 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopService.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/domain/DesktopService.kt @@ -152,7 +152,7 @@ fun Prov.provisionBasicDesktop( installFirefox() installGopass() configureGopass(publicGpgKey = gpg?.publicKey) - installGopassBridgeJsonApi() + installGopassJsonApi() downloadGopassBridge() installRedshift() diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridge.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridge.kt index 82be5fa..21c9e6d 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridge.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridge.kt @@ -6,7 +6,6 @@ import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.* import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.isPackageInstalled import org.domaindrivenarchitecture.provs.framework.ubuntu.web.base.downloadFromURL -import java.io.File fun Prov.downloadGopassBridge() = task { @@ -22,10 +21,10 @@ fun Prov.downloadGopassBridge() = task { // needs manual installation with: firefox Downloads/gopass_bridge-0.8.0-fx.xpi } -fun Prov.installGopassBridgeJsonApi() = task { +fun Prov.installGopassJsonApi() = taskWithResult { // see https://github.com/gopasspw/gopass-jsonapi val gopassJsonApiVersion = "1.11.1" - val requiredGopassVersion = "1.14.4" + val requiredGopassVersion = "1.12.7" val filename = "gopass-jsonapi_${gopassJsonApiVersion}_linux_amd64.deb" val downloadUrl = "-L https://github.com/gopasspw/gopass-jsonapi/releases/download/v$gopassJsonApiVersion/$filename" val downloadDir = "${userHome()}Downloads" @@ -46,51 +45,56 @@ fun Prov.installGopassBridgeJsonApi() = task { ) } } else { - addResultToEval( - ProvResult( - false, - "gopass not initialized correctly. You can initialize gopass with: \"gopass init\"" - ) + ProvResult( + false, + "gopass not initialized correctly. You can initialize gopass with: \"gopass init\"" ) } } else { if (installedJsonApiVersion.startsWith("gopass-jsonapi version $gopassJsonApiVersion")) { - addResultToEval(ProvResult(true, out = "Version $gopassJsonApiVersion of gopass-jsonapi is already installed")) + ProvResult(true, out = "Version $gopassJsonApiVersion of gopass-jsonapi is already installed") } else { - addResultToEval( - ProvResult( - false, - err = "gopass-jsonapi (version $gopassJsonApiVersion) cannot be installed as version $installedJsonApiVersion is already installed." + - " Upgrading gopass-jsonapi is currently not supported by provs." - ) + ProvResult( + false, + err = "gopass-jsonapi (version $gopassJsonApiVersion) cannot be installed as version $installedJsonApiVersion is already installed." + + " Upgrading gopass-jsonapi is currently not supported by provs." ) } } } -fun Prov.configureGopassWrapperShForFirefox() = task { +/** + * Configures apparmor to allow firefox to access to gopass_wrapper.sh in avoid + * the error "An unexpected error occurred - Is your browser correctly set up for gopass? ..." + * when trying to use gopass bridge. + * This error appears in spite of having already set up gopass-jsonapi correctly. + */ +fun Prov.configureApparmorForGopassWrapperShForFirefox() = task { val appArmorFile = "/etc/apparmor.d/usr.bin.firefox" + val gopassAccessPermission = "owner @{HOME}/.config/gopass/gopass_wrapper.sh Ux," + val insertAfterText = "# per-user firefox configuration\n" - if (checkFile(appArmorFile)) { - addTextToFile( - "\nowner @{HOME}/.config/gopass/gopass_wrapper.sh Ux\n", - File(appArmorFile), - sudo = true + if (checkFile(appArmorFile) && !fileContainsText(appArmorFile, gopassAccessPermission, true)) { + replaceTextInFile( + appArmorFile, insertAfterText, "$insertAfterText $gopassAccessPermission\n" ) + cmd("systemctl reload apparmor", sudo = true) } - - cmd("systemctl reload apparmor", sudo = true) } -fun Prov.configureGopassBridgeJsonApi() = task { +fun Prov.configureGopassJsonApi() = taskWithResult { if (isPackageInstalled("gopass-jsonapi")) { - // configure for firefox and choose default for each: - // "Install for all users? [y/N/q]", - // "In which path should gopass_wrapper.sh be installed? [/home/testuser/.config/gopass]" - // "Wrapper Script for gopass_wrapper.sh ..." - configureGopassWrapperShForFirefox() + // configures gopass-jsonapi for firefox and chooses default for each: + // * "Install for all users? [y/N/q]", + // * "In which path should gopass_wrapper.sh be installed? [/home//.config/gopass]" + // * "Wrapper Script for gopass_wrapper.sh ..." + // + // I.e. creates file "gopass_wrapper.sh" in "/home//.config/gopass" as well as + // the manifest file "/home//.mozilla/native-messaging-hosts/com.justwatch.gopass.json" cmd("printf \"\\n\\n\\n\" | gopass-jsonapi configure --browser firefox") + + configureApparmorForGopassWrapperShForFirefox() } else { ProvResult( false, diff --git a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/Filesystem.kt b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/Filesystem.kt index 10a7101..ac1c814 100644 --- a/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/Filesystem.kt +++ b/src/main/kotlin/org/domaindrivenarchitecture/provs/framework/ubuntu/filesystem/base/Filesystem.kt @@ -251,7 +251,7 @@ fun Prov.replaceTextInFile(file: String, oldText: String, replacement: String) = } -fun Prov.replaceTextInFile(file: String, oldText: Regex, replacement: String) = task { +fun Prov.replaceTextInFile(file: String, oldText: Regex, replacement: String) = taskWithResult { // todo: only use sudo for root or if owner different from current val content = fileContent(file, true) if (content != null) { diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridgeKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridgeKtTest.kt index c553868..fe90a29 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridgeKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassBridgeKtTest.kt @@ -51,8 +51,8 @@ internal class GopassBridgeKtTest { // when val res = prov.task { - installGopassBridgeJsonApi() - configureGopassBridgeJsonApi() + installGopassJsonApi() + configureGopassJsonApi() } // then @@ -79,8 +79,8 @@ internal class GopassBridgeKtTest { // when val res = prov.task { - installGopassBridgeJsonApi() - configureGopassBridgeJsonApi() + installGopassJsonApi() + configureGopassJsonApi() } // then @@ -107,8 +107,8 @@ internal class GopassBridgeKtTest { // when val res = prov.task { - installGopassBridgeJsonApi() - configureGopassBridgeJsonApi() + installGopassJsonApi() + configureGopassJsonApi() } // then diff --git a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassKtTest.kt b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassKtTest.kt index 482fbec..efab669 100644 --- a/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassKtTest.kt +++ b/src/test/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/GopassKtTest.kt @@ -80,8 +80,8 @@ internal class GopassKtTest { cmd("printf \"\\ntest\\ntest@test.org\\n\" | gopass init " + gpgFingerprint(pubKey.plain())) // gopass init in default location with gpg-key-fingerprint of given key } downloadGopassBridge() - installGopassBridgeJsonApi() - configureGopassBridgeJsonApi() + installGopassJsonApi() + configureGopassJsonApi() } // then