You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
provs/src/main/kotlin/org/domaindrivenarchitecture/provs/desktop/infrastructure/Gopass.kt

109 lines
4.1 KiB
Kotlin

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.ubuntu.filesystem.base.createDir
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createDirs
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.createFile
import org.domaindrivenarchitecture.provs.framework.ubuntu.filesystem.base.userHome
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
fun Prov.installGopass(
version: String = "1.12.7",
enforceVersion: Boolean = false,
sha256sum: String = "0824d5110ff1e68bff1ba10c1be63acb67cb1ad8e3bccddd6b6fc989608beca8" // checksum for sha256sum version 8.30 (e.g. ubuntu 20.04)
) = def {
if (isPackageInstalled("gopass") && !enforceVersion) {
return@def ProvResult(true)
}
if (checkGopassVersion(version)) {
return@def ProvResult(true, out = "Version $version of gopass is already installed.")
}
val path = "tmp"
// install required dependencies
aptInstall("rng-tools gnupg2 git")
val filename = "gopass_${version}_linux_amd64.deb"
val result = downloadFromURL(
"https://github.com/gopasspw/gopass/releases/download/v$version/$filename",
filename,
path,
sha256sum = sha256sum
)
if (result.success) {
cmd("sudo dpkg -i $path/gopass_${version}_linux_amd64.deb")
// Cross-check if installation was successful
addResultToEval(ProvResult(checkGopassVersion(version)))
} else {
addResultToEval(ProvResult(false, err = "Gopass could not be installed. " + result.err))
}
}
fun Prov.configureGopass(gopassRootFolder: String? = null) = def {
if ((gopassRootFolder != null) && (gopassRootFolder.trim().length > 0) && ("~" == gopassRootFolder.trim().substring(0, 1))) {
return@def ProvResult(false, err = "Gopass cannot be initialized with folders starting with ~")
}
val defaultRootFolder = userHome() + ".password-store"
val rootFolder = gopassRootFolder ?: defaultRootFolder
// use default
createDir(rootFolder)
createDirs(".config/gopass")
createFile("~/.config/gopass/config.yml", gopassConfig(rootFolder))
// auto-completion
configureBashForUser()
createFile("~/.bashrc.d/gopass.sh", "source <(gopass completion bash)\n")
}
fun Prov.gopassMountStore(storeName: String, path: String, indexOfRecepientKey: Int = 0) = def {
cmd("printf \"$indexOfRecepientKey\\n\" | gopass mounts add $storeName $path")
}
internal fun gopassConfig(gopassRoot: String): String {
return """
root:
askformore: false
autoclip: true
autoprint: false
autoimport: true
autosync: false
check_recipient_hash: false
cliptimeout: 45
concurrency: 1
editrecipients: false
exportkeys: true
nocolor: false
noconfirm: true
nopager: false
notifications: true
path: gpgcli-gitcli-fs+file://$gopassRoot
recipient_hash:
.gpg-id: 3078303637343130344341383141343930350aa69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26
safecontent: false
usesymbols: false
mounts: {}
""".trim() + "\n"
}
/**
* Returns true if gopass is installed and has the given version.
*
* @param version that is checked; specifies left part of text of installed version, e.g. both "1" and "1.12" will return true if installed version is "1.12.6+8d7a311b9273846bbb618e4bd9ddbae51b1db7b8"
*/
internal fun Prov.checkGopassVersion(version: String): Boolean {
val installedGopassVersion = gopassVersion()
return installedGopassVersion != null && installedGopassVersion.startsWith("gopass " + version)
}
internal fun Prov.gopassVersion(): String? {
val result = cmdNoEval("gopass -v")
return if (!result.success) null else result.out
}