Mercurial > cgi-bin > hgweb.cgi > PassMan
view src/main/kotlin/name/blackcap/passman/RenameSubcommand.kt @ 14:4dae7a15ee48
Fix bugs found in additional round of testing.
author | David Barts <n5jrn@me.com> |
---|---|
date | Tue, 31 Jan 2023 19:07:46 -0800 |
parents | c69665ff37d0 |
children | 0fc90892a3ae |
line wrap: on
line source
package name.blackcap.passman import org.apache.commons.cli.* import java.sql.PreparedStatement import java.sql.Types import kotlin.system.exitProcess class RenameSubcommand(): Subcommand() { private companion object { const val FORCE = "force" const val HELP = "help" } private lateinit var commandLine: CommandLine private lateinit var source: String private lateinit var destination: String private lateinit var db: Database override fun run(args: Array<String>) { parseArguments(args) db = Database.open() renameIt() } private fun parseArguments(args: Array<String>) { val options = Options().apply { addOption("f", FORCE, false, "If destination exists exists, force overwrite.") addOption("h", HELP, false, "Print this help message.") } try { commandLine = DefaultParser().parse(options, args) } catch (e: ParseException) { die(e.message ?: "syntax error", 2) } if (commandLine.hasOption(HELP)) { HelpFormatter().printHelp("$SHORTNAME rename [options] source destination", options) exitProcess(0) } if (commandLine.args.size < 2) { die("expecting source and destination", 2) } if (commandLine.args.size > 2) { die("unexpected trailing arguments", 2) } source = commandLine.args[0] destination = commandLine.args[1] } private fun renameIt(): Unit { val sid = db.makeKey(source) val did = db.makeKey(destination) if(!recordExists(sid)) { die("no record matches ${see(source)}") } if (recordExists(did)) { if (commandLine.hasOption(FORCE)) { deleteRecord(did) } else { die("record matching ${see(destination)} already exists") } } db.connection.prepareStatement("select username, password, notes, created, modified, accessed from passwords where id = ?").use { sourceStmt -> sourceStmt.setLong(1, sid) val result = sourceStmt.executeQuery() result.next() db.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created, modified, accessed) values (?, ?, ?, ?, ?, ?, ?, ?)").use { it.setLong(1, did) it.setEncryptedString(2, destination, db.encryption) it.setBytes(3, result.getBytes(1)) it.setBytes(4, result.getBytes(2)) it.setBytesOrNull(5, result.getBytes(3)) it.setLong(6, result.getLong(4)) it.setLong(7, System.currentTimeMillis()) it.setDateOrNull(8, result.getLong(6)) it.executeUpdate() } } deleteRecord(sid) } private fun recordExists(id: Long): Boolean { db.connection.prepareStatement("select count(*) from passwords where id = ?").use { it.setLong(1, id) val result = it.executeQuery() result.next() return result.getInt(1) > 0 } } private fun deleteRecord(id: Long): Unit { db.connection.prepareStatement("delete from passwords where id = ?").use { it.setLong(1, id); it.executeUpdate() } } private fun PreparedStatement.setDateOrNull(parameterIndex: Int, value: Long?) { if (value == null || value == 0L) { setNull(parameterIndex, Types.INTEGER) } else { setLong(parameterIndex, value) } } }