comparison src/main/kotlin/name/blackcap/passman/UpdateSubcommand.kt @ 8:698c4a3d758d

Some code clean-up.
author David Barts <n5jrn@me.com>
date Fri, 23 Sep 2022 20:59:52 -0700
parents 711cc42e96d7
children 72619175004e
comparison
equal deleted inserted replaced
7:f245b9a53495 8:698c4a3d758d
10 private lateinit var commandLine: CommandLine 10 private lateinit var commandLine: CommandLine
11 private lateinit var db: Database 11 private lateinit var db: Database
12 private lateinit var nameIn: String 12 private lateinit var nameIn: String
13 private var id by Delegates.notNull<Long>() 13 private var id by Delegates.notNull<Long>()
14 private var length by Delegates.notNull<Int>() 14 private var length by Delegates.notNull<Int>()
15 private var generate by Delegates.notNull<Boolean>()
16 private var allowSymbols by Delegates.notNull<Boolean>()
17 private var verbose by Delegates.notNull<Boolean>()
18 private val fields = StringBuilder() 15 private val fields = StringBuilder()
19 private val fieldValues = mutableListOf<Any?>() 16 private val fieldValues = mutableListOf<Any?>()
20 17
21 private companion object { 18 private companion object {
19 const val GENERATE = "generate"
20 const val HELP = "help"
21 const val LENGTH = "length"
22 const val SYMBOLS = "symbols"
23 const val VERBOSE = "verbose"
22 const val NULL_SPECIFIED = "." 24 const val NULL_SPECIFIED = "."
23 val NULLABLE_FIELDS = setOf<String>("notes") 25 val NULLABLE_FIELDS = setOf<String>("notes")
24 val SENSITIVE_FIELDS = setOf<String>("password") 26 val SENSITIVE_FIELDS = setOf<String>("password")
25 } 27 }
26 28
27 override fun run(args: Array<String>) { 29 override fun run(args: Array<String>) {
28 parseArguments(args) 30 parseArguments(args)
29 checkDatabase() 31 checkDatabase()
30 update() 32 try {
33 update()
34 } finally {
35 cleanUp()
36 }
31 } 37 }
32 38
33 private fun parseArguments(args: Array<String>) { 39 private fun parseArguments(args: Array<String>) {
34 val options = Options().apply { 40 val options = Options().apply {
35 addOption("g", "generate", false, "Use password generator.") 41 addOption("g", GENERATE, false, "Use password generator.")
36 addOption("h", "help", false, "Print this help message.") 42 addOption("h", HELP, false, "Print this help message.")
37 addOption("l", "length", true, "Length of generated password.") 43 addOption("l", LENGTH, true, "Length of generated password.")
38 addOption("s", "symbols", false, "Use symbol characters in generated password.") 44 addOption("s", SYMBOLS, false, "Use symbol characters in generated password.")
39 addOption("v", "verbose", false, "Print the generated password.") 45 addOption("v", VERBOSE, false, "Print the generated password.")
40 } 46 }
41 try { 47 try {
42 commandLine = DefaultParser().parse(options, args) 48 commandLine = DefaultParser().parse(options, args)
43 } catch (e: ParseException) { 49 } catch (e: ParseException) {
44 die(e.message ?: "syntax error", 2) 50 die(e.message ?: "syntax error", 2)
45 } 51 }
46 if (commandLine.hasOption("help")) { 52 if (commandLine.hasOption(HELP)) {
47 HelpFormatter().printHelp("$SHORTNAME update", options) 53 HelpFormatter().printHelp("$SHORTNAME update", options)
48 exitProcess(0) 54 exitProcess(0)
49 } 55 }
50 checkArguments() 56 checkArguments()
51 db = Database.open() 57 db = Database.open()
52 nameIn = commandLine.args[0] 58 nameIn = commandLine.args[0]
53 id = db.makeKey(nameIn) 59 id = db.makeKey(nameIn)
54 length = commandLine.getOptionValue("length").let { rawLength -> 60 length = commandLine.getOptionValue(LENGTH)?.let { rawLength ->
55 try { 61 try {
56 rawLength?.toInt() ?: DEFAULT_GENERATED_LENGTH 62 rawLength.toInt()
57 } catch (e: NumberFormatException) { 63 } catch (e: NumberFormatException) {
58 die("${see(rawLength)} - invalid length") 64 die("${see(rawLength)} - invalid length")
59 -1 /* will never happen */ 65 -1 /* will never happen */
60 } 66 }
61 } 67 } ?: DEFAULT_GENERATED_LENGTH
62 generate = commandLine.hasOption("generate")
63 allowSymbols = commandLine.hasOption("symbols")
64 verbose = commandLine.hasOption("verbose")
65 } 68 }
66 69
67 private fun checkArguments(): Unit { 70 private fun checkArguments(): Unit {
68 var bad = false 71 var bad = false
69 if (!commandLine.hasOption("generate")) { 72 if (!commandLine.hasOption(GENERATE)) {
70 for (option in listOf<String>("length", "symbols", "verbose")) { 73 for (option in listOf<String>(LENGTH, SYMBOLS, VERBOSE)) {
71 if (commandLine.hasOption(option)) { 74 if (commandLine.hasOption(option)) {
72 error("--$option requires --generate") 75 error("--$option requires --$GENERATE")
73 bad = true 76 bad = true
74 } 77 }
75 } 78 }
76 } 79 }
77 if (commandLine.args.isEmpty()) { 80 if (commandLine.args.isEmpty()) {
97 } 100 }
98 } 101 }
99 102
100 private fun update(): Unit { 103 private fun update(): Unit {
101 updateOne("username") 104 updateOne("username")
102 if (generate) { 105 if (commandLine.hasOption(GENERATE)) {
103 generatePassword() 106 generatePassword()
104 } else { 107 } else {
105 updateOne("password") 108 updateOne("password")
106 } 109 }
107 updateOne("notes") 110 updateOne("notes")
123 } 126 }
124 } 127 }
125 stmt.setLong(fieldValues.size + 2, id) 128 stmt.setLong(fieldValues.size + 2, id)
126 stmt.execute() 129 stmt.execute()
127 } 130 }
131 }
132
133 private fun cleanUp(): Unit {
134 fieldValues.forEach { if (it is CharArray) { it.clear() } }
128 } 135 }
129 136
130 private fun updateOne(name: String): Unit { 137 private fun updateOne(name: String): Unit {
131 val prompt = name.replaceFirstChar { it.titlecase(Locale.getDefault()) } + ": " 138 val prompt = name.replaceFirstChar { it.titlecase(Locale.getDefault()) } + ": "
132 val value: Any? = if (name in SENSITIVE_FIELDS) { 139 val value: Any? = if (name in SENSITIVE_FIELDS) {
160 fields.append(" = ?") 167 fields.append(" = ?")
161 fieldValues.add(value) 168 fieldValues.add(value)
162 } 169 }
163 170
164 private fun generatePassword(): Unit { 171 private fun generatePassword(): Unit {
165 val newPassword = generate(length, allowSymbols) 172 val newPassword = generate(length, commandLine.hasOption(SYMBOLS))
166 if (verbose) { 173 if (commandLine.hasOption(VERBOSE)) {
167 printPassword(newPassword) 174 printPassword(newPassword)
168 } 175 }
169 addOne("password", newPassword) 176 addOne("password", newPassword)
170 } 177 }
171 178