Mercurial > cgi-bin > hgweb.cgi > PassMan
view src/main/kotlin/name/blackcap/passman/CreateSubcommand.kt @ 11:c69665ff37d0
Add merge subcommand (untested).
author | David Barts <n5jrn@me.com> |
---|---|
date | Sat, 21 Jan 2023 15:39:42 -0800 |
parents | cbe4c797c9a6 |
children | 302d224bbd57 |
line wrap: on
line source
package name.blackcap.passman import org.apache.commons.cli.* import kotlin.system.exitProcess class CreateSubcommand(): Subcommand() { private companion object { const val GENERATE = "generate" const val HELP = "help" const val LENGTH = "length" const val SYMBOLS = "symbols" const val VERBOSE = "verbose" } private lateinit var commandLine: CommandLine override fun run(args: Array<String>) { val options = Options().apply { addOption("g", GENERATE, false, "Use password generator.") addOption("h", HELP, false, "Print this help message.") addOption("l", LENGTH, true, "Length of generated password.") addOption("s", SYMBOLS, false, "Use symbol characters in generated password.") addOption("v", VERBOSE, false, "Print the generated password.") } try { commandLine = DefaultParser().parse(options, args) } catch (e: ParseException) { die(e.message ?: "syntax error", 2) } if (commandLine.hasOption(HELP)) { HelpFormatter().printHelp("$SHORTNAME create [options]", options) exitProcess(0) } checkArguments() val db = Database.open() val entry = if (commandLine.hasOption(GENERATE)) { val rawLength = commandLine.getOptionValue(LENGTH) val length = try { rawLength?.toInt() ?: DEFAULT_GENERATED_LENGTH } catch (e: NumberFormatException) { -1 } if (length < MIN_GENERATED_LENGTH) { die("${see(rawLength)} - invalid length") } Entry.withGeneratedPassword(length, commandLine.hasOption(SYMBOLS), commandLine.hasOption(VERBOSE)) } else { Entry.withPromptedPassword() } val id = db.makeKey(entry.name) db.connection.prepareStatement("select count(*) from passwords where id = ?").use { it.setLong(1, id) val result = it.executeQuery() result.next() val count = result.getInt(1) if (count > 0) { die("record matching ${see(entry.name)} already exists") } } try { if (entry.notes.isNullOrBlank()) { db.connection.prepareStatement("insert into passwords (id, name, username, password, created) values (?, ?, ?, ?, ?)") .use { it.setLong(1, id) it.setEncryptedString(2, entry.name, db.encryption) it.setEncryptedString(3, entry.username, db.encryption) it.setEncrypted(4, entry.password, db.encryption) it.setLong(5, System.currentTimeMillis()) it.execute() } } else { db.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created) values (?, ?, ?, ?, ?, ?)") .use { it.setLong(1, db.makeKey(entry.name)) it.setEncryptedString(2, entry.name, db.encryption) it.setEncryptedString(3, entry.username, db.encryption) it.setEncrypted(4, entry.password, db.encryption) it.setEncryptedString(5, entry.notes, db.encryption) it.setLong(6, System.currentTimeMillis()) it.execute() } } } finally { entry.password.clear() } } private fun checkArguments(): Unit { var bad = false if (!commandLine.hasOption(GENERATE)) { for (option in listOf<String>(LENGTH, SYMBOLS, VERBOSE)) { if (commandLine.hasOption(option)) { error("--$option requires --$GENERATE") bad = true } } } if (bad) { exitProcess(2); } if (commandLine.args.isNotEmpty()) { die("unexpected trailing arguments", 2) } } }