comparison src/main/kotlin/name/blackcap/passman/MergeSubcommand.kt @ 18:8f3ddebb4295

Was using wrong db object to decrypt, fixed.
author David Barts <n5jrn@me.com>
date Tue, 04 Apr 2023 20:38:52 -0700
parents a38a2a1036c3
children ea65ab890f66
comparison
equal deleted inserted replaced
17:4427199eb218 18:8f3ddebb4295
6 6
7 class MergeSubcommand(): Subcommand() { 7 class MergeSubcommand(): Subcommand() {
8 private companion object { 8 private companion object {
9 const val FORCE = "force" 9 const val FORCE = "force"
10 const val HELP = "help" 10 const val HELP = "help"
11 const val VERBOSE = "verbose"
11 } 12 }
12 private lateinit var commandLine: CommandLine 13 private lateinit var commandLine: CommandLine
13 private lateinit var db: Database 14 private lateinit var db: Database
14 15
15 override fun run(args: Array<String>) { 16 override fun run(args: Array<String>) {
18 doMerge() 19 doMerge()
19 } 20 }
20 21
21 private fun parseArguments(args: Array<String>) { 22 private fun parseArguments(args: Array<String>) {
22 val options = Options().apply { 23 val options = Options().apply {
24 addOption("v", MergeSubcommand.VERBOSE, false, "Verbose mode, print what we are doing.")
23 addOption("f", MergeSubcommand.FORCE, false, "Do not ask before overwriting.") 25 addOption("f", MergeSubcommand.FORCE, false, "Do not ask before overwriting.")
24 addOption("h", MergeSubcommand.HELP, false, "Print this help message.") 26 addOption("h", MergeSubcommand.HELP, false, "Print this help message.")
25 } 27 }
26 try { 28 try {
27 commandLine = DefaultParser().parse(options, args) 29 commandLine = DefaultParser().parse(options, args)
47 passwordPrompt = "Key for ${see(otherFile)}: ", create = false 49 passwordPrompt = "Key for ${see(otherFile)}: ", create = false
48 ) 50 )
49 otherDb.connection.prepareStatement("select name, username, password, notes, created, modified, accessed from passwords").use { stmt -> 51 otherDb.connection.prepareStatement("select name, username, password, notes, created, modified, accessed from passwords").use { stmt ->
50 val results = stmt.executeQuery() 52 val results = stmt.executeQuery()
51 while (results.next()) { 53 while (results.next()) {
52 val otherEntry = makeEntry(results) 54 val otherEntry = makeEntry(otherDb, results)
55 vprint("read ${see(otherEntry.name)}…")
53 val thisEntry = getEntry(db, otherEntry.name) 56 val thisEntry = getEntry(db, otherEntry.name)
54 if (thisEntry == null) { 57 if (thisEntry == null) {
58 vprintln(" missing, inserting it")
55 otherEntry.insert(db) 59 otherEntry.insert(db)
56 } else { 60 } else {
57 doCompare(thisEntry, otherEntry) 61 doCompare(thisEntry, otherEntry)
58 thisEntry.password.clear() 62 thisEntry.password.clear()
59 } 63 }
60 otherEntry.password.clear() 64 otherEntry.password.clear()
61 } 65 }
62 } 66 }
63 } 67 }
64 68
65 private fun makeEntry(results: ResultSet) = Entry( 69 private fun makeEntry(dbParam: Database, results: ResultSet) = Entry(
66 name = results.getDecryptedString(1, db.encryption)!!, 70 name = results.getDecryptedString(1, dbParam.encryption)!!,
67 username = results.getDecryptedString(2, db.encryption)!!, 71 username = results.getDecryptedString(2, dbParam.encryption)!!,
68 password = results.getDecrypted(3, db.encryption)!!, 72 password = results.getDecrypted(3, dbParam.encryption)!!,
69 notes = results.getDecryptedString(4, db.encryption), 73 notes = results.getDecryptedString(4, dbParam.encryption),
70 created = results.getDate(5), 74 created = results.getDate(5),
71 modified = results.getDate(6), 75 modified = results.getDate(6),
72 accessed = results.getDate(7) 76 accessed = results.getDate(7)
73 ) 77 )
74 78
75 private fun getEntry(otherDb: Database, name: String): Entry? { 79 private fun getEntry(dbParam: Database, name: String): Entry? {
76 otherDb.connection.prepareStatement("select name, username, password, notes, created, modified, accessed from passwords where id = ?").use { stmt -> 80 dbParam.connection.prepareStatement("select name, username, password, notes, created, modified, accessed from passwords where id = ?").use { stmt ->
77 stmt.setLong(1, otherDb.makeKey(name)) 81 stmt.setLong(1, dbParam.makeKey(name))
78 val results = stmt.executeQuery() 82 val results = stmt.executeQuery()
79 return if (results.next()) makeEntry(results) else null 83 return if (results.next()) makeEntry(dbParam, results) else null
80 } 84 }
81 } 85 }
82 86
83 private fun doCompare(thisEntry: Entry, otherEntry: Entry) { 87 private fun doCompare(thisEntry: Entry, otherEntry: Entry) {
84 if (otherEntry.modifiedOrCreated.after(thisEntry.modifiedOrCreated) && okToChange(thisEntry, otherEntry)) { 88 if (otherEntry.modifiedOrCreated.after(thisEntry.modifiedOrCreated) && okToChange(thisEntry, otherEntry)) {
89 vprintln(" newer, updating it")
85 db.connection.prepareStatement("update passwords set name = ?, username = ?, password = ?, notes = ?, modified = ? where id = ?").use { 90 db.connection.prepareStatement("update passwords set name = ?, username = ?, password = ?, notes = ?, modified = ? where id = ?").use {
86 it.setEncryptedString(1, otherEntry.name, db.encryption) 91 it.setEncryptedString(1, otherEntry.name, db.encryption)
87 it.setEncryptedString(2, otherEntry.username, db.encryption) 92 it.setEncryptedString(2, otherEntry.username, db.encryption)
88 it.setEncrypted(3, otherEntry.password, db.encryption) 93 it.setEncrypted(3, otherEntry.password, db.encryption)
89 it.setEncryptedString(4, otherEntry.notes, db.encryption) 94 it.setEncryptedString(4, otherEntry.notes, db.encryption)
90 it.setLong(5, otherEntry.modifiedOrCreated.time) 95 it.setLong(5, otherEntry.modifiedOrCreated.time)
91 it.setLong(6, db.makeKey(thisEntry.name)) 96 it.setLong(6, db.makeKey(thisEntry.name))
92 it.executeUpdate() 97 it.executeUpdate()
93 } 98 }
99 } else {
100 vprintln(" older or update denied, ignoring it")
94 } 101 }
95 } 102 }
96 103
97 private fun okToChange(thisEntry: Entry, otherEntry: Entry): Boolean = 104 private fun okToChange(thisEntry: Entry, otherEntry: Entry): Boolean =
98 commandLine.hasOption(FORCE) || askUserIfOkToOverwrite(thisEntry, otherEntry) 105 commandLine.hasOption(FORCE) || askUserIfOkToOverwrite(thisEntry, otherEntry)
106
107 private fun vprint(message: String) {
108 if (commandLine.hasOption(VERBOSE)) {
109 print(message)
110 }
111 }
112
113 private fun vprintln(message: String) {
114 if (commandLine.hasOption(VERBOSE)) {
115 println(message)
116 }
117 }
99 } 118 }