PasswordTreeFavoritesMigrationService.kt
package de.pflugradts.passbird.application.process.migration.passwordtree
import de.pflugradts.passbird.application.configuration.ReadableConfiguration
import de.pflugradts.passbird.application.configuration.ReadableConfiguration.Companion.PASSWORD_TREE_FILENAME
import de.pflugradts.passbird.application.passwordtree.LegacyPasswordTreePayloadReader
import de.pflugradts.passbird.application.passwordtree.PasswordTreeEnvelope
import de.pflugradts.passbird.application.passwordtree.PasswordTreePayloadWriter
import de.pflugradts.passbird.application.security.AesGcmCipher
import de.pflugradts.passbird.application.toDirectory
import de.pflugradts.passbird.application.toFileName
import de.pflugradts.passbird.application.util.SystemOperation
import de.pflugradts.passbird.domain.model.shell.EncryptedShell.Companion.encryptedShellOf
import de.pflugradts.passbird.domain.model.shell.Shell
class PasswordTreeFavoritesMigrationService constructor(
private val configuration: ReadableConfiguration,
private val legacyPasswordTreePayloadReader: LegacyPasswordTreePayloadReader,
private val passwordTreeEnvelope: PasswordTreeEnvelope,
private val passwordTreePayloadWriter: PasswordTreePayloadWriter,
private val systemOperation: SystemOperation,
) {
fun migrate(keyShell: Shell) {
try {
val cryptoProvider = AesGcmCipher(keyShell)
val decryptedShell = systemOperation.readBytesFromFile(filePath)
.let(passwordTreeEnvelope::unwrapLegacyCurrent)
.let { cryptoProvider.decrypt(encryptedShellOf(it)) }
val snapshot = try {
legacyPasswordTreePayloadReader.read(decryptedShell)
} finally {
decryptedShell.scramble()
}
val payloadShell = passwordTreePayloadWriter.write(snapshot)
val migratedBytes = try {
passwordTreeEnvelope.wrap(cryptoProvider.encrypt(payloadShell).toByteArray())
} finally {
payloadShell.scramble()
}
systemOperation.writeBytesToSensitiveFile(filePath, migratedBytes)
} finally {
keyShell.scramble()
}
}
private val filePath get() = systemOperation.resolvePath(
configuration.adapter.passwordTree.location.toDirectory(),
PASSWORD_TREE_FILENAME.toFileName(),
)
}