From e2c8f51dc7a94dd1f0efb588ab073f4128082e8b Mon Sep 17 00:00:00 2001 From: ever Date: Tue, 22 Aug 2023 19:48:41 +0200 Subject: [PATCH 1/4] Implemented group sync --- src/keeshare/ShareExport.cpp | 48 +++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/keeshare/ShareExport.cpp b/src/keeshare/ShareExport.cpp index 1a64ccde0..1dff43c85 100644 --- a/src/keeshare/ShareExport.cpp +++ b/src/keeshare/ShareExport.cpp @@ -62,6 +62,39 @@ namespace } } + void cloneIcon(Metadata* targetMetadata, const Database* sourceDb, const QUuid& iconUuid) + { + if (!iconUuid.isNull() && !targetMetadata->hasCustomIcon(iconUuid)) { + targetMetadata->addCustomIcon(iconUuid, sourceDb->metadata()->customIcon(iconUuid)); + } + } + + void cloneEntries(Metadata* targetMetadata, const Group* sourceGroup, Group* targetGroup) + { + for (const Entry* sourceEntry : sourceGroup->entries()) { + auto* targetEntry = sourceEntry->clone(Entry::CloneIncludeHistory); + const bool updateTimeinfoEntry = targetEntry->canUpdateTimeinfo(); + targetEntry->setUpdateTimeinfo(false); + targetEntry->setGroup(targetGroup); + targetEntry->setUpdateTimeinfo(updateTimeinfoEntry); + cloneIcon(targetMetadata, sourceEntry->database(), targetEntry->iconUuid()); + } + } + + void cloneChildren(Metadata* targetMetadata, const Group* sourceRoot, Group* targetRoot) + { + for (const Group* sourceGroup : sourceRoot->children()) { + auto* targetGroup = sourceGroup->clone(Entry::CloneNoFlags, Group::CloneNoFlags); + const bool updateTimeinfo = targetGroup->canUpdateTimeinfo(); + targetGroup->setUpdateTimeinfo(false); + targetGroup->setParent(targetRoot); + targetGroup->setUpdateTimeinfo(updateTimeinfo); + cloneIcon(targetMetadata, sourceRoot->database(), targetGroup->iconUuid()); + cloneEntries(targetMetadata, sourceGroup, targetGroup); + cloneChildren(targetMetadata, sourceGroup, targetGroup); + } + } + Database* extractIntoDatabase(const KeeShareSettings::Reference& reference, const Group* sourceRoot) { const auto* sourceDb = sourceRoot->database(); @@ -75,18 +108,9 @@ namespace targetRoot->setUpdateTimeinfo(false); KeeShare::setReferenceTo(targetRoot, KeeShareSettings::Reference()); targetRoot->setUpdateTimeinfo(updateTimeinfo); - const auto sourceEntries = sourceRoot->entriesRecursive(false); - for (const Entry* sourceEntry : sourceEntries) { - auto* targetEntry = sourceEntry->clone(Entry::CloneIncludeHistory); - const bool updateTimeinfoEntry = targetEntry->canUpdateTimeinfo(); - targetEntry->setUpdateTimeinfo(false); - targetEntry->setGroup(targetRoot); - targetEntry->setUpdateTimeinfo(updateTimeinfoEntry); - const auto iconUuid = targetEntry->iconUuid(); - if (!iconUuid.isNull() && !targetMetadata->hasCustomIcon(iconUuid)) { - targetMetadata->addCustomIcon(iconUuid, sourceEntry->database()->metadata()->customIcon(iconUuid)); - } - } + cloneIcon(targetMetadata, sourceRoot->database(), targetRoot->iconUuid()); + cloneEntries(targetMetadata, sourceRoot, targetRoot); + cloneChildren(targetMetadata, sourceRoot, targetRoot); auto key = QSharedPointer::create(); key->addKey(QSharedPointer::create(reference.password)); From 963f7b5b05a8aae84b38f0ed1d2cc53db78776a3 Mon Sep 17 00:00:00 2001 From: Ben Kluwe Date: Thu, 11 Apr 2024 08:37:48 +0200 Subject: [PATCH 2/4] ui: added checkbox and associated logic for recursing into groups --- src/keeshare/KeeShareSettings.h | 1 + src/keeshare/ShareExport.cpp | 4 +++- src/keeshare/group/EditGroupWidgetKeeShare.cpp | 12 ++++++++++++ src/keeshare/group/EditGroupWidgetKeeShare.h | 1 + src/keeshare/group/EditGroupWidgetKeeShare.ui | 11 +++++++++-- 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/keeshare/KeeShareSettings.h b/src/keeshare/KeeShareSettings.h index b81dc15af..c8ee73d67 100644 --- a/src/keeshare/KeeShareSettings.h +++ b/src/keeshare/KeeShareSettings.h @@ -126,6 +126,7 @@ namespace KeeShareSettings QUuid uuid; QString path; QString password; + bool recurse; Reference(); bool isNull() const; diff --git a/src/keeshare/ShareExport.cpp b/src/keeshare/ShareExport.cpp index 1dff43c85..15dfcd562 100644 --- a/src/keeshare/ShareExport.cpp +++ b/src/keeshare/ShareExport.cpp @@ -110,7 +110,9 @@ namespace targetRoot->setUpdateTimeinfo(updateTimeinfo); cloneIcon(targetMetadata, sourceRoot->database(), targetRoot->iconUuid()); cloneEntries(targetMetadata, sourceRoot, targetRoot); - cloneChildren(targetMetadata, sourceRoot, targetRoot); + if(reference.recurse) { + cloneChildren(targetMetadata, sourceRoot, targetRoot); + } auto key = QSharedPointer::create(); key->addKey(QSharedPointer::create(reference.password)); diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.cpp b/src/keeshare/group/EditGroupWidgetKeeShare.cpp index 82f8dd1c0..39da44e1f 100644 --- a/src/keeshare/group/EditGroupWidgetKeeShare.cpp +++ b/src/keeshare/group/EditGroupWidgetKeeShare.cpp @@ -43,6 +43,7 @@ EditGroupWidgetKeeShare::EditGroupWidgetKeeShare(QWidget* parent) connect(m_ui->pathEdit, SIGNAL(editingFinished()), SLOT(selectPath())); connect(m_ui->pathSelectionButton, SIGNAL(pressed()), SLOT(launchPathSelectionDialog())); connect(m_ui->typeComboBox, SIGNAL(currentIndexChanged(int)), SLOT(selectType())); + connect(m_ui->recurseIntoGroupsCheckbox, SIGNAL(toggled(bool)), SLOT(recurseIntoGroupsToggled(bool))); connect(m_ui->clearButton, SIGNAL(clicked(bool)), SLOT(clearInputs())); connect(KeeShare::instance(), SIGNAL(activeChanged()), SLOT(updateSharingState())); @@ -97,6 +98,7 @@ void EditGroupWidgetKeeShare::updateSharingState() m_ui->pathEdit->setEnabled(isEnabled); m_ui->pathSelectionButton->setEnabled(isEnabled); m_ui->passwordEdit->setEnabled(isEnabled); + m_ui->recurseIntoGroupsCheckbox->setEnabled(isEnabled); if (!m_temporaryGroup || !isEnabled) { m_ui->messageWidget->hideMessage(); @@ -291,3 +293,13 @@ void EditGroupWidgetKeeShare::selectType() updateSharingState(); } + +void EditGroupWidgetKeeShare::recurseIntoGroupsToggled(bool toggled) +{ + if (!m_temporaryGroup) { + return; + } + auto reference = KeeShare::referenceOf(m_temporaryGroup); + reference.recurse = toggled; + KeeShare::setReferenceTo(m_temporaryGroup, reference); +} diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.h b/src/keeshare/group/EditGroupWidgetKeeShare.h index aaa3ebbd3..3e403b1e3 100644 --- a/src/keeshare/group/EditGroupWidgetKeeShare.h +++ b/src/keeshare/group/EditGroupWidgetKeeShare.h @@ -48,6 +48,7 @@ private slots: void selectPassword(); void launchPathSelectionDialog(); void selectPath(); + void recurseIntoGroupsToggled(bool); private: QScopedPointer m_ui; diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.ui b/src/keeshare/group/EditGroupWidgetKeeShare.ui index 857ba61c8..921b1f002 100644 --- a/src/keeshare/group/EditGroupWidgetKeeShare.ui +++ b/src/keeshare/group/EditGroupWidgetKeeShare.ui @@ -138,7 +138,7 @@ - + @@ -171,7 +171,7 @@ - + Qt::Vertical @@ -184,6 +184,13 @@ + + + + Share recursively + + + From 910655d356befc3430bb9e488fb438ad78a9b268 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Mon, 23 Dec 2024 16:32:02 -0500 Subject: [PATCH 3/4] Translations and code format --- share/translations/keepassxc_en.ts | 4 ++++ src/keeshare/ShareExport.cpp | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 81895f9ea..4139414b6 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -3633,6 +3633,10 @@ Supported extensions are: %1. Select import/export file + + Share recursively + + EditGroupWidgetMain diff --git a/src/keeshare/ShareExport.cpp b/src/keeshare/ShareExport.cpp index 15dfcd562..3c5b618de 100644 --- a/src/keeshare/ShareExport.cpp +++ b/src/keeshare/ShareExport.cpp @@ -68,7 +68,7 @@ namespace targetMetadata->addCustomIcon(iconUuid, sourceDb->metadata()->customIcon(iconUuid)); } } - + void cloneEntries(Metadata* targetMetadata, const Group* sourceGroup, Group* targetGroup) { for (const Entry* sourceEntry : sourceGroup->entries()) { @@ -110,7 +110,7 @@ namespace targetRoot->setUpdateTimeinfo(updateTimeinfo); cloneIcon(targetMetadata, sourceRoot->database(), targetRoot->iconUuid()); cloneEntries(targetMetadata, sourceRoot, targetRoot); - if(reference.recurse) { + if (reference.recurse) { cloneChildren(targetMetadata, sourceRoot, targetRoot); } From 06f9ab6775e0a7251e344266f77dc75b8ca59286 Mon Sep 17 00:00:00 2001 From: Jonathan White Date: Fri, 27 Dec 2024 23:29:49 -0500 Subject: [PATCH 4/4] Complete code and test sat --- src/keeshare/KeeShareSettings.cpp | 5 +++++ src/keeshare/group/EditGroupWidgetKeeShare.cpp | 1 + 2 files changed, 6 insertions(+) diff --git a/src/keeshare/KeeShareSettings.cpp b/src/keeshare/KeeShareSettings.cpp index 4f53fc25f..268e4e9a0 100644 --- a/src/keeshare/KeeShareSettings.cpp +++ b/src/keeshare/KeeShareSettings.cpp @@ -320,6 +320,9 @@ namespace KeeShareSettings writer.writeStartElement("Password"); writer.writeCharacters(reference.password.toUtf8().toBase64()); writer.writeEndElement(); + writer.writeStartElement("Recurse"); + writer.writeCharacters(reference.recurse ? "True" : "False"); + writer.writeEndElement(); }); } @@ -346,6 +349,8 @@ namespace KeeShareSettings reference.path = QString::fromUtf8(QByteArray::fromBase64(reader.readElementText().toLatin1())); } else if (reader.name() == "Password") { reference.password = QString::fromUtf8(QByteArray::fromBase64(reader.readElementText().toLatin1())); + } else if (reader.name() == "Recurse") { + reference.recurse = reader.readElementText().compare("True") == 0; } else { qWarning("Unknown Reference element %s", qPrintable(reader.name().toString())); reader.skipCurrentElement(); diff --git a/src/keeshare/group/EditGroupWidgetKeeShare.cpp b/src/keeshare/group/EditGroupWidgetKeeShare.cpp index 39da44e1f..0efd061bc 100644 --- a/src/keeshare/group/EditGroupWidgetKeeShare.cpp +++ b/src/keeshare/group/EditGroupWidgetKeeShare.cpp @@ -190,6 +190,7 @@ void EditGroupWidgetKeeShare::update() m_ui->typeComboBox->setCurrentIndex(reference.type); m_ui->passwordEdit->setText(reference.password); m_ui->pathEdit->setText(reference.path); + m_ui->recurseIntoGroupsCheckbox->setChecked(reference.recurse); } updateSharingState();