mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Better database loader implementation
This commit is contained in:
@@ -60,7 +60,6 @@ class LoadDatabaseRunnable(private val context: Context,
|
||||
{ memoryWanted ->
|
||||
BinaryData.canMemoryBeAllocatedInRAM(context, memoryWanted)
|
||||
},
|
||||
LoadedKey.generateNewCipherKey(),
|
||||
mFixDuplicateUUID,
|
||||
progressTaskUpdater)
|
||||
}
|
||||
|
||||
@@ -35,21 +35,16 @@ class MergeDatabaseRunnable(private val context: Context,
|
||||
private val mLoadDatabaseResult: ((Result) -> Unit)?)
|
||||
: ActionRunnable() {
|
||||
|
||||
private var tempCipherKey: LoadedKey? = null
|
||||
|
||||
override fun onStartRun() {
|
||||
tempCipherKey = mDatabase.binaryCache.loadedCipherKey
|
||||
mDatabase.wasReloaded = true
|
||||
}
|
||||
|
||||
override fun onActionRun() {
|
||||
try {
|
||||
mDatabase.mergeData(context.contentResolver,
|
||||
UriUtil.getBinaryDir(context),
|
||||
{ memoryWanted ->
|
||||
BinaryData.canMemoryBeAllocatedInRAM(context, memoryWanted)
|
||||
},
|
||||
tempCipherKey ?: LoadedKey.generateNewCipherKey(),
|
||||
progressTaskUpdater)
|
||||
} catch (e: LoadDatabaseException) {
|
||||
setError(e)
|
||||
@@ -59,7 +54,6 @@ class MergeDatabaseRunnable(private val context: Context,
|
||||
// Register the current time to init the lock timer
|
||||
PreferencesUtil.saveCurrentTime(context)
|
||||
} else {
|
||||
tempCipherKey = null
|
||||
mDatabase.clearAndClose(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,7 @@ class ReloadDatabaseRunnable(private val context: Context,
|
||||
private val mLoadDatabaseResult: ((Result) -> Unit)?)
|
||||
: ActionRunnable() {
|
||||
|
||||
private var tempCipherKey: LoadedKey? = null
|
||||
|
||||
override fun onStartRun() {
|
||||
tempCipherKey = mDatabase.binaryCache.loadedCipherKey
|
||||
// Clear before we load
|
||||
mDatabase.clear(UriUtil.getBinaryDir(context))
|
||||
mDatabase.wasReloaded = true
|
||||
@@ -47,11 +44,9 @@ class ReloadDatabaseRunnable(private val context: Context,
|
||||
override fun onActionRun() {
|
||||
try {
|
||||
mDatabase.reloadData(context.contentResolver,
|
||||
UriUtil.getBinaryDir(context),
|
||||
{ memoryWanted ->
|
||||
BinaryData.canMemoryBeAllocatedInRAM(context, memoryWanted)
|
||||
},
|
||||
tempCipherKey ?: LoadedKey.generateNewCipherKey(),
|
||||
progressTaskUpdater)
|
||||
} catch (e: LoadDatabaseException) {
|
||||
setError(e)
|
||||
@@ -61,7 +56,6 @@ class ReloadDatabaseRunnable(private val context: Context,
|
||||
// Register the current time to init the lock timer
|
||||
PreferencesUtil.saveCurrentTime(context)
|
||||
} else {
|
||||
tempCipherKey = null
|
||||
mDatabase.clearAndClose(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ import com.kunzisoft.keepass.database.crypto.kdf.KdfEngine
|
||||
import com.kunzisoft.keepass.database.element.binary.AttachmentPool
|
||||
import com.kunzisoft.keepass.database.element.binary.BinaryCache
|
||||
import com.kunzisoft.keepass.database.element.binary.BinaryData
|
||||
import com.kunzisoft.keepass.database.element.binary.LoadedKey
|
||||
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
||||
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
|
||||
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
|
||||
@@ -143,7 +142,7 @@ class Database {
|
||||
|
||||
fun removeCustomIcon(customIcon: IconImageCustom) {
|
||||
iconDrawableFactory.clearFromCache(customIcon)
|
||||
iconsManager.removeCustomIcon(binaryCache, customIcon.uuid)
|
||||
iconsManager.removeCustomIcon(customIcon.uuid)
|
||||
mDatabaseKDBX?.addDeletedObject(customIcon.uuid)
|
||||
}
|
||||
|
||||
@@ -575,7 +574,6 @@ class Database {
|
||||
contentResolver: ContentResolver,
|
||||
cacheDirectory: File,
|
||||
isRAMSufficient: (memoryWanted: Long) -> Boolean,
|
||||
tempCipherKey: LoadedKey,
|
||||
fixDuplicateUUID: Boolean,
|
||||
progressTaskUpdater: ProgressTaskUpdater?) {
|
||||
|
||||
@@ -596,22 +594,30 @@ class Database {
|
||||
// Read database stream for the first time
|
||||
readDatabaseStream(contentResolver, uri,
|
||||
{ databaseInputStream ->
|
||||
DatabaseInputKDB(cacheDirectory, isRAMSufficient)
|
||||
.openDatabase(databaseInputStream,
|
||||
mainCredential.masterPassword,
|
||||
keyFileInputStream,
|
||||
tempCipherKey,
|
||||
progressTaskUpdater,
|
||||
fixDuplicateUUID)
|
||||
val databaseKDB = DatabaseKDB().apply {
|
||||
binaryCache.cacheDirectory = cacheDirectory
|
||||
changeDuplicateId = fixDuplicateUUID
|
||||
}
|
||||
DatabaseInputKDB(databaseKDB)
|
||||
.openDatabase(databaseInputStream,
|
||||
mainCredential.masterPassword,
|
||||
keyFileInputStream,
|
||||
progressTaskUpdater)
|
||||
databaseKDB
|
||||
},
|
||||
{ databaseInputStream ->
|
||||
DatabaseInputKDBX(cacheDirectory, isRAMSufficient)
|
||||
.openDatabase(databaseInputStream,
|
||||
mainCredential.masterPassword,
|
||||
keyFileInputStream,
|
||||
tempCipherKey,
|
||||
progressTaskUpdater,
|
||||
fixDuplicateUUID)
|
||||
val databaseKDBX = DatabaseKDBX().apply {
|
||||
binaryCache.cacheDirectory = cacheDirectory
|
||||
changeDuplicateId = fixDuplicateUUID
|
||||
}
|
||||
DatabaseInputKDBX(databaseKDBX).apply {
|
||||
setMethodToCheckIfRAMIsSufficient(isRAMSufficient)
|
||||
openDatabase(databaseInputStream,
|
||||
mainCredential.masterPassword,
|
||||
keyFileInputStream,
|
||||
progressTaskUpdater)
|
||||
}
|
||||
databaseKDBX
|
||||
}
|
||||
)
|
||||
} catch (e: FileNotFoundException) {
|
||||
@@ -628,43 +634,55 @@ class Database {
|
||||
|
||||
@Throws(LoadDatabaseException::class)
|
||||
fun mergeData(contentResolver: ContentResolver,
|
||||
cacheDirectory: File,
|
||||
isRAMSufficient: (memoryWanted: Long) -> Boolean,
|
||||
tempCipherKey: LoadedKey,
|
||||
progressTaskUpdater: ProgressTaskUpdater?) {
|
||||
|
||||
// New database instance to get new changes
|
||||
val databaseToMerge = Database()
|
||||
databaseToMerge.fileUri = this.fileUri
|
||||
|
||||
try {
|
||||
databaseToMerge.fileUri?.let { databaseUri ->
|
||||
|
||||
// TODO Merge KDB
|
||||
var databaseMerger: DatabaseKDBXMerger? = null
|
||||
|
||||
databaseToMerge.readDatabaseStream(contentResolver, databaseUri,
|
||||
{ databaseInputStream ->
|
||||
DatabaseInputKDB(cacheDirectory, isRAMSufficient)
|
||||
val databaseKDB = DatabaseKDB()
|
||||
this.mDatabaseKDB?.let {
|
||||
databaseKDB.binaryCache = it.binaryCache
|
||||
}
|
||||
DatabaseInputKDB(databaseKDB)
|
||||
.openDatabase(databaseInputStream,
|
||||
masterKey,
|
||||
tempCipherKey,
|
||||
progressTaskUpdater)
|
||||
databaseKDB
|
||||
},
|
||||
{ databaseInputStream ->
|
||||
DatabaseInputKDBX(cacheDirectory, isRAMSufficient)
|
||||
.openDatabase(databaseInputStream,
|
||||
val databaseKDBX = DatabaseKDBX()
|
||||
// Share cache
|
||||
this.mDatabaseKDBX?.let {
|
||||
databaseKDBX.binaryCache = it.binaryCache
|
||||
}
|
||||
databaseMerger = DatabaseKDBXMerger(databaseKDBX)
|
||||
DatabaseInputKDBX(databaseKDBX).apply {
|
||||
setMethodToCheckIfRAMIsSufficient(isRAMSufficient)
|
||||
openDatabase(databaseInputStream,
|
||||
masterKey,
|
||||
tempCipherKey,
|
||||
progressTaskUpdater)
|
||||
}
|
||||
databaseKDBX
|
||||
}
|
||||
)
|
||||
|
||||
databaseToMerge.mDatabaseKDBX?.let { databaseKDBXToMerge ->
|
||||
databaseMerger?.merge(databaseKDBXToMerge)
|
||||
}
|
||||
} ?: run {
|
||||
Log.e(TAG, "Database URI is null, database cannot be reloaded")
|
||||
throw IODatabaseException()
|
||||
}
|
||||
|
||||
// TODO Merge KDB
|
||||
mDatabaseKDBX?.let { databaseKDBX ->
|
||||
databaseToMerge.mDatabaseKDBX?.let { databaseKDBXToMerge ->
|
||||
DatabaseKDBXMerger(databaseKDBX).merge(databaseKDBXToMerge)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw LoadDatabaseException(e)
|
||||
} finally {
|
||||
@@ -674,9 +692,7 @@ class Database {
|
||||
|
||||
@Throws(LoadDatabaseException::class)
|
||||
fun reloadData(contentResolver: ContentResolver,
|
||||
cacheDirectory: File,
|
||||
isRAMSufficient: (memoryWanted: Long) -> Boolean,
|
||||
tempCipherKey: LoadedKey,
|
||||
progressTaskUpdater: ProgressTaskUpdater?) {
|
||||
|
||||
// Retrieve the stream from the old database URI
|
||||
@@ -684,18 +700,28 @@ class Database {
|
||||
fileUri?.let { oldDatabaseUri ->
|
||||
readDatabaseStream(contentResolver, oldDatabaseUri,
|
||||
{ databaseInputStream ->
|
||||
DatabaseInputKDB(cacheDirectory, isRAMSufficient)
|
||||
val databaseKDB = DatabaseKDB()
|
||||
mDatabaseKDB?.let {
|
||||
databaseKDB.binaryCache = it.binaryCache
|
||||
}
|
||||
DatabaseInputKDB(databaseKDB)
|
||||
.openDatabase(databaseInputStream,
|
||||
masterKey,
|
||||
tempCipherKey,
|
||||
progressTaskUpdater)
|
||||
databaseKDB
|
||||
},
|
||||
{ databaseInputStream ->
|
||||
DatabaseInputKDBX(cacheDirectory, isRAMSufficient)
|
||||
.openDatabase(databaseInputStream,
|
||||
val databaseKDBX = DatabaseKDBX()
|
||||
mDatabaseKDBX?.let {
|
||||
databaseKDBX.binaryCache = it.binaryCache
|
||||
}
|
||||
DatabaseInputKDBX(databaseKDBX).apply {
|
||||
setMethodToCheckIfRAMIsSufficient(isRAMSufficient)
|
||||
openDatabase(databaseInputStream,
|
||||
masterKey,
|
||||
tempCipherKey,
|
||||
progressTaskUpdater)
|
||||
}
|
||||
databaseKDBX
|
||||
}
|
||||
)
|
||||
} ?: run {
|
||||
|
||||
@@ -28,29 +28,18 @@ import java.util.*
|
||||
class DeletedObject : Parcelable {
|
||||
|
||||
var uuid: UUID = DatabaseVersioned.UUID_ZERO
|
||||
private var mDeletionTime: DateInstant? = null
|
||||
var deletionTime: DateInstant = DateInstant()
|
||||
|
||||
constructor()
|
||||
|
||||
constructor(uuid: UUID, deletionTime: DateInstant = DateInstant()) {
|
||||
this.uuid = uuid
|
||||
this.mDeletionTime = deletionTime
|
||||
this.deletionTime = deletionTime
|
||||
}
|
||||
|
||||
constructor(parcel: Parcel) {
|
||||
uuid = parcel.readParcelable<ParcelUuid>(ParcelUuid::class.java.classLoader)?.uuid ?: DatabaseVersioned.UUID_ZERO
|
||||
mDeletionTime = parcel.readParcelable(DateInstant::class.java.classLoader)
|
||||
}
|
||||
|
||||
fun getDeletionTime(): DateInstant {
|
||||
if (mDeletionTime == null) {
|
||||
mDeletionTime = DateInstant(System.currentTimeMillis())
|
||||
}
|
||||
return mDeletionTime!!
|
||||
}
|
||||
|
||||
fun setDeletionTime(deletionTime: DateInstant) {
|
||||
this.mDeletionTime = deletionTime
|
||||
deletionTime = parcel.readParcelable(DateInstant::class.java.classLoader) ?: deletionTime
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
@@ -69,7 +58,7 @@ class DeletedObject : Parcelable {
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
parcel.writeParcelable(ParcelUuid(uuid), flags)
|
||||
parcel.writeParcelable(mDeletionTime, flags)
|
||||
parcel.writeParcelable(deletionTime, flags)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
|
||||
@@ -336,6 +336,10 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
|
||||
iconsManager.addCustomIcon(customIconId, name, lastModificationTime, smallSize, result)
|
||||
}
|
||||
|
||||
fun removeCustomIcon(iconUuid: UUID) {
|
||||
iconsManager.removeCustomIcon(iconUuid)
|
||||
}
|
||||
|
||||
fun isCustomIconBinaryDuplicate(binary: BinaryData): Boolean {
|
||||
return iconsManager.isCustomIconBinaryDuplicate(binary)
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ abstract class DatabaseVersioned<
|
||||
* Can be used to temporarily store database elements
|
||||
*/
|
||||
var binaryCache = BinaryCache()
|
||||
val iconsManager = IconsManager(binaryCache)
|
||||
var iconsManager = IconsManager(binaryCache)
|
||||
var attachmentPool = AttachmentPool(binaryCache)
|
||||
|
||||
var changeDuplicateId = false
|
||||
|
||||
@@ -28,7 +28,7 @@ import com.kunzisoft.keepass.database.element.icon.IconImageStandard.Companion.K
|
||||
import com.kunzisoft.keepass.icons.IconPack.Companion.NB_ICONS
|
||||
import java.util.*
|
||||
|
||||
class IconsManager(binaryCache: BinaryCache) {
|
||||
class IconsManager(private var binaryCache: BinaryCache) {
|
||||
|
||||
private val standardCache = List(NB_ICONS) {
|
||||
IconImageStandard(it)
|
||||
@@ -72,7 +72,7 @@ class IconsManager(binaryCache: BinaryCache) {
|
||||
return customCache.isBinaryDuplicate(binaryData)
|
||||
}
|
||||
|
||||
fun removeCustomIcon(binaryCache: BinaryCache, iconUuid: UUID) {
|
||||
fun removeCustomIcon(iconUuid: UUID) {
|
||||
val binary = customCache[iconUuid]
|
||||
customCache.remove(iconUuid)
|
||||
try {
|
||||
|
||||
@@ -21,16 +21,12 @@ package com.kunzisoft.keepass.database.file.input
|
||||
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.binary.LoadedKey
|
||||
import com.kunzisoft.keepass.database.element.database.DatabaseVersioned
|
||||
import com.kunzisoft.keepass.database.exception.LoadDatabaseException
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
|
||||
abstract class DatabaseInput<D : DatabaseVersioned<*, *, *, *>>
|
||||
(protected val cacheDirectory: File,
|
||||
protected val isRAMSufficient: (memoryWanted: Long) -> Boolean) {
|
||||
abstract class DatabaseInput<D : DatabaseVersioned<*, *, *, *>> (protected var mDatabase: D) {
|
||||
|
||||
private var startTimeKey = System.currentTimeMillis()
|
||||
private var startTimeContent = System.currentTimeMillis()
|
||||
@@ -49,17 +45,13 @@ abstract class DatabaseInput<D : DatabaseVersioned<*, *, *, *>>
|
||||
abstract fun openDatabase(databaseInputStream: InputStream,
|
||||
password: String?,
|
||||
keyfileInputStream: InputStream?,
|
||||
loadedCipherKey: LoadedKey,
|
||||
progressTaskUpdater: ProgressTaskUpdater?,
|
||||
fixDuplicateUUID: Boolean = false): D
|
||||
progressTaskUpdater: ProgressTaskUpdater?): D
|
||||
|
||||
|
||||
@Throws(LoadDatabaseException::class)
|
||||
abstract fun openDatabase(databaseInputStream: InputStream,
|
||||
masterKey: ByteArray,
|
||||
loadedCipherKey: LoadedKey,
|
||||
progressTaskUpdater: ProgressTaskUpdater?,
|
||||
fixDuplicateUUID: Boolean = false): D
|
||||
progressTaskUpdater: ProgressTaskUpdater?): D
|
||||
|
||||
protected fun startKeyTimer(progressTaskUpdater: ProgressTaskUpdater?) {
|
||||
progressTaskUpdater?.updateMessage(R.string.retrieving_db_key)
|
||||
|
||||
@@ -23,7 +23,6 @@ package com.kunzisoft.keepass.database.file.input
|
||||
import com.kunzisoft.encrypt.HashManager
|
||||
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
|
||||
import com.kunzisoft.keepass.database.element.DateInstant
|
||||
import com.kunzisoft.keepass.database.element.binary.LoadedKey
|
||||
import com.kunzisoft.keepass.database.element.database.DatabaseKDB
|
||||
import com.kunzisoft.keepass.database.element.entry.EntryKDB
|
||||
import com.kunzisoft.keepass.database.element.group.GroupKDB
|
||||
@@ -46,21 +45,15 @@ import kotlin.collections.HashMap
|
||||
/**
|
||||
* Load a KDB database file.
|
||||
*/
|
||||
class DatabaseInputKDB(cacheDirectory: File,
|
||||
isRAMSufficient: (memoryWanted: Long) -> Boolean)
|
||||
: DatabaseInput<DatabaseKDB>(cacheDirectory, isRAMSufficient) {
|
||||
|
||||
private lateinit var mDatabase: DatabaseKDB
|
||||
class DatabaseInputKDB(database: DatabaseKDB)
|
||||
: DatabaseInput<DatabaseKDB>(database) {
|
||||
|
||||
@Throws(LoadDatabaseException::class)
|
||||
override fun openDatabase(databaseInputStream: InputStream,
|
||||
password: String?,
|
||||
keyfileInputStream: InputStream?,
|
||||
loadedCipherKey: LoadedKey,
|
||||
progressTaskUpdater: ProgressTaskUpdater?,
|
||||
fixDuplicateUUID: Boolean): DatabaseKDB {
|
||||
return openDatabase(databaseInputStream, progressTaskUpdater, fixDuplicateUUID) {
|
||||
mDatabase.binaryCache.loadedCipherKey = loadedCipherKey
|
||||
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDB {
|
||||
return openDatabase(databaseInputStream, progressTaskUpdater) {
|
||||
mDatabase.retrieveMasterKey(password, keyfileInputStream)
|
||||
}
|
||||
}
|
||||
@@ -68,11 +61,8 @@ class DatabaseInputKDB(cacheDirectory: File,
|
||||
@Throws(LoadDatabaseException::class)
|
||||
override fun openDatabase(databaseInputStream: InputStream,
|
||||
masterKey: ByteArray,
|
||||
loadedCipherKey: LoadedKey,
|
||||
progressTaskUpdater: ProgressTaskUpdater?,
|
||||
fixDuplicateUUID: Boolean): DatabaseKDB {
|
||||
return openDatabase(databaseInputStream, progressTaskUpdater, fixDuplicateUUID) {
|
||||
mDatabase.binaryCache.loadedCipherKey = loadedCipherKey
|
||||
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDB {
|
||||
return openDatabase(databaseInputStream, progressTaskUpdater) {
|
||||
mDatabase.masterKey = masterKey
|
||||
}
|
||||
}
|
||||
@@ -80,7 +70,6 @@ class DatabaseInputKDB(cacheDirectory: File,
|
||||
@Throws(LoadDatabaseException::class)
|
||||
private fun openDatabase(databaseInputStream: InputStream,
|
||||
progressTaskUpdater: ProgressTaskUpdater?,
|
||||
fixDuplicateUUID: Boolean,
|
||||
assignMasterKey: (() -> Unit)? = null): DatabaseKDB {
|
||||
|
||||
try {
|
||||
@@ -107,10 +96,6 @@ class DatabaseInputKDB(cacheDirectory: File,
|
||||
throw VersionDatabaseException()
|
||||
}
|
||||
|
||||
mDatabase = DatabaseKDB()
|
||||
mDatabase.binaryCache.cacheDirectory = cacheDirectory
|
||||
|
||||
mDatabase.changeDuplicateId = fixDuplicateUUID
|
||||
assignMasterKey?.invoke()
|
||||
|
||||
// Select algorithm
|
||||
|
||||
@@ -63,12 +63,10 @@ import javax.crypto.CipherInputStream
|
||||
import javax.crypto.Mac
|
||||
import kotlin.math.min
|
||||
|
||||
class DatabaseInputKDBX(cacheDirectory: File,
|
||||
isRAMSufficient: (memoryWanted: Long) -> Boolean)
|
||||
: DatabaseInput<DatabaseKDBX>(cacheDirectory, isRAMSufficient) {
|
||||
class DatabaseInputKDBX(database: DatabaseKDBX)
|
||||
: DatabaseInput<DatabaseKDBX>(database) {
|
||||
|
||||
private var randomStream: StreamCipher? = null
|
||||
private lateinit var mDatabase: DatabaseKDBX
|
||||
|
||||
private var hashOfHeader: ByteArray? = null
|
||||
|
||||
@@ -97,15 +95,18 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
||||
private var entryCustomDataKey: String? = null
|
||||
private var entryCustomDataValue: String? = null
|
||||
|
||||
private var isRAMSufficient: (memoryWanted: Long) -> Boolean = {true}
|
||||
|
||||
fun setMethodToCheckIfRAMIsSufficient(method: (memoryWanted: Long) -> Boolean) {
|
||||
this.isRAMSufficient = method
|
||||
}
|
||||
|
||||
@Throws(LoadDatabaseException::class)
|
||||
override fun openDatabase(databaseInputStream: InputStream,
|
||||
password: String?,
|
||||
keyfileInputStream: InputStream?,
|
||||
loadedCipherKey: LoadedKey,
|
||||
progressTaskUpdater: ProgressTaskUpdater?,
|
||||
fixDuplicateUUID: Boolean): DatabaseKDBX {
|
||||
return openDatabase(databaseInputStream, progressTaskUpdater, fixDuplicateUUID) {
|
||||
mDatabase.binaryCache.loadedCipherKey = loadedCipherKey
|
||||
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDBX {
|
||||
return openDatabase(databaseInputStream, progressTaskUpdater) {
|
||||
mDatabase.retrieveMasterKey(password, keyfileInputStream)
|
||||
}
|
||||
}
|
||||
@@ -113,11 +114,8 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
||||
@Throws(LoadDatabaseException::class)
|
||||
override fun openDatabase(databaseInputStream: InputStream,
|
||||
masterKey: ByteArray,
|
||||
loadedCipherKey: LoadedKey,
|
||||
progressTaskUpdater: ProgressTaskUpdater?,
|
||||
fixDuplicateUUID: Boolean): DatabaseKDBX {
|
||||
return openDatabase(databaseInputStream, progressTaskUpdater, fixDuplicateUUID) {
|
||||
mDatabase.binaryCache.loadedCipherKey = loadedCipherKey
|
||||
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDBX {
|
||||
return openDatabase(databaseInputStream, progressTaskUpdater) {
|
||||
mDatabase.masterKey = masterKey
|
||||
}
|
||||
}
|
||||
@@ -125,14 +123,9 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
||||
@Throws(LoadDatabaseException::class)
|
||||
private fun openDatabase(databaseInputStream: InputStream,
|
||||
progressTaskUpdater: ProgressTaskUpdater?,
|
||||
fixDuplicateUUID: Boolean,
|
||||
assignMasterKey: (() -> Unit)? = null): DatabaseKDBX {
|
||||
try {
|
||||
startKeyTimer(progressTaskUpdater)
|
||||
mDatabase = DatabaseKDBX()
|
||||
mDatabase.binaryCache.cacheDirectory = cacheDirectory
|
||||
|
||||
mDatabase.changeDuplicateId = fixDuplicateUUID
|
||||
|
||||
val header = DatabaseHeaderKDBX(mDatabase)
|
||||
|
||||
@@ -704,7 +697,7 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
||||
KdbContext.DeletedObject -> if (name.equals(DatabaseKDBXXML.ElemUuid, ignoreCase = true)) {
|
||||
ctxDeletedObject?.uuid = readUuid(xpp)
|
||||
} else if (name.equals(DatabaseKDBXXML.ElemDeletionTime, ignoreCase = true)) {
|
||||
ctxDeletedObject?.setDeletionTime(readDateInstant(xpp))
|
||||
ctxDeletedObject?.deletionTime = readDateInstant(xpp)
|
||||
} else {
|
||||
readUnknown(xpp)
|
||||
}
|
||||
|
||||
@@ -592,7 +592,7 @@ class DatabaseOutputKDBX(private val mDatabaseKDBX: DatabaseKDBX,
|
||||
xml.startTag(null, DatabaseKDBXXML.ElemDeletedObject)
|
||||
|
||||
writeUuid(DatabaseKDBXXML.ElemUuid, value.uuid)
|
||||
writeDateInstant(DatabaseKDBXXML.ElemDeletionTime, value.getDeletionTime())
|
||||
writeDateInstant(DatabaseKDBXXML.ElemDeletionTime, value.deletionTime)
|
||||
|
||||
xml.endTag(null, DatabaseKDBXXML.ElemDeletedObject)
|
||||
}
|
||||
|
||||
@@ -52,17 +52,22 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
val deletedObjectId = deletedObject.uuid
|
||||
val databaseEntry = database.getEntryById(deletedObjectId)
|
||||
val databaseGroup = database.getGroupById(deletedObjectId)
|
||||
val databaseIconModificationTime = database.getCustomIcon(deletedObjectId).lastModificationTime
|
||||
if (databaseEntry != null
|
||||
&& deletedObject.getDeletionTime().date
|
||||
&& deletedObject.deletionTime.date
|
||||
.after(databaseEntry.lastModificationTime.date)) {
|
||||
database.removeEntryFrom(databaseEntry, databaseEntry.parent)
|
||||
}
|
||||
if (databaseGroup != null
|
||||
&& deletedObject.getDeletionTime().date
|
||||
&& deletedObject.deletionTime.date
|
||||
.after(databaseGroup.lastModificationTime.date)) {
|
||||
database.removeGroupFrom(databaseGroup, databaseGroup.parent)
|
||||
}
|
||||
// TODO Remove icon
|
||||
if (databaseIconModificationTime != null
|
||||
&& deletedObject.deletionTime.date
|
||||
.after(databaseIconModificationTime.date)) {
|
||||
database.removeCustomIcon(deletedObjectId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +88,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
// If it's a deleted object, but another instance was updated
|
||||
// If entry parent to add exists and in current database
|
||||
if (deletedObject == null
|
||||
|| deletedObject.getDeletionTime().date
|
||||
|| deletedObject.deletionTime.date
|
||||
.before(databaseEntryToMerge.lastModificationTime.date)
|
||||
|| parentEntry != null) {
|
||||
database.addEntryTo(databaseEntryToMerge, parentEntry)
|
||||
@@ -120,7 +125,7 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
|
||||
if (databaseGroup == null) {
|
||||
// If group parent to add exists and in current database
|
||||
if (deletedObject == null
|
||||
|| deletedObject.getDeletionTime().date
|
||||
|| deletedObject.deletionTime.date
|
||||
.before(databaseGroupToMerge.lastModificationTime.date)
|
||||
|| parentGroup != null) {
|
||||
database.addGroupTo(databaseGroupToMerge, parentGroup)
|
||||
|
||||
Reference in New Issue
Block a user