mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Merge database metadata
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user