Mercurial > cgi-bin > hgweb.cgi > PassMan
view src/main/kotlin/name/blackcap/passman/CreateSubcommand.kt @ 0:a6cfdffcaa94
Initial commit, incomplete but it runs sorta.
author | David Barts <n5jrn@me.com> |
---|---|
date | Sun, 11 Sep 2022 16:11:37 -0700 |
parents | |
children | eafa3779aef8 |
line wrap: on
line source
package name.blackcap.passman import org.apache.commons.cli.CommandLine import org.apache.commons.cli.DefaultParser import org.apache.commons.cli.Options import org.apache.commons.cli.ParseException import kotlin.system.exitProcess class CreateSubcommand(): Subcommand() { private lateinit var commandLine: CommandLine override fun run(args: Array<String>) { val options = Options().apply { addOption("g", "generate", false, "Use password generator.") 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) } 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) { die("$rawLength - invalid length") -1 /* will never happen */ } val symbols = commandLine.hasOption("symbols") val verbose = commandLine.hasOption("verbose") Entry.withGeneratedPassword(length, symbols, 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 ${entry.name} already exists") } } try { if (entry.notes.isBlank()) { 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 (commandLine.args.isNotEmpty()) { error("unexpected trailing arguments") } if (bad) { exitProcess(2); } } }