annotate src/main/kotlin/name/blackcap/passman/Entry.kt @ 15:0fc90892a3ae

Add password subcommand.
author David Barts <n5jrn@me.com>
date Fri, 03 Feb 2023 18:48:13 -0800
parents a38a2a1036c3
children 3a3067ba673b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
1 package name.blackcap.passman
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
2
12
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
3 import java.sql.ResultSet
5
ad997df1f560 Fix see() to be about as good as sccc.
David Barts <n5jrn@me.com>
parents: 2
diff changeset
4 import java.util.*
7
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
5 import kotlin.reflect.KProperty
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
6 import kotlin.reflect.full.declaredMemberProperties
0
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
7
8
698c4a3d758d Some code clean-up.
David Barts <n5jrn@me.com>
parents: 7
diff changeset
8 class Entry(val name: String, val username: String, val password: CharArray, val notes: String?,
0
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
9 val created: Date? = null, val modified: Date? = null, val accessed: Date? = null) {
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
10
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
11 companion object {
7
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
12 private val FIELD_MAP = mutableMapOf<String, KProperty.Getter<*>>().apply {
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
13 Entry::class.declaredMemberProperties.forEach{
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
14 this[it.name] = it.getter
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
15 }
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
16 }
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
17
0
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
18 fun withPromptedPassword() = Entry(
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
19 name = _getName(),
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
20 username = _getUsername(),
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
21 password = _getPassword(),
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
22 notes = _getNotes()
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
23 )
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
24
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
25 fun withGeneratedPassword(length: Int, allowSymbols: Boolean, verbose: Boolean): Entry {
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
26 return Entry(
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
27 name = _getName(),
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
28 username = _getUsername(),
2
3c792ad36b3d Can now update a password and read it back.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
29 password = _genPassword(length, allowSymbols, verbose),
0
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
30 notes = _getNotes()
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
31 )
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
32 }
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
33
12
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
34 fun fromDatabase(db: Database, name: String): Entry? {
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
35 db.connection.prepareStatement("select name, username, password, notes, created, modified, accessed from passwords where id = ?").use {
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
36 it.setLong(1, db.makeKey(name))
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
37 val results = it.executeQuery()
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
38 if (!results.next()) {
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
39 return null
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
40 }
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
41 return Entry(
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
42 name = results.getDecryptedString(1, db.encryption)!!,
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
43 username = results.getDecryptedString(2, db.encryption)!!,
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
44 password = results.getDecrypted(3, db.encryption)!!,
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
45 notes = results.getDecryptedString(4, db.encryption),
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
46 created = results.getDate(5),
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
47 modified = results.getDate(6),
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
48 accessed = results.getDate(7)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
49 )
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
50 }
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
51 }
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
52
2
3c792ad36b3d Can now update a password and read it back.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
53 private fun _genPassword(length: Int, allowSymbols: Boolean, verbose: Boolean): CharArray {
3c792ad36b3d Can now update a password and read it back.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
54 val generated = generate(length, allowSymbols)
3c792ad36b3d Can now update a password and read it back.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
55 if (verbose) {
3c792ad36b3d Can now update a password and read it back.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
56 printPassword(generated)
3c792ad36b3d Can now update a password and read it back.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
57 }
3c792ad36b3d Can now update a password and read it back.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
58 return generated
3c792ad36b3d Can now update a password and read it back.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
59 }
3c792ad36b3d Can now update a password and read it back.
David Barts <n5jrn@me.com>
parents: 0
diff changeset
60
0
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
61 private fun _getName() = mustReadLine("Name of site: ")
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
62
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
63 private fun _getUsername() = mustReadLine("Username: ")
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
64
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
65 private fun _getPassword() = mustGetPassword("Password: ", verify = true)
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
66
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
67 private fun _getNotes() = readLine("Notes: ")
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
68 }
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
69
12
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
70 fun insert(db: Database) {
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
71 db.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created, modified, accessed) values (?, ?, ?, ?, ?, ?, ?, ?)")
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
72 .use {
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
73 it.setLong(1, db.makeKey(name))
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
74 it.setEncryptedString(2, name, db.encryption)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
75 it.setEncryptedString(3, username, db.encryption)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
76 it.setEncrypted(4, password, db.encryption)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
77 it.setEncryptedString(5, notes, db.encryption)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
78 it.setLongOrNull(6, created?.time)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
79 it.setLongOrNull(7, modified?.time)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
80 it.setLongOrNull(8, accessed?.time)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
81 it.executeUpdate()
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
82 }
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
83 }
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
84
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
85 fun update(db: Database) {
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
86 db.connection.prepareStatement("update passwords set name = ?, username = ?, password = ?, notes = ?, created = ?, modified = ?, accessed = ? where id = ?").use {
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
87 it.setEncryptedString(1, name, db.encryption)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
88 it.setEncryptedString(2, username, db.encryption)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
89 it.setEncrypted(3, password, db.encryption)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
90 it.setEncryptedString(4, notes, db.encryption)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
91 it.setLongOrNull(5, created?.time)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
92 it.setLongOrNull(6, modified?.time)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
93 it.setLongOrNull(7, accessed?.time)
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
94 it.setLong(8, db.makeKey(name))
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
95 it.executeUpdate()
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
96 }
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
97 }
a38a2a1036c3 Add import subcommand.
David Barts <n5jrn@me.com>
parents: 11
diff changeset
98
11
c69665ff37d0 Add merge subcommand (untested).
David Barts <n5jrn@me.com>
parents: 9
diff changeset
99 val modifiedOrCreated get() = modified ?: created!!
c69665ff37d0 Add merge subcommand (untested).
David Barts <n5jrn@me.com>
parents: 9
diff changeset
100
0
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
101 fun print(redactPassword: String? = null) {
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
102 println("Name of site: $name")
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
103 println("Username: $username")
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
104 if (redactPassword == null) {
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
105 printPassword(password)
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
106 } else {
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
107 println("Password: $redactPassword")
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
108 }
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
109 }
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
110
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
111 fun printLong(redactPassword: String? = null) {
9
72619175004e Fix issues found in testing.
David Barts <n5jrn@me.com>
parents: 8
diff changeset
112 this.print(redactPassword)
8
698c4a3d758d Some code clean-up.
David Barts <n5jrn@me.com>
parents: 7
diff changeset
113 println("Notes: ${notes ?: "(none)"}")
0
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
114 printDate("Created", created)
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
115 printDate("Modified", modified)
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
116 printDate("Accessed", accessed)
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
117 }
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
118
7
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
119 fun getField(name: String): Any? {
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
120 return FIELD_MAP[name]!!.call(this)
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
121 }
f245b9a53495 Efficiency improvements.
David Barts <n5jrn@me.com>
parents: 5
diff changeset
122
0
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
123 private fun printDate(tag: String, date: Date?) {
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
124 kotlin.io.print("${tag}: ")
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
125 if (date == null) {
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
126 println("never")
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
127 } else {
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
128 println(ISO8601.format(date))
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
129 }
a6cfdffcaa94 Initial commit, incomplete but it runs sorta.
David Barts <n5jrn@me.com>
parents:
diff changeset
130 }
8
698c4a3d758d Some code clean-up.
David Barts <n5jrn@me.com>
parents: 7
diff changeset
131 }