11
|
1 package name.blackcap.passman
|
|
2
|
|
3 import org.apache.commons.cli.*
|
|
4
|
|
5 class RenameSubcommand(): Subcommand() {
|
|
6 private companion object {
|
|
7 const val FORCE = "force"
|
|
8 const val HELP = "help"
|
|
9 }
|
|
10 private lateinit var commandLine: CommandLine
|
|
11 private lateinit var source: String
|
|
12 private lateinit var destination: String
|
|
13 private lateinit var db: Database
|
|
14
|
|
15 override fun run(args: Array<String>) {
|
|
16 parseArguments(args)
|
21
|
17 if (commandLine.hasOption(HELP)) {
|
|
18 return
|
|
19 }
|
|
20 db = Database.default
|
11
|
21 renameIt()
|
|
22 }
|
|
23
|
|
24 private fun parseArguments(args: Array<String>) {
|
|
25 val options = Options().apply {
|
|
26 addOption("f", FORCE, false, "If destination exists exists, force overwrite.")
|
|
27 addOption("h", HELP, false, "Print this help message.")
|
|
28 }
|
|
29 try {
|
|
30 commandLine = DefaultParser().parse(options, args)
|
|
31 } catch (e: ParseException) {
|
21
|
32 throw SubcommandException(message = e.message ?: "syntax error", status = 2, cause = e)
|
11
|
33 }
|
|
34 if (commandLine.hasOption(HELP)) {
|
|
35 HelpFormatter().printHelp("$SHORTNAME rename [options] source destination", options)
|
21
|
36 return
|
11
|
37 }
|
|
38 if (commandLine.args.size < 2) {
|
21
|
39 throw SubcommandException(message = "expecting source and destination", status = 2)
|
11
|
40 }
|
|
41 if (commandLine.args.size > 2) {
|
21
|
42 throw SubcommandException(message = "unexpected trailing arguments", status = 2)
|
11
|
43 }
|
|
44 source = commandLine.args[0]
|
|
45 destination = commandLine.args[1]
|
|
46 }
|
|
47
|
|
48 private fun renameIt(): Unit {
|
|
49 val sid = db.makeKey(source)
|
|
50 val did = db.makeKey(destination)
|
|
51
|
|
52 if(!recordExists(sid)) {
|
21
|
53 throw SubcommandException(message = "no record matches ${see(source)}")
|
11
|
54 }
|
|
55 if (recordExists(did)) {
|
|
56 if (commandLine.hasOption(FORCE)) {
|
|
57 deleteRecord(did)
|
|
58 } else {
|
21
|
59 throw SubcommandException(message = "record matching ${see(destination)} already exists")
|
11
|
60 }
|
|
61 }
|
|
62
|
|
63 db.connection.prepareStatement("select username, password, notes, created, modified, accessed from passwords where id = ?").use { sourceStmt ->
|
14
|
64 sourceStmt.setLong(1, sid)
|
11
|
65 val result = sourceStmt.executeQuery()
|
|
66 result.next()
|
14
|
67 db.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created, modified, accessed) values (?, ?, ?, ?, ?, ?, ?, ?)").use {
|
|
68 it.setLong(1, did)
|
|
69 it.setEncryptedString(2, destination, db.encryption)
|
|
70 it.setBytes(3, result.getBytes(1))
|
|
71 it.setBytes(4, result.getBytes(2))
|
|
72 it.setBytesOrNull(5, result.getBytes(3))
|
|
73 it.setLong(6, result.getLong(4))
|
|
74 it.setLong(7, System.currentTimeMillis())
|
|
75 it.setDateOrNull(8, result.getLong(6))
|
|
76 it.executeUpdate()
|
11
|
77 }
|
|
78 }
|
|
79
|
|
80 deleteRecord(sid)
|
|
81 }
|
|
82
|
|
83 private fun recordExists(id: Long): Boolean {
|
|
84 db.connection.prepareStatement("select count(*) from passwords where id = ?").use {
|
|
85 it.setLong(1, id)
|
|
86 val result = it.executeQuery()
|
|
87 result.next()
|
|
88 return result.getInt(1) > 0
|
|
89 }
|
|
90 }
|
|
91
|
|
92 private fun deleteRecord(id: Long): Unit {
|
|
93 db.connection.prepareStatement("delete from passwords where id = ?").use {
|
|
94 it.setLong(1, id);
|
|
95 it.executeUpdate()
|
|
96 }
|
|
97 }
|
14
|
98 }
|