view src/main/kotlin/name/blackcap/passman/ReadSubcommand.kt @ 28:287eadf5ab30 default tip

Check for timeouts inside subcommands while in interactive mode as well.
author David Barts <n5jrn@me.com>
date Wed, 31 Jul 2024 11:21:18 -0700
parents 131e39d96862
children
line wrap: on
line source

package name.blackcap.passman

import org.apache.commons.cli.*

class ReadSubcommand(): Subcommand() {
    private companion object {
        const val CLIPBOARD = "clipboard"
        const val HELP = "help"
        const val LONG = "long"
        const val ALT_SB = "\u001b[?1049h"
        const val NORM_SB = "\u001b[?1049l"
        const val CLEAR = "\u001b[H\u001b[2J"
    }
    private lateinit var commandLine: CommandLine

    override fun run(args: Array<String>) {
        val options = Options().apply {
            addOption("c", CLIPBOARD, false, "Copy password into clipboard.")
            addOption("h", HELP, false, "Print this help message.")
            addOption("l", LONG, false, "Long format listing.")
        }
        try {
            commandLine = DefaultParser().parse(options, args)
        } catch (e: ParseException) {
            throw SubcommandException(message = e.message ?: "syntax error", status = 2, cause = e)
        }
        if (commandLine.hasOption(HELP)) {
            HelpFormatter().printHelp("$SHORTNAME read [options] name", options)
            return
        }
        if (commandLine.args.isEmpty()) {
            throw SubcommandException(message = "expecting site name", status = 2)
        }
        if (commandLine.args.size > 1) {
            throw SubcommandException(message = "unexpected trailing arguments", status = 2)
        }
        val nameIn = commandLine.args[0];
        val db = Database.default
        val entry = Entry.fromDatabase(db, nameIn)
        if (entry == null) {
            throw SubcommandException(message = "no record matches ${see(nameIn)}")
        }
        try {
            print(ALT_SB + CLEAR)
            val redaction = if (commandLine.hasOption(CLIPBOARD)) { "(in clipboard)" } else { null }
            if (commandLine.hasOption(LONG)) {
                entry.printLong(redaction)
            } else {
                entry.print(redaction)
            }
            if (commandLine.hasOption(CLIPBOARD)) {
                writeToClipboard(entry.password)
            }
            name.blackcap.passman.readLine("Press ENTER to continue: ")
        } finally {
            print(CLEAR + NORM_SB)
            entry.password.clear()
        }

        db.connection.prepareStatement("update passwords set accessed = ? where id = ?").use {
            it.setLong(1, System.currentTimeMillis())
            it.setLong(2, db.makeKey(nameIn))
            it.execute()
        }
    }
}