mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Manage default user name and color in KDB
This commit is contained in:
@@ -22,10 +22,10 @@ package com.kunzisoft.keepass.database.element
|
|||||||
import android.content.ContentResolver
|
import android.content.ContentResolver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
import android.graphics.Color
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Build
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
import com.kunzisoft.androidclearchroma.ChromaUtil
|
||||||
import com.kunzisoft.keepass.database.action.node.NodeHandler
|
import com.kunzisoft.keepass.database.action.node.NodeHandler
|
||||||
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
|
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
|
||||||
import com.kunzisoft.keepass.database.crypto.kdf.KdfEngine
|
import com.kunzisoft.keepass.database.crypto.kdf.KdfEngine
|
||||||
@@ -226,30 +226,31 @@ class Database {
|
|||||||
mDatabaseKDBX?.descriptionChanged = DateInstant()
|
mDatabaseKDBX?.descriptionChanged = DateInstant()
|
||||||
}
|
}
|
||||||
|
|
||||||
val allowDefaultUsername: Boolean
|
|
||||||
get() = mDatabaseKDBX != null
|
|
||||||
// TODO get() = mDatabaseKDB != null || mDatabaseKDBX != null
|
|
||||||
|
|
||||||
var defaultUsername: String
|
var defaultUsername: String
|
||||||
get() {
|
get() {
|
||||||
return mDatabaseKDBX?.defaultUserName ?: "" // TODO mDatabaseKDB default username
|
return mDatabaseKDB?.defaultUserName ?: mDatabaseKDBX?.defaultUserName ?: ""
|
||||||
}
|
}
|
||||||
set(username) {
|
set(username) {
|
||||||
|
mDatabaseKDB?.defaultUserName = username
|
||||||
mDatabaseKDBX?.defaultUserName = username
|
mDatabaseKDBX?.defaultUserName = username
|
||||||
mDatabaseKDBX?.defaultUserNameChanged = DateInstant()
|
mDatabaseKDBX?.defaultUserNameChanged = DateInstant()
|
||||||
}
|
}
|
||||||
|
|
||||||
val allowCustomColor: Boolean
|
|
||||||
get() = mDatabaseKDBX != null
|
|
||||||
// TODO get() = mDatabaseKDB != null || mDatabaseKDBX != null
|
|
||||||
|
|
||||||
// with format "#000000"
|
// with format "#000000"
|
||||||
var customColor: String
|
var customColor: String
|
||||||
get() {
|
get() {
|
||||||
return mDatabaseKDBX?.color ?: "" // TODO mDatabaseKDB color
|
var colorString = ""
|
||||||
|
mDatabaseKDB?.color?.let {
|
||||||
|
colorString = ChromaUtil.getFormattedColorString(it, false)
|
||||||
|
}
|
||||||
|
return mDatabaseKDBX?.color ?: colorString
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
// TODO Check color string
|
mDatabaseKDB?.color = if (value == "") {
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
Color.parseColor(value)
|
||||||
|
}
|
||||||
mDatabaseKDBX?.color = value
|
mDatabaseKDBX?.color = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -309,8 +309,9 @@ class Group : Node, GroupVersionedInterface<Group, Entry> {
|
|||||||
val withoutMetaStream = filters.contains(ChildFilter.META_STREAM)
|
val withoutMetaStream = filters.contains(ChildFilter.META_STREAM)
|
||||||
val showExpiredEntries = !filters.contains(ChildFilter.EXPIRED)
|
val showExpiredEntries = !filters.contains(ChildFilter.EXPIRED)
|
||||||
|
|
||||||
|
// TODO Change KDB parser to remove meta entries
|
||||||
return groupKDB?.getChildEntries()?.filter {
|
return groupKDB?.getChildEntries()?.filter {
|
||||||
(!withoutMetaStream || (withoutMetaStream && !it.isMetaStream))
|
(!withoutMetaStream || (withoutMetaStream && !it.isMetaStream()))
|
||||||
&& (!it.isCurrentlyExpires or showExpiredEntries)
|
&& (!it.isCurrentlyExpires or showExpiredEntries)
|
||||||
}?.map {
|
}?.map {
|
||||||
Entry(it)
|
Entry(it)
|
||||||
|
|||||||
@@ -61,6 +61,9 @@ class DatabaseKDB : DatabaseVersioned<Int, UUID, GroupKDB, EntryKDB>() {
|
|||||||
return listOf(BACKUP_FOLDER_TITLE)
|
return listOf(BACKUP_FOLDER_TITLE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var defaultUserName: String = ""
|
||||||
|
var color: Int? = null
|
||||||
|
|
||||||
override val kdfEngine: KdfEngine
|
override val kdfEngine: KdfEngine
|
||||||
get() = kdfListV3[0]
|
get() = kdfListV3[0]
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.kunzisoft.keepass.database.element.Attachment
|
|||||||
import com.kunzisoft.keepass.database.element.binary.AttachmentPool
|
import com.kunzisoft.keepass.database.element.binary.AttachmentPool
|
||||||
import com.kunzisoft.keepass.database.element.binary.BinaryData
|
import com.kunzisoft.keepass.database.element.binary.BinaryData
|
||||||
import com.kunzisoft.keepass.database.element.group.GroupKDB
|
import com.kunzisoft.keepass.database.element.group.GroupKDB
|
||||||
|
import com.kunzisoft.keepass.database.element.icon.IconImageStandard
|
||||||
import com.kunzisoft.keepass.database.element.icon.IconImageStandard.Companion.KEY_ID
|
import com.kunzisoft.keepass.database.element.icon.IconImageStandard.Companion.KEY_ID
|
||||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||||
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
||||||
@@ -60,18 +61,43 @@ class EntryKDB : EntryVersioned<Int, UUID, GroupKDB, EntryKDB>, NodeKDBInterface
|
|||||||
private var binaryDataId: Int? = null
|
private var binaryDataId: Int? = null
|
||||||
|
|
||||||
// Determine if this is a MetaStream entry
|
// Determine if this is a MetaStream entry
|
||||||
val isMetaStream: Boolean
|
fun isMetaStream(): Boolean {
|
||||||
get() {
|
if (notes.isEmpty()) return false
|
||||||
if (notes.isEmpty()) return false
|
if (binaryDescription != PMS_ID_BINDESC) return false
|
||||||
if (binaryDescription != PMS_ID_BINDESC) return false
|
if (title.isEmpty()) return false
|
||||||
if (title.isEmpty()) return false
|
if (title != PMS_ID_TITLE) return false
|
||||||
if (title != PMS_ID_TITLE) return false
|
if (username.isEmpty()) return false
|
||||||
if (username.isEmpty()) return false
|
if (username != PMS_ID_USER) return false
|
||||||
if (username != PMS_ID_USER) return false
|
if (url.isEmpty()) return false
|
||||||
if (url.isEmpty()) return false
|
if (url != PMS_ID_URL) return false
|
||||||
if (url != PMS_ID_URL) return false
|
return icon.standard.id == KEY_ID
|
||||||
return icon.standard.id == KEY_ID
|
}
|
||||||
}
|
|
||||||
|
fun isMetaStreamDefaultUsername(): Boolean {
|
||||||
|
return isMetaStream() && notes == PMS_STREAM_DEFAULTUSER
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setMetaStream() {
|
||||||
|
binaryDescription = PMS_ID_BINDESC
|
||||||
|
title = PMS_ID_TITLE
|
||||||
|
username = PMS_ID_USER
|
||||||
|
url = PMS_ID_URL
|
||||||
|
icon.standard = IconImageStandard(KEY_ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setMetaStreamDefaultUsername() {
|
||||||
|
notes = PMS_STREAM_DEFAULTUSER
|
||||||
|
setMetaStream()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isMetaStreamDatabaseColor(): Boolean {
|
||||||
|
return isMetaStream() && notes == PMS_STREAM_DBCOLOR
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setMetaStreamDatabaseColor() {
|
||||||
|
notes = PMS_STREAM_DBCOLOR
|
||||||
|
setMetaStream()
|
||||||
|
}
|
||||||
|
|
||||||
override fun initNodeId(): NodeId<UUID> {
|
override fun initNodeId(): NodeId<UUID> {
|
||||||
return NodeIdUUID()
|
return NodeIdUUID()
|
||||||
@@ -184,6 +210,13 @@ class EntryKDB : EntryVersioned<Int, UUID, GroupKDB, EntryKDB>, NodeKDBInterface
|
|||||||
private const val PMS_ID_USER = "SYSTEM"
|
private const val PMS_ID_USER = "SYSTEM"
|
||||||
private const val PMS_ID_URL = "$"
|
private const val PMS_ID_URL = "$"
|
||||||
|
|
||||||
|
const val PMS_STREAM_SIMPLESTATE = "Simple UI State"
|
||||||
|
const val PMS_STREAM_DEFAULTUSER = "Default User Name"
|
||||||
|
const val PMS_STREAM_SEARCHHISTORYITEM = "Search History Item"
|
||||||
|
const val PMS_STREAM_CUSTOMKVP = "Custom KVP"
|
||||||
|
const val PMS_STREAM_DBCOLOR = "Database Color"
|
||||||
|
const val PMS_STREAM_KPXICON2 = "KPX_CUSTOM_ICONS_2"
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
val CREATOR: Parcelable.Creator<EntryKDB> = object : Parcelable.Creator<EntryKDB> {
|
val CREATOR: Parcelable.Creator<EntryKDB> = object : Parcelable.Creator<EntryKDB> {
|
||||||
override fun createFromParcel(parcel: Parcel): EntryKDB {
|
override fun createFromParcel(parcel: Parcel): EntryKDB {
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import com.kunzisoft.keepass.database.element.group.GroupKDB
|
|||||||
import com.kunzisoft.keepass.database.element.node.NodeIdInt
|
import com.kunzisoft.keepass.database.element.node.NodeIdInt
|
||||||
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
||||||
import com.kunzisoft.keepass.database.exception.*
|
import com.kunzisoft.keepass.database.exception.*
|
||||||
import com.kunzisoft.keepass.database.file.DatabaseHeader
|
|
||||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDB
|
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDB
|
||||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
||||||
import com.kunzisoft.keepass.utils.*
|
import com.kunzisoft.keepass.utils.*
|
||||||
@@ -300,6 +299,22 @@ class DatabaseInputKDB(cacheDirectory: File,
|
|||||||
}
|
}
|
||||||
newEntry?.let { entry ->
|
newEntry?.let { entry ->
|
||||||
mDatabase.addEntryIndex(entry)
|
mDatabase.addEntryIndex(entry)
|
||||||
|
// Parse meta info
|
||||||
|
if (entry.isMetaStreamDefaultUsername()) {
|
||||||
|
var defaultUser = ""
|
||||||
|
entry.getBinary(mDatabase.attachmentPool)
|
||||||
|
?.getInputDataStream(mDatabase.binaryCache)?.use {
|
||||||
|
defaultUser = String(it.readBytes())
|
||||||
|
}
|
||||||
|
mDatabase.defaultUserName = defaultUser
|
||||||
|
} else if (entry.isMetaStreamDatabaseColor()) {
|
||||||
|
var color: Int? = null
|
||||||
|
entry.getBinary(mDatabase.attachmentPool)
|
||||||
|
?.getInputDataStream(mDatabase.binaryCache)?.use {
|
||||||
|
color = it.read()
|
||||||
|
}
|
||||||
|
mDatabase.color = color
|
||||||
|
}
|
||||||
currentEntryNumber++
|
currentEntryNumber++
|
||||||
newEntry = null
|
newEntry = null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB,
|
|||||||
private var mGroupList = mutableListOf<GroupKDB>()
|
private var mGroupList = mutableListOf<GroupKDB>()
|
||||||
private var mEntryList = mutableListOf<EntryKDB>()
|
private var mEntryList = mutableListOf<EntryKDB>()
|
||||||
|
|
||||||
|
private var mDefaultUsernameAdded = false
|
||||||
|
private var mDatabaseColorAdded = false
|
||||||
|
|
||||||
@Throws(DatabaseOutputException::class)
|
@Throws(DatabaseOutputException::class)
|
||||||
fun getFinalKey(header: DatabaseHeader): ByteArray? {
|
fun getFinalKey(header: DatabaseHeader): ByteArray? {
|
||||||
try {
|
try {
|
||||||
@@ -94,8 +97,7 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB,
|
|||||||
} finally {
|
} finally {
|
||||||
// Add again the virtual root group for better management
|
// Add again the virtual root group for better management
|
||||||
mDatabaseKDB.rootGroup = rootGroup
|
mDatabaseKDB.rootGroup = rootGroup
|
||||||
mGroupList.clear()
|
clearParser()
|
||||||
mEntryList.clear()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,9 +213,14 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sortNodesForOutput() {
|
private fun clearParser() {
|
||||||
mGroupList.clear()
|
mGroupList.clear()
|
||||||
mEntryList.clear()
|
mEntryList.clear()
|
||||||
|
mDefaultUsernameAdded = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sortNodesForOutput() {
|
||||||
|
clearParser()
|
||||||
// Rebuild list according to sorting order removing any orphaned groups
|
// Rebuild list according to sorting order removing any orphaned groups
|
||||||
// Do not keep root
|
// Do not keep root
|
||||||
mDatabaseKDB.rootGroup?.getChildGroups()?.let { rootSubGroups ->
|
mDatabaseKDB.rootGroup?.getChildGroups()?.let { rootSubGroups ->
|
||||||
@@ -228,7 +235,39 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB,
|
|||||||
mGroupList.add(group)
|
mGroupList.add(group)
|
||||||
|
|
||||||
for (childEntry in group.getChildEntries()) {
|
for (childEntry in group.getChildEntries()) {
|
||||||
mEntryList.add(childEntry)
|
if (childEntry.isMetaStreamDefaultUsername()
|
||||||
|
&& mDatabaseKDB.defaultUserName.isNotEmpty()) {
|
||||||
|
setDefaultUsername(childEntry)
|
||||||
|
mEntryList.add(childEntry)
|
||||||
|
mDefaultUsernameAdded = true
|
||||||
|
} else if (childEntry.isMetaStreamDatabaseColor()
|
||||||
|
&& mDatabaseKDB.color != null) {
|
||||||
|
setDatabaseColor(childEntry)
|
||||||
|
mEntryList.add(childEntry)
|
||||||
|
mDatabaseColorAdded = true
|
||||||
|
} else {
|
||||||
|
mEntryList.add(childEntry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add MetaStream
|
||||||
|
if (!mDefaultUsernameAdded
|
||||||
|
&& mDatabaseKDB.defaultUserName.isNotEmpty()) {
|
||||||
|
val metaEntry = EntryKDB().apply {
|
||||||
|
setMetaStreamDefaultUsername()
|
||||||
|
setDefaultUsername(this)
|
||||||
|
}
|
||||||
|
mDatabaseKDB.addEntryTo(metaEntry, group)
|
||||||
|
mEntryList.add(metaEntry)
|
||||||
|
}
|
||||||
|
if (!mDatabaseColorAdded
|
||||||
|
&& mDatabaseKDB.color != null) {
|
||||||
|
val metaEntry = EntryKDB().apply {
|
||||||
|
setMetaStreamDatabaseColor()
|
||||||
|
setDatabaseColor(this)
|
||||||
|
}
|
||||||
|
mDatabaseKDB.addEntryTo(metaEntry, group)
|
||||||
|
mEntryList.add(metaEntry)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recurse over children
|
// Recurse over children
|
||||||
@@ -237,6 +276,22 @@ class DatabaseOutputKDB(private val mDatabaseKDB: DatabaseKDB,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setDefaultUsername(entryKDB: EntryKDB) {
|
||||||
|
val binaryData = mDatabaseKDB.buildNewAttachment()
|
||||||
|
entryKDB.putBinary(binaryData, mDatabaseKDB.attachmentPool)
|
||||||
|
BufferedOutputStream(binaryData.getOutputDataStream(mDatabaseKDB.binaryCache)).use { outputStream ->
|
||||||
|
outputStream.write(mDatabaseKDB.defaultUserName.toByteArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setDatabaseColor(entryKDB: EntryKDB) {
|
||||||
|
val binaryData = mDatabaseKDB.buildNewAttachment()
|
||||||
|
entryKDB.putBinary(binaryData, mDatabaseKDB.attachmentPool)
|
||||||
|
BufferedOutputStream(binaryData.getOutputDataStream(mDatabaseKDB.binaryCache)).use { outputStream ->
|
||||||
|
outputStream.write(mDatabaseKDB.color!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getHeaderHashBuffer(headerDigest: ByteArray): ByteArray? {
|
private fun getHeaderHashBuffer(headerDigest: ByteArray): ByteArray? {
|
||||||
return try {
|
return try {
|
||||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ import androidx.preference.PreferenceCategory
|
|||||||
import androidx.preference.SwitchPreference
|
import androidx.preference.SwitchPreference
|
||||||
import com.kunzisoft.androidclearchroma.ChromaUtil
|
import com.kunzisoft.androidclearchroma.ChromaUtil
|
||||||
import com.kunzisoft.keepass.R
|
import com.kunzisoft.keepass.R
|
||||||
import com.kunzisoft.keepass.activities.legacy.DatabaseRetrieval
|
|
||||||
import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment
|
import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment
|
||||||
|
import com.kunzisoft.keepass.activities.legacy.DatabaseRetrieval
|
||||||
import com.kunzisoft.keepass.activities.legacy.resetAppTimeoutWhenViewTouchedOrFocused
|
import com.kunzisoft.keepass.activities.legacy.resetAppTimeoutWhenViewTouchedOrFocused
|
||||||
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
|
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
|
||||||
import com.kunzisoft.keepass.database.crypto.kdf.KdfEngine
|
import com.kunzisoft.keepass.database.crypto.kdf.KdfEngine
|
||||||
@@ -165,28 +165,18 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment(), DatabaseRetriev
|
|||||||
|
|
||||||
// Database default username
|
// Database default username
|
||||||
dbDefaultUsernamePref = findPreference(getString(R.string.database_default_username_key))
|
dbDefaultUsernamePref = findPreference(getString(R.string.database_default_username_key))
|
||||||
if (database.allowDefaultUsername) {
|
dbDefaultUsernamePref?.summary = database.defaultUsername
|
||||||
dbDefaultUsernamePref?.summary = database.defaultUsername
|
|
||||||
} else {
|
|
||||||
dbDefaultUsernamePref?.isEnabled = false
|
|
||||||
// TODO dbGeneralPrefCategory?.removePreference(dbDefaultUsername)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Database custom color
|
// Database custom color
|
||||||
dbCustomColorPref = findPreference(getString(R.string.database_custom_color_key))
|
dbCustomColorPref = findPreference(getString(R.string.database_custom_color_key))
|
||||||
if (database.allowCustomColor) {
|
dbCustomColorPref?.apply {
|
||||||
dbCustomColorPref?.apply {
|
try {
|
||||||
try {
|
color = Color.parseColor(database.customColor)
|
||||||
color = Color.parseColor(database.customColor)
|
summary = database.customColor
|
||||||
summary = database.customColor
|
} catch (e: Exception) {
|
||||||
} catch (e: Exception) {
|
color = DialogColorPreference.DISABLE_COLOR
|
||||||
color = DialogColorPreference.DISABLE_COLOR
|
summary = ""
|
||||||
summary = ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
dbCustomColorPref?.isEnabled = false
|
|
||||||
// TODO dbGeneralPrefCategory?.removePreference(dbCustomColorPref)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version
|
// Version
|
||||||
|
|||||||
Reference in New Issue
Block a user