Merge database metadata

This commit is contained in:
J-Jamet
2022-01-15 21:03:40 +01:00
parent c26995779a
commit f9445de71f
4 changed files with 66 additions and 48 deletions

View File

@@ -43,7 +43,7 @@ open class AssignPasswordInDatabaseRunnable (
System.arraycopy(database.masterKey, 0, mBackupKey!!, 0, mBackupKey!!.size) System.arraycopy(database.masterKey, 0, mBackupKey!!, 0, mBackupKey!!.size)
val uriInputStream = UriUtil.getUriInputStream(context.contentResolver, mMainCredential.keyFileUri) val uriInputStream = UriUtil.getUriInputStream(context.contentResolver, mMainCredential.keyFileUri)
database.retrieveMasterKey(mMainCredential.masterPassword, uriInputStream) database.assignMasterKey(mMainCredential.masterPassword, uriInputStream)
} catch (e: Exception) { } catch (e: Exception) {
erase(mBackupKey) erase(mBackupKey)
setError(e) setError(e)

View File

@@ -916,9 +916,10 @@ class Database {
} }
@Throws(IOException::class) @Throws(IOException::class)
fun retrieveMasterKey(key: String?, keyInputStream: InputStream?) { fun assignMasterKey(key: String?, keyInputStream: InputStream?) {
mDatabaseKDB?.retrieveMasterKey(key, keyInputStream) mDatabaseKDB?.retrieveMasterKey(key, keyInputStream)
mDatabaseKDBX?.retrieveMasterKey(key, keyInputStream) mDatabaseKDBX?.retrieveMasterKey(key, keyInputStream)
mDatabaseKDBX?.keyLastChanged = DateInstant()
} }
fun rootCanContainsEntry(): Boolean { fun rootCanContainsEntry(): Boolean {

View File

@@ -88,14 +88,13 @@ class DatabaseKDBX : DatabaseVersioned<UUID, UUID, GroupKDBX, EntryKDBX> {
var kdbxVersion = UnsignedInt(0) var kdbxVersion = UnsignedInt(0)
var name = "" var name = ""
var nameChanged = DateInstant() var nameChanged = DateInstant()
// TODO change setting date
var settingsChanged = DateInstant()
var description = "" var description = ""
var descriptionChanged = DateInstant() var descriptionChanged = DateInstant()
var defaultUserName = "" var defaultUserName = ""
var defaultUserNameChanged = DateInstant() var defaultUserNameChanged = DateInstant()
// TODO change setting date
var settingsChanged = DateInstant()
// TODO last change date
var keyLastChanged = DateInstant() var keyLastChanged = DateInstant()
var keyChangeRecDays: Long = -1 var keyChangeRecDays: Long = -1
var keyChangeForceDays: Long = 1 var keyChangeForceDays: Long = 1

View File

@@ -2,7 +2,6 @@ package com.kunzisoft.keepass.database.merge
import com.kunzisoft.keepass.database.action.node.NodeHandler import com.kunzisoft.keepass.database.action.node.NodeHandler
import com.kunzisoft.keepass.database.element.Attachment import com.kunzisoft.keepass.database.element.Attachment
import com.kunzisoft.keepass.database.element.DateInstant
import com.kunzisoft.keepass.database.element.database.DatabaseKDBX import com.kunzisoft.keepass.database.element.database.DatabaseKDBX
import com.kunzisoft.keepass.database.element.entry.EntryKDBX import com.kunzisoft.keepass.database.element.entry.EntryKDBX
import com.kunzisoft.keepass.database.element.group.GroupKDBX import com.kunzisoft.keepass.database.element.group.GroupKDBX
@@ -15,12 +14,28 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
fun merge(databaseToMerge: DatabaseKDBX) { fun merge(databaseToMerge: DatabaseKDBX) {
// TODO database data if (database.nameChanged.date.before(databaseToMerge.nameChanged.date)) {
var nameChanged = DateInstant() database.name = databaseToMerge.name
var settingsChanged = DateInstant() database.nameChanged = databaseToMerge.nameChanged
var descriptionChanged = DateInstant() }
var defaultUserNameChanged = DateInstant() if (database.descriptionChanged.date.before(databaseToMerge.descriptionChanged.date)) {
var keyLastChanged = DateInstant() database.description = databaseToMerge.description
database.descriptionChanged = databaseToMerge.descriptionChanged
}
if (database.defaultUserNameChanged.date.before(databaseToMerge.defaultUserNameChanged.date)) {
database.defaultUserName = databaseToMerge.defaultUserName
database.defaultUserNameChanged = databaseToMerge.defaultUserNameChanged
}
if (database.keyLastChanged.date.before(databaseToMerge.keyLastChanged.date)) {
database.keyChangeRecDays = databaseToMerge.keyChangeRecDays
database.keyChangeForceDays = databaseToMerge.keyChangeForceDays
database.isKeyChangeForceOnce = databaseToMerge.isKeyChangeForceOnce
database.keyLastChanged = databaseToMerge.keyLastChanged
}
if (database.settingsChanged.date.before(databaseToMerge.settingsChanged.date)) {
// TODO settings
database.settingsChanged = databaseToMerge.settingsChanged
}
val databaseRootGroupId = database.rootGroup?.nodeId val databaseRootGroupId = database.rootGroup?.nodeId
val databaseRootGroupIdToMerge = databaseToMerge.rootGroup?.nodeId val databaseRootGroupIdToMerge = databaseToMerge.rootGroup?.nodeId
@@ -40,7 +55,6 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
} }
} }
// TODO fix concurrent modification exception
databaseToMerge.rootGroup?.doForEachChild( databaseToMerge.rootGroup?.doForEachChild(
object : NodeHandler<EntryKDBX>() { object : NodeHandler<EntryKDBX>() {
override fun operate(node: EntryKDBX): Boolean { override fun operate(node: EntryKDBX): Boolean {
@@ -80,21 +94,21 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
} }
} }
private fun mergeEntry(entryToMerge: EntryKDBX, databaseToMerge: DatabaseKDBX) { private fun mergeEntry(nodeToMerge: EntryKDBX, databaseToMerge: DatabaseKDBX) {
val entryId = entryToMerge.nodeId val entryId = nodeToMerge.nodeId
val databaseEntryToMerge = databaseToMerge.getEntryById(entryId) val entryToMerge = databaseToMerge.getEntryById(entryId)
val databaseEntry = database.getEntryById(entryId) val entry = database.getEntryById(entryId)
val deletedObject = database.getDeletedObject(entryId) val deletedObject = database.getDeletedObject(entryId)
if (databaseEntryToMerge != null) { if (entryToMerge != null) {
// Retrieve parent in current database // Retrieve parent in current database
var parentEntryToMerge: GroupKDBX? = null var parentEntryToMerge: GroupKDBX? = null
databaseEntryToMerge.parent?.nodeId?.let { entryToMerge.parent?.nodeId?.let {
parentEntryToMerge = database.getGroupById(it) parentEntryToMerge = database.getGroupById(it)
} }
// Copy attachments in main pool // Copy attachments in main pool
val newAttachments = mutableListOf<Attachment>() val newAttachments = mutableListOf<Attachment>()
databaseEntryToMerge.getAttachments(databaseToMerge.attachmentPool).forEach { attachment -> entryToMerge.getAttachments(databaseToMerge.attachmentPool).forEach { attachment ->
val binarySize = attachment.binaryData.getSize() val binarySize = attachment.binaryData.getSize()
val binaryData = database.buildNewBinaryAttachment( val binaryData = database.buildNewBinaryAttachment(
isRAMSufficient.invoke(binarySize), isRAMSufficient.invoke(binarySize),
@@ -110,64 +124,68 @@ class DatabaseKDBXMerger(private var database: DatabaseKDBX) {
} }
newAttachments.add(Attachment(attachment.name, binaryData)) newAttachments.add(Attachment(attachment.name, binaryData))
} }
databaseEntryToMerge.removeAttachments() entryToMerge.removeAttachments()
newAttachments.forEach { newAttachment -> newAttachments.forEach { newAttachment ->
databaseEntryToMerge.putAttachment(newAttachment, database.attachmentPool) entryToMerge.putAttachment(newAttachment, database.attachmentPool)
} }
if (databaseEntry == null) { if (entry == null) {
// If it's a deleted object, but another instance was updated // If it's a deleted object, but another instance was updated
// If entry parent to add exists and in current database // If entry parent to add exists and in current database
if (deletedObject == null if (deletedObject == null
|| deletedObject.deletionTime.date || deletedObject.deletionTime.date
.before(databaseEntryToMerge.lastModificationTime.date) .before(entryToMerge.lastModificationTime.date)
|| parentEntryToMerge != null) { || parentEntryToMerge != null) {
database.addEntryTo(databaseEntryToMerge, parentEntryToMerge) database.addEntryTo(entryToMerge, parentEntryToMerge)
} }
} else if (databaseEntry.lastModificationTime.date } else if (entry.lastModificationTime.date
.before(databaseEntryToMerge.lastModificationTime.date) .before(entryToMerge.lastModificationTime.date)
) { ) {
if (parentEntryToMerge == databaseEntry.parent) { if (parentEntryToMerge == entry.parent) {
databaseEntry.updateWith(databaseEntryToMerge) entry.updateWith(entryToMerge)
} else { } else {
// Update entry with databaseEntryToMerge and merge history // Update entry with databaseEntryToMerge and merge history
database.removeEntryFrom(databaseEntry, databaseEntry.parent) database.removeEntryFrom(entry, entry.parent)
// TODO history = // TODO history =
if (parentEntryToMerge != null) { if (parentEntryToMerge != null) {
database.addEntryTo(databaseEntryToMerge, parentEntryToMerge) database.addEntryTo(entryToMerge, parentEntryToMerge)
} }
} }
} }
} }
} }
private fun mergeGroup(node: GroupKDBX, databaseToMerge: DatabaseKDBX) { private fun mergeGroup(nodeToMerge: GroupKDBX, databaseToMerge: DatabaseKDBX) {
val groupId = node.nodeId val groupId = nodeToMerge.nodeId
val databaseGroupToMerge = databaseToMerge.getGroupById(groupId) val groupToMerge = databaseToMerge.getGroupById(groupId)
val databaseGroup = database.getGroupById(groupId) val group = database.getGroupById(groupId)
val deletedObject = database.getDeletedObject(groupId) val deletedObject = database.getDeletedObject(groupId)
if (databaseGroupToMerge != null) { if (groupToMerge != null) {
// Retrieve parent in current database // Retrieve parent in current database
var parentGroup: GroupKDBX? = null var parentGroupToMerge: GroupKDBX? = null
databaseGroupToMerge.parent?.nodeId?.let { groupToMerge.parent?.nodeId?.let {
parentGroup = database.getGroupById(it) parentGroupToMerge = database.getGroupById(it)
} }
if (databaseGroup == null) { if (group == null) {
// If group parent to add exists and in current database // If group parent to add exists and in current database
if (deletedObject == null if (deletedObject == null
|| deletedObject.deletionTime.date || deletedObject.deletionTime.date
.before(databaseGroupToMerge.lastModificationTime.date) .before(groupToMerge.lastModificationTime.date)
|| parentGroup != null) { || parentGroupToMerge != null) {
database.addGroupTo(databaseGroupToMerge, parentGroup) database.addGroupTo(groupToMerge, parentGroupToMerge)
} }
} else if (databaseGroup.lastModificationTime.date } else if (group.lastModificationTime.date
.before(databaseGroupToMerge.lastModificationTime.date) .before(groupToMerge.lastModificationTime.date)
) { ) {
database.removeGroupFrom(databaseGroup, databaseGroup.parent) if (parentGroupToMerge == group.parent) {
if (parentGroup != null) { group.updateWith(groupToMerge)
database.addGroupTo(databaseGroupToMerge, parentGroup) } else {
database.removeGroupFrom(group, group.parent)
if (parentGroupToMerge != null) {
database.addGroupTo(groupToMerge, parentGroupToMerge)
}
} }
} }
} }