Mercurial > cgi-bin > hgweb.cgi > PassMan
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a6cfdffcaa94 |
---|---|
1 package name.blackcap.passman | |
2 | |
3 import org.apache.commons.cli.CommandLine | |
4 import org.apache.commons.cli.DefaultParser | |
5 import org.apache.commons.cli.Options | |
6 import org.apache.commons.cli.ParseException | |
7 import kotlin.system.exitProcess | |
8 | |
9 class CreateSubcommand(): Subcommand() { | |
10 private lateinit var commandLine: CommandLine | |
11 | |
12 override fun run(args: Array<String>) { | |
13 val options = Options().apply { | |
14 addOption("g", "generate", false, "Use password generator.") | |
15 addOption("l", "length", true, "Length of generated password.") | |
16 addOption("s", "symbols", false, "Use symbol characters in generated password.") | |
17 addOption("v", "verbose", false, "Print the generated password.") | |
18 } | |
19 try { | |
20 commandLine = DefaultParser().parse(options, args) | |
21 } catch (e: ParseException) { | |
22 die(e.message ?: "syntax error", 2) | |
23 } | |
24 checkArguments() | |
25 val db = Database.open() | |
26 | |
27 val entry = if (commandLine.hasOption("generate")) { | |
28 val rawLength = commandLine.getOptionValue("length") | |
29 val length = try { | |
30 rawLength?.toInt() ?: DEFAULT_GENERATED_LENGTH | |
31 } catch (e: NumberFormatException) { | |
32 die("$rawLength - invalid length") | |
33 -1 /* will never happen */ | |
34 } | |
35 val symbols = commandLine.hasOption("symbols") | |
36 val verbose = commandLine.hasOption("verbose") | |
37 Entry.withGeneratedPassword(length, symbols, verbose) | |
38 } else { | |
39 Entry.withPromptedPassword() | |
40 } | |
41 val id = db.makeKey(entry.name) | |
42 | |
43 db.connection.prepareStatement("select count(*) from passwords where id = ?").use { | |
44 it.setLong(1, id) | |
45 val result = it.executeQuery() | |
46 result.next() | |
47 val count = result.getInt(1) | |
48 if (count > 0) { | |
49 die("record matching ${entry.name} already exists") | |
50 } | |
51 } | |
52 | |
53 try { | |
54 if (entry.notes.isBlank()) { | |
55 db.connection.prepareStatement("insert into passwords (id, name, username, password, created) values (?, ?, ?, ?, ?)") | |
56 .use { | |
57 it.setLong(1, id) | |
58 it.setEncryptedString(2, entry.name, db.encryption) | |
59 it.setEncryptedString(3, entry.username, db.encryption) | |
60 it.setEncrypted(4, entry.password, db.encryption) | |
61 it.setLong(5, System.currentTimeMillis()) | |
62 it.execute() | |
63 } | |
64 } else { | |
65 db.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created) values (?, ?, ?, ?, ?, ?)") | |
66 .use { | |
67 it.setLong(1, db.makeKey(entry.name)) | |
68 it.setEncryptedString(2, entry.name, db.encryption) | |
69 it.setEncryptedString(3, entry.username, db.encryption) | |
70 it.setEncrypted(4, entry.password, db.encryption) | |
71 it.setEncryptedString(5, entry.notes, db.encryption) | |
72 it.setLong(6, System.currentTimeMillis()) | |
73 it.execute() | |
74 } | |
75 } | |
76 } finally { | |
77 entry.password.clear() | |
78 } | |
79 } | |
80 | |
81 private fun checkArguments(): Unit { | |
82 var bad = false | |
83 if (!commandLine.hasOption("generate")) { | |
84 for (option in listOf<String>("length", "symbols", "verbose")) { | |
85 if (commandLine.hasOption(option)) { | |
86 error("--$option requires --generate") | |
87 bad = true | |
88 } | |
89 } | |
90 } | |
91 if (commandLine.args.isNotEmpty()) { | |
92 error("unexpected trailing arguments") | |
93 } | |
94 if (bad) { | |
95 exitProcess(2); | |
96 } | |
97 } | |
98 } |