Mercurial > cgi-bin > hgweb.cgi > PassMan
view src/main/kotlin/name/blackcap/passman/Entry.kt @ 19:7d80cbcb67bb
add shlex-style splitter and tests
author | David Barts <n5jrn@me.com> |
---|---|
date | Sun, 30 Jun 2024 20:37:36 -0700 |
parents | a38a2a1036c3 |
children | 3a3067ba673b |
line wrap: on
line source
package name.blackcap.passman import java.sql.ResultSet import java.util.* import kotlin.reflect.KProperty import kotlin.reflect.full.declaredMemberProperties class Entry(val name: String, val username: String, val password: CharArray, val notes: String?, val created: Date? = null, val modified: Date? = null, val accessed: Date? = null) { companion object { private val FIELD_MAP = mutableMapOf<String, KProperty.Getter<*>>().apply { Entry::class.declaredMemberProperties.forEach{ this[it.name] = it.getter } } fun withPromptedPassword() = Entry( name = _getName(), username = _getUsername(), password = _getPassword(), notes = _getNotes() ) fun withGeneratedPassword(length: Int, allowSymbols: Boolean, verbose: Boolean): Entry { return Entry( name = _getName(), username = _getUsername(), password = _genPassword(length, allowSymbols, verbose), notes = _getNotes() ) } fun fromDatabase(db: Database, name: String): Entry? { db.connection.prepareStatement("select name, username, password, notes, created, modified, accessed from passwords where id = ?").use { it.setLong(1, db.makeKey(name)) val results = it.executeQuery() if (!results.next()) { return null } return Entry( name = results.getDecryptedString(1, db.encryption)!!, username = results.getDecryptedString(2, db.encryption)!!, password = results.getDecrypted(3, db.encryption)!!, notes = results.getDecryptedString(4, db.encryption), created = results.getDate(5), modified = results.getDate(6), accessed = results.getDate(7) ) } } private fun _genPassword(length: Int, allowSymbols: Boolean, verbose: Boolean): CharArray { val generated = generate(length, allowSymbols) if (verbose) { printPassword(generated) } return generated } private fun _getName() = mustReadLine("Name of site: ") private fun _getUsername() = mustReadLine("Username: ") private fun _getPassword() = mustGetPassword("Password: ", verify = true) private fun _getNotes() = readLine("Notes: ") } fun insert(db: Database) { db.connection.prepareStatement("insert into passwords (id, name, username, password, notes, created, modified, accessed) values (?, ?, ?, ?, ?, ?, ?, ?)") .use { it.setLong(1, db.makeKey(name)) it.setEncryptedString(2, name, db.encryption) it.setEncryptedString(3, username, db.encryption) it.setEncrypted(4, password, db.encryption) it.setEncryptedString(5, notes, db.encryption) it.setLongOrNull(6, created?.time) it.setLongOrNull(7, modified?.time) it.setLongOrNull(8, accessed?.time) it.executeUpdate() } } fun update(db: Database) { db.connection.prepareStatement("update passwords set name = ?, username = ?, password = ?, notes = ?, created = ?, modified = ?, accessed = ? where id = ?").use { it.setEncryptedString(1, name, db.encryption) it.setEncryptedString(2, username, db.encryption) it.setEncrypted(3, password, db.encryption) it.setEncryptedString(4, notes, db.encryption) it.setLongOrNull(5, created?.time) it.setLongOrNull(6, modified?.time) it.setLongOrNull(7, accessed?.time) it.setLong(8, db.makeKey(name)) it.executeUpdate() } } val modifiedOrCreated get() = modified ?: created!! fun print(redactPassword: String? = null) { println("Name of site: $name") println("Username: $username") if (redactPassword == null) { printPassword(password) } else { println("Password: $redactPassword") } } fun printLong(redactPassword: String? = null) { this.print(redactPassword) println("Notes: ${notes ?: "(none)"}") printDate("Created", created) printDate("Modified", modified) printDate("Accessed", accessed) } fun getField(name: String): Any? { return FIELD_MAP[name]!!.call(this) } private fun printDate(tag: String, date: Date?) { kotlin.io.print("${tag}: ") if (date == null) { println("never") } else { println(ISO8601.format(date)) } } }