fix gopassBridge by gopassInitStoreFolder

This commit is contained in:
az 2023-04-20 09:47:14 +02:00
parent c725cc0202
commit 87df8b9dc3
6 changed files with 55 additions and 88 deletions

View file

@ -151,11 +151,13 @@ fun Prov.provisionBasicDesktop(
installFirefox() installFirefox()
installGopass() installGopass()
configureGopass(publicGpgKey = gpg?.publicKey)
installGopassBridgeJsonApi() installGopassBridgeJsonApi()
downloadGopassBridge() downloadGopassBridge()
installRedshift()
installRedshift()
configureRedshift() configureRedshift()
configureNoSwappiness() configureNoSwappiness()
configureBash() configureBash()
installVirtualBoxGuestAdditions() installVirtualBoxGuestAdditions()

View file

@ -2,9 +2,11 @@ package org.domaindrivenarchitecture.provs.desktop.infrastructure
import org.domaindrivenarchitecture.provs.framework.core.Prov import org.domaindrivenarchitecture.provs.framework.core.Prov
import org.domaindrivenarchitecture.provs.framework.core.ProvResult import org.domaindrivenarchitecture.provs.framework.core.ProvResult
import org.domaindrivenarchitecture.provs.framework.core.Secret
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.* 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.aptInstall
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.isPackageInstalled import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.isPackageInstalled
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.gpgFingerprint
import org.domaindrivenarchitecture.provs.framework.ubuntu.web.base.downloadFromURL import org.domaindrivenarchitecture.provs.framework.ubuntu.web.base.downloadFromURL
@ -34,29 +36,34 @@ fun Prov.installGopass(
if (result.success) { if (result.success) {
cmd("sudo dpkg -i $path/gopass_${version}_linux_amd64.deb") cmd("sudo dpkg -i $path/gopass_${version}_linux_amd64.deb")
// Cross-check if installation was successful // Cross-check if installation was successful
addResultToEval(ProvResult(checkGopassVersion(version))) return@taskWithResult ProvResult(checkGopassVersion(version))
} else { } else {
addResultToEval(ProvResult(false, err = "Gopass could not be installed. " + result.err)) return@taskWithResult ProvResult(false, err = "Gopass could not be installed. " + result.err)
} }
} }
fun Prov.configureGopass(gopassRootFolder: String? = null) = taskWithResult() { fun Prov.configureGopass(gopassRootFolder: String? = null, publicGpgKey: Secret? = null) = taskWithResult {
val configFile = ".config/gopass/config.yml" val configFile = ".config/gopass/config.yml"
val defaultRootFolder = userHome() + ".password-store"
val rootFolder = gopassRootFolder ?: defaultRootFolder
if (checkFile(configFile)) { if (checkFile(configFile)) {
return@taskWithResult ProvResult(true, out = "Gopass already configured in file $configFile") return@taskWithResult ProvResult(true, out = "Gopass already configured in file $configFile")
} }
if ((gopassRootFolder != null) && (!gopassRootFolder.startsWith("/"))) { if ((gopassRootFolder != null) && (!gopassRootFolder.startsWith("/"))) {
return@taskWithResult ProvResult(false, err = "Gopass cannot be initialized with a relative path or path starting with ~") return@taskWithResult ProvResult(false, err = "Gopass cannot be initialized with a relative path or path starting with ~ ($gopassRootFolder)")
} }
// use default
createDir(rootFolder) val defaultRootFolder = userHome() + ".password-store"
val gopassRoot = gopassRootFolder ?: defaultRootFolder
// initialize root store
val fingerprint = publicGpgKey?.let { gpgFingerprint(it.plain()) }
gopassInitStoreFolder(gopassRoot, fingerprint)
createDirs(".config/gopass") createDirs(".config/gopass")
createFile(configFile, gopassConfig(rootFolder)) createFile(configFile, gopassConfig(gopassRoot))
// auto-completion // auto-completion
configureBashForUser() configureBashForUser()
@ -69,9 +76,8 @@ fun Prov.gopassMountStore(storeName: String, path: String) = task {
} }
@Suppress("unused") fun Prov.gopassInitStoreFolder(path: String, gpgFingerprint: String? = null ) = task {
fun Prov.gopassInitStore(storeName: String, indexOfRecepientKey: Int = 0) = task { createFile("$path/.gpg-id", gpgFingerprint ?: "_replace_this_by_a_fingerprint_of_a_public_gpg_key_")
cmd("printf \"$indexOfRecepientKey\\n\" | gopass init --store=$storeName")
} }
@ -105,4 +111,4 @@ internal fun Prov.checkGopassVersion(version: String): Boolean {
internal fun Prov.gopassVersion(): String? { internal fun Prov.gopassVersion(): String? {
val result = cmdNoEval("gopass -v") val result = cmdNoEval("gopass -v")
return if (!result.success) null else result.out return if (!result.success) null else result.out
} }

View file

@ -73,7 +73,7 @@ fun Prov.isPackageInstalled(packageName: String): Boolean {
/** /**
* Removes a package including its configuration and data files * Removes a package including its configuration and data file
*/ */
@Suppress("unused") // used externally @Suppress("unused") // used externally
fun Prov.aptPurge(packageName: String): Boolean { fun Prov.aptPurge(packageName: String): Boolean {

View file

@ -1,16 +1,12 @@
package org.domaindrivenarchitecture.provs.desktop.infrastructure package org.domaindrivenarchitecture.provs.desktop.infrastructure
import org.domaindrivenarchitecture.provs.framework.core.Prov
import org.domaindrivenarchitecture.provs.framework.core.ProvResult
import org.domaindrivenarchitecture.provs.framework.core.Secret import org.domaindrivenarchitecture.provs.framework.core.Secret
import org.domaindrivenarchitecture.provs.framework.core.docker.exitAndRmContainer import org.domaindrivenarchitecture.provs.framework.core.docker.exitAndRmContainer
import org.domaindrivenarchitecture.provs.framework.core.local import org.domaindrivenarchitecture.provs.framework.core.local
import org.domaindrivenarchitecture.provs.framework.core.processors.ContainerStartMode import org.domaindrivenarchitecture.provs.framework.core.processors.ContainerStartMode
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.KeyPair import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.KeyPair
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.configureGpgKeys import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.configureGpgKeys
import org.domaindrivenarchitecture.provs.test.defaultTestContainer import org.domaindrivenarchitecture.provs.test.defaultTestContainer
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
import org.domaindrivenarchitecture.provs.test.tags.ExtensiveContainerTest import org.domaindrivenarchitecture.provs.test.tags.ExtensiveContainerTest
import org.domaindrivenarchitecture.provs.test.tags.NonCi import org.domaindrivenarchitecture.provs.test.tags.NonCi
import org.domaindrivenarchitecture.provs.test_keys.privateGPGSnakeoilKey import org.domaindrivenarchitecture.provs.test_keys.privateGPGSnakeoilKey
@ -27,11 +23,10 @@ internal class GopassBridgeKtTest {
fun test_downloadGopassBridge() { fun test_downloadGopassBridge() {
// given // given
local().exitAndRmContainer("provs_test") local().exitAndRmContainer("provs_test")
val a = defaultTestContainer() val prov = defaultTestContainer()
a.aptInstallCurl()
// when // when
val res = a.downloadGopassBridge() val res = prov.downloadGopassBridge()
// then // then
assertTrue(res.success) assertTrue(res.success)
@ -42,26 +37,20 @@ internal class GopassBridgeKtTest {
fun test_install_and_configure_GopassBridgeJsonApi() { fun test_install_and_configure_GopassBridgeJsonApi() {
// given // given
local().exitAndRmContainer("provs_test") local().exitAndRmContainer("provs_test")
val a = defaultTestContainer() val prov = defaultTestContainer()
val preparationResult = a.task { val preparationResult = prov.task {
aptInstallCurl()
configureGpgKeys( configureGpgKeys(
KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())), KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())),
trust = true, trust = true,
skipIfExistin = false skipIfExistin = false
) )
installGopass() installGopass()
if (!chk("gopass ls")) { configureGopass(publicGpgKey = Secret(publicGPGSnakeoilKey()))
// configure/init gopass in default location with gpg-key-fingerprint of snakeoil keys
cmd("printf \"\\ntest\\ntest@test.org\\n\" | gopass init 0x0674104CA81A4905")
} else {
ProvResult(true, out = "gopass already configured")
}
} }
assertTrue(preparationResult.success) assertTrue(preparationResult.success)
// when // when
val res = a.task { val res = prov.task {
installGopassBridgeJsonApi() installGopassBridgeJsonApi()
configureGopassBridgeJsonApi() configureGopassBridgeJsonApi()
} }
@ -70,33 +59,26 @@ internal class GopassBridgeKtTest {
assertTrue(res.success) assertTrue(res.success)
} }
@ContainerTest @ExtensiveContainerTest
@Test @Test
@NonCi @NonCi
@Disabled // long running test (> 1 min); if needed enable test and run manually @Disabled // long running test (> 1 min); if needed enable test and run manually
fun test_install_GopassBridgeJsonApi_with_incompatible_gopass_jsonapi_version_installed() { fun test_install_GopassBridgeJsonApi_with_incompatible_gopass_jsonapi_version_installed() {
// given // given
val a = defaultTestContainer(ContainerStartMode.CREATE_NEW_KILL_EXISTING) val prov = defaultTestContainer(ContainerStartMode.CREATE_NEW_KILL_EXISTING)
val preparationResult = a.task { val preparationResult = prov.task {
aptInstallCurl()
configureGpgKeys( configureGpgKeys(
KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())), KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())),
trust = true, trust = true,
skipIfExistin = false skipIfExistin = false
) )
installGopass("1.11.0", enforceVersion = true, "1ec9e0dfcfd9bcc241943e1a7d92f31bf3e66bb16f61ae5d079981325c31baa6") installGopass("1.11.0", enforceVersion = true, "1ec9e0dfcfd9bcc241943e1a7d92f31bf3e66bb16f61ae5d079981325c31baa6")
if (!chk("gopass ls")) { configureGopass(publicGpgKey = Secret(publicGPGSnakeoilKey()))
// configure gopass in default location with gpg-key-fingerprint of snakeoil keys
cmd("printf \"\\ntest\\ntest@test.org\\n\" | gopass init 0x0674104CA81A4905")
} else {
ProvResult(true, out = "gopass already configured")
}
} }
assertTrue(preparationResult.success) assertTrue(preparationResult.success)
// when // when
val res = a.task { val res = prov.task {
installGopassBridgeJsonApi() installGopassBridgeJsonApi()
configureGopassBridgeJsonApi() configureGopassBridgeJsonApi()
} }
@ -105,32 +87,26 @@ internal class GopassBridgeKtTest {
assertFalse(res.success) assertFalse(res.success)
} }
@ContainerTest @ExtensiveContainerTest
@Test @Test
@NonCi @NonCi
@Disabled // long running test (> 1 min); if needed enable test and run manually @Disabled // long running test (> 1 min); if needed, enable test and run manually
fun test_install_GopassBridgeJsonApi_with_incompatible_gopass_version_installed() { fun test_install_GopassBridgeJsonApi_with_incompatible_gopass_version_installed() {
// given // given
val a = defaultTestContainer(ContainerStartMode.CREATE_NEW_KILL_EXISTING) val prov = defaultTestContainer(ContainerStartMode.CREATE_NEW_KILL_EXISTING)
val preparationResult = a.task { val preparationResult = prov.task {
aptInstallCurl()
configureGpgKeys( configureGpgKeys(
KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())), KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())),
trust = true, trust = true,
skipIfExistin = false skipIfExistin = false
) )
installGopass("1.9.0", enforceVersion = true, "fe13ef810d7fe200495107161e99eac081368aa0ce5e53971b1bd47a64eba4db") installGopass("1.9.0", enforceVersion = true, "fe13ef810d7fe200495107161e99eac081368aa0ce5e53971b1bd47a64eba4db")
if (!chk("gopass ls")) { configureGopass(publicGpgKey = Secret(publicGPGSnakeoilKey()))
// configure gopass in default location with gpg-key-fingerprint of snakeoil keys
cmd("printf \"\\ntest\\ntest@test.org\\n\" | gopass init 0x0674104CA81A4905")
} else {
ProvResult(true, out = "gopass already configured")
}
} }
assertTrue(preparationResult.success) assertTrue(preparationResult.success)
// when // when
val res = a.task { val res = prov.task {
installGopassBridgeJsonApi() installGopassBridgeJsonApi()
configureGopassBridgeJsonApi() configureGopassBridgeJsonApi()
} }
@ -138,9 +114,4 @@ internal class GopassBridgeKtTest {
// then // then
assertFalse(res.success) assertFalse(res.success)
} }
private fun Prov.aptInstallCurl() = task {
cmd("apt-get update", sudo = true)
aptInstall("curl")
}
} }

View file

@ -1,10 +1,8 @@
package org.domaindrivenarchitecture.provs.desktop.infrastructure package org.domaindrivenarchitecture.provs.desktop.infrastructure
import org.domaindrivenarchitecture.provs.framework.core.Secret
import org.domaindrivenarchitecture.provs.framework.core.remote import org.domaindrivenarchitecture.provs.framework.core.remote
import org.domaindrivenarchitecture.provs.test.defaultTestContainer import org.domaindrivenarchitecture.provs.test.defaultTestContainer
import org.domaindrivenarchitecture.provs.test.tags.ContainerTest import org.domaindrivenarchitecture.provs.test.tags.ContainerTest
import org.domaindrivenarchitecture.provs.framework.ubuntu.install.base.aptInstall
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.KeyPair import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.KeyPair
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.configureGpgKeys import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.configureGpgKeys
import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.gpgFingerprint import org.domaindrivenarchitecture.provs.framework.ubuntu.keys.base.gpgFingerprint
@ -12,8 +10,6 @@ import org.domaindrivenarchitecture.provs.framework.ubuntu.secret.secretSources.
import org.junit.jupiter.api.Assertions.assertTrue import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.Disabled
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.domaindrivenarchitecture.provs.test_keys.privateGPGSnakeoilKey
import org.domaindrivenarchitecture.provs.test_keys.publicGPGSnakeoilKey
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.* import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.*
import org.domaindrivenarchitecture.provs.test.tags.ExtensiveContainerTest import org.domaindrivenarchitecture.provs.test.tags.ExtensiveContainerTest
import org.junit.jupiter.api.Assertions.assertFalse import org.junit.jupiter.api.Assertions.assertFalse
@ -36,32 +32,23 @@ internal class GopassKtTest {
@ExtensiveContainerTest @ExtensiveContainerTest
fun test_installAndConfigureGopassAndMountStore() { fun test_installAndConfigureGopassAndMountStore() {
// given // given
val a = defaultTestContainer() val prov = defaultTestContainer()
val gopassRootDir = ".password-store" val gopassRootDir = ".password-store"
a.aptInstall("wget git gnupg")
a.createDir(gopassRootDir, "~/")
a.cmd("git init", "~/$gopassRootDir")
val fpr = a.gpgFingerprint(publicGPGSnakeoilKey())
println("+++++++++++++++++++++++++++++++++++++ $fpr +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
a.createFile("~/" + gopassRootDir + "/.gpg-id", fpr)
a.createDir("exampleStoreFolder", "~/")
a.createFile("~/exampleStoreFolder/.gpg-id", fpr)
a.configureGpgKeys(KeyPair(Secret(publicGPGSnakeoilKey()), Secret(privateGPGSnakeoilKey())), true)
// when // when
val res = a.installGopass() val res = prov.task("test_installAndConfigureGopassAndMountStore") {
val res2 = a.configureGopass(a.userHome() + gopassRootDir) installGopass()
val res3 = a.gopassMountStore("exampleStore", "~/exampleStoreFolder") configureGopass(prov.userHome() + gopassRootDir)
gopassInitStoreFolder("~/exampleStoreFolder")
gopassMountStore("exampleStore", "~/exampleStoreFolder")
prov.cmd("gopass ls")
}
// then // then
a.fileContent("~/.config/gopass/config.yml") // displays the content in the logs prov.fileContent("~/.config/gopass/config.yml") // displays the content in the logs
assertTrue(res.success) assertTrue(res.success)
assertTrue(res2.success) assertTrue(prov.fileContainsText("~/.config/gopass/config.yml", "/home/testuser/.password-store"))
assertTrue(res3.success) assertTrue(prov.fileContainsText("~/.config/gopass/config.yml", "exampleStore"))
assertTrue(a.fileContainsText("~/.config/gopass/config.yml", "/home/testuser/.password-store"))
assertTrue(a.fileContainsText("~/.config/gopass/config.yml", "exampleStore"))
} }
@Test @Test
@ -74,10 +61,10 @@ internal class GopassKtTest {
val privateKey = GopassSecretSource("path-to/priv.key").secret() val privateKey = GopassSecretSource("path-to/priv.key").secret()
// given // given
val a = remote(host, user) val prov = remote(host, user)
// when // when
val res = a.task { val res = prov.task {
configureGpgKeys( configureGpgKeys(
KeyPair( KeyPair(
pubKey, pubKey,
@ -101,3 +88,4 @@ internal class GopassKtTest {
assertTrue(res.success) assertTrue(res.success)
} }
} }

View file

@ -16,7 +16,7 @@ const val defaultTestContainerName = "provs_test"
private lateinit var prov: Prov private lateinit var prov: Prov
fun defaultTestContainer(startMode: ContainerStartMode = ContainerStartMode.USE_RUNNING_ELSE_CREATE): Prov { fun defaultTestContainer(startMode: ContainerStartMode = ContainerStartMode.USE_RUNNING_ELSE_CREATE): Prov {
if (!::prov.isInitialized || !testLocal().containerRuns(defaultTestContainerName)) { prov = initDefaultTestContainer(startMode) } if (!::prov.isInitialized || !testLocal().containerRuns(defaultTestContainerName) || (startMode == ContainerStartMode.CREATE_NEW_KILL_EXISTING)) { prov = initDefaultTestContainer(startMode) }
return prov return prov
} }