mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2024-10-01 01:26:01 -04:00
Minor changes to Group API to make it more explicit
* Include check for group as recycle bin directly into the Group::isRecycled() function * Return the original root group from Database::setRootGroup(...) to force memory management transfer
This commit is contained in:
parent
b4ff1fa36c
commit
a02bceabd2
@ -66,9 +66,9 @@ Database::Database()
|
|||||||
// block modified signal and set root group
|
// block modified signal and set root group
|
||||||
setEmitModified(false);
|
setEmitModified(false);
|
||||||
|
|
||||||
setRootGroup(new Group());
|
// Note: oldGroup is nullptr but need to respect return value capture
|
||||||
rootGroup()->setUuid(QUuid::createUuid());
|
auto oldGroup = setRootGroup(new Group());
|
||||||
rootGroup()->setName(tr("Passwords", "Root group name"));
|
Q_UNUSED(oldGroup)
|
||||||
|
|
||||||
m_modified = false;
|
m_modified = false;
|
||||||
setEmitModified(true);
|
setEmitModified(true);
|
||||||
@ -481,9 +481,8 @@ void Database::releaseData()
|
|||||||
m_data.clear();
|
m_data.clear();
|
||||||
m_metadata->clear();
|
m_metadata->clear();
|
||||||
|
|
||||||
auto oldGroup = rootGroup();
|
// Reset and delete the root group
|
||||||
setRootGroup(new Group());
|
auto oldGroup = setRootGroup(new Group());
|
||||||
// explicitly delete old group, otherwise it is only deleted when the database object is destructed
|
|
||||||
delete oldGroup;
|
delete oldGroup;
|
||||||
|
|
||||||
m_fileWatcher->stop();
|
m_fileWatcher->stop();
|
||||||
@ -559,14 +558,12 @@ const Group* Database::rootGroup() const
|
|||||||
return m_rootGroup;
|
return m_rootGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/* Set the root group of the database and return
|
||||||
* Sets group as the root group and takes ownership of it.
|
* the old root group. It is the responsibility
|
||||||
* Warning: Be careful when calling this method as it doesn't
|
* of the calling function to dispose of the old
|
||||||
* emit any notifications so e.g. models aren't updated.
|
* root group.
|
||||||
* The caller is responsible for cleaning up the previous
|
|
||||||
root group.
|
|
||||||
*/
|
*/
|
||||||
void Database::setRootGroup(Group* group)
|
Group* Database::setRootGroup(Group* group)
|
||||||
{
|
{
|
||||||
Q_ASSERT(group);
|
Q_ASSERT(group);
|
||||||
|
|
||||||
@ -574,8 +571,17 @@ void Database::setRootGroup(Group* group)
|
|||||||
emit databaseDiscarded();
|
emit databaseDiscarded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto oldRoot = m_rootGroup;
|
||||||
m_rootGroup = group;
|
m_rootGroup = group;
|
||||||
m_rootGroup->setParent(this);
|
m_rootGroup->setParent(this);
|
||||||
|
|
||||||
|
// Initialize the root group if not done already
|
||||||
|
if (m_rootGroup->uuid().isNull()) {
|
||||||
|
m_rootGroup->setUuid(QUuid::createUuid());
|
||||||
|
m_rootGroup->setName(tr("Passwords", "Root group name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
Metadata* Database::metadata()
|
Metadata* Database::metadata()
|
||||||
|
@ -112,7 +112,7 @@ public:
|
|||||||
const Metadata* metadata() const;
|
const Metadata* metadata() const;
|
||||||
Group* rootGroup();
|
Group* rootGroup();
|
||||||
const Group* rootGroup() const;
|
const Group* rootGroup() const;
|
||||||
void setRootGroup(Group* group);
|
Q_REQUIRED_RESULT Group* setRootGroup(Group* group);
|
||||||
QVariantMap& publicCustomData();
|
QVariantMap& publicCustomData();
|
||||||
const QVariantMap& publicCustomData() const;
|
const QVariantMap& publicCustomData() const;
|
||||||
void setPublicCustomData(const QVariantMap& customData);
|
void setPublicCustomData(const QVariantMap& customData);
|
||||||
|
@ -463,7 +463,7 @@ bool Entry::isRecycled() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_group == db->metadata()->recycleBin() || m_group->isRecycled();
|
return m_group->isRecycled();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entry::isAttributeReference(const QString& key) const
|
bool Entry::isAttributeReference(const QString& key) const
|
||||||
|
@ -223,18 +223,16 @@ Entry* Group::lastTopVisibleEntry() const
|
|||||||
bool Group::isRecycled() const
|
bool Group::isRecycled() const
|
||||||
{
|
{
|
||||||
auto group = this;
|
auto group = this;
|
||||||
if (!group->database()) {
|
if (!group->database() || !group->m_db->metadata()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (group->m_parent && group->m_db->metadata()) {
|
if (group == group->m_db->metadata()->recycleBin()) {
|
||||||
if (group->m_parent == group->m_db->metadata()->recycleBin()) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
group = group->m_parent;
|
group = group->m_parent;
|
||||||
} while (group && group->m_parent && group->m_parent != group->m_db->rootGroup());
|
} while (group);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -228,9 +228,7 @@ private:
|
|||||||
|
|
||||||
bool m_updateTimeinfo;
|
bool m_updateTimeinfo;
|
||||||
|
|
||||||
friend void Database::setRootGroup(Group* group);
|
friend Group* Database::setRootGroup(Group* group);
|
||||||
friend Entry::~Entry();
|
|
||||||
friend void Entry::setGroup(Group* group, bool trackPrevious);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(Group::CloneFlags)
|
Q_DECLARE_OPERATORS_FOR_FLAGS(Group::CloneFlags)
|
||||||
|
@ -408,7 +408,7 @@ namespace FdoSecrets
|
|||||||
|
|
||||||
auto newUuid = FdoSecrets::settings()->exposedGroup(m_backend->database());
|
auto newUuid = FdoSecrets::settings()->exposedGroup(m_backend->database());
|
||||||
auto newGroup = m_backend->database()->rootGroup()->findGroupByUuid(newUuid);
|
auto newGroup = m_backend->database()->rootGroup()->findGroupByUuid(newUuid);
|
||||||
if (!newGroup || inRecycleBin(newGroup)) {
|
if (!newGroup || newGroup->isRecycled()) {
|
||||||
// no exposed group, delete self
|
// no exposed group, delete self
|
||||||
removeFromDBus();
|
removeFromDBus();
|
||||||
return;
|
return;
|
||||||
@ -444,7 +444,7 @@ namespace FdoSecrets
|
|||||||
});
|
});
|
||||||
// Another possibility is the group being moved to recycle bin.
|
// Another possibility is the group being moved to recycle bin.
|
||||||
connect(m_exposedGroup.data(), &Group::modified, this, [this]() {
|
connect(m_exposedGroup.data(), &Group::modified, this, [this]() {
|
||||||
if (inRecycleBin(m_exposedGroup)) {
|
if (m_exposedGroup->isRecycled()) {
|
||||||
// reset the exposed group to none
|
// reset the exposed group to none
|
||||||
FdoSecrets::settings()->setExposedGroup(m_backend->database().data(), {});
|
FdoSecrets::settings()->setExposedGroup(m_backend->database().data(), {});
|
||||||
}
|
}
|
||||||
@ -490,7 +490,7 @@ namespace FdoSecrets
|
|||||||
|
|
||||||
void Collection::onEntryAdded(Entry* entry, bool emitSignal)
|
void Collection::onEntryAdded(Entry* entry, bool emitSignal)
|
||||||
{
|
{
|
||||||
if (inRecycleBin(entry)) {
|
if (entry->isRecycled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,7 +524,7 @@ namespace FdoSecrets
|
|||||||
|
|
||||||
void Collection::connectGroupSignalRecursive(Group* group)
|
void Collection::connectGroupSignalRecursive(Group* group)
|
||||||
{
|
{
|
||||||
if (inRecycleBin(group)) {
|
if (group->isRecycled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,7 +627,7 @@ namespace FdoSecrets
|
|||||||
bool Collection::doDeleteEntry(Entry* entry)
|
bool Collection::doDeleteEntry(Entry* entry)
|
||||||
{
|
{
|
||||||
// Confirm entry removal before moving forward
|
// Confirm entry removal before moving forward
|
||||||
bool permanent = inRecycleBin(entry) || !m_backend->database()->metadata()->recycleBinEnabled();
|
bool permanent = entry->isRecycled() || !m_backend->database()->metadata()->recycleBinEnabled();
|
||||||
if (FdoSecrets::settings()->confirmDeleteItem()
|
if (FdoSecrets::settings()->confirmDeleteItem()
|
||||||
&& !GuiTools::confirmDeleteEntries(m_backend, {entry}, permanent)) {
|
&& !GuiTools::confirmDeleteEntries(m_backend, {entry}, permanent)) {
|
||||||
return false;
|
return false;
|
||||||
@ -664,29 +664,6 @@ namespace FdoSecrets
|
|||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Collection::inRecycleBin(Group* group) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(m_backend);
|
|
||||||
Q_ASSERT(group);
|
|
||||||
|
|
||||||
if (!m_backend->database()->metadata()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto recycleBin = m_backend->database()->metadata()->recycleBin();
|
|
||||||
if (!recycleBin) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return group->uuid() == recycleBin->uuid() || group->isRecycled();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Collection::inRecycleBin(Entry* entry) const
|
|
||||||
{
|
|
||||||
Q_ASSERT(entry);
|
|
||||||
return inRecycleBin(entry->group());
|
|
||||||
}
|
|
||||||
|
|
||||||
Item* Collection::doNewItem(const DBusClientPtr& client, QString itemPath)
|
Item* Collection::doNewItem(const DBusClientPtr& client, QString itemPath)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_backend);
|
Q_ASSERT(m_backend);
|
||||||
|
@ -107,11 +107,6 @@ namespace FdoSecrets
|
|||||||
DatabaseWidget* backend() const;
|
DatabaseWidget* backend() const;
|
||||||
QString backendFilePath() const;
|
QString backendFilePath() const;
|
||||||
Service* service() const;
|
Service* service() const;
|
||||||
/**
|
|
||||||
* similar to Group::isRecycled, but we also return true when the group itself is the recycle bin
|
|
||||||
*/
|
|
||||||
bool inRecycleBin(Group* group) const;
|
|
||||||
bool inRecycleBin(Entry* entry) const;
|
|
||||||
|
|
||||||
static EntrySearcher::SearchTerm attributeToTerm(const QString& key, const QString& value);
|
static EntrySearcher::SearchTerm attributeToTerm(const QString& key, const QString& value);
|
||||||
|
|
||||||
|
@ -463,8 +463,7 @@ bool KdbxXmlReader::parseRoot()
|
|||||||
|
|
||||||
Group* rootGroup = parseGroup();
|
Group* rootGroup = parseGroup();
|
||||||
if (rootGroup) {
|
if (rootGroup) {
|
||||||
Group* oldRoot = m_db->rootGroup();
|
auto oldRoot = m_db->setRootGroup(rootGroup);
|
||||||
m_db->setRootGroup(rootGroup);
|
|
||||||
delete oldRoot;
|
delete oldRoot;
|
||||||
groupParsedSuccessfully = true;
|
groupParsedSuccessfully = true;
|
||||||
}
|
}
|
||||||
|
@ -92,8 +92,7 @@ namespace
|
|||||||
key->addKey(QSharedPointer<PasswordKey>::create(reference.password));
|
key->addKey(QSharedPointer<PasswordKey>::create(reference.password));
|
||||||
targetDb->setKey(key);
|
targetDb->setKey(key);
|
||||||
|
|
||||||
auto* obsoleteRoot = targetDb->rootGroup();
|
auto obsoleteRoot = targetDb->setRootGroup(targetRoot);
|
||||||
targetDb->setRootGroup(targetRoot);
|
|
||||||
delete obsoleteRoot;
|
delete obsoleteRoot;
|
||||||
|
|
||||||
targetDb->metadata()->setName(sourceRoot->name());
|
targetDb->metadata()->setName(sourceRoot->name());
|
||||||
|
@ -54,6 +54,7 @@ ShareObserver::ShareObserver(QSharedPointer<Database> db, QObject* parent)
|
|||||||
|
|
||||||
ShareObserver::~ShareObserver()
|
ShareObserver::~ShareObserver()
|
||||||
{
|
{
|
||||||
|
m_db->disconnect(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShareObserver::deinitialize()
|
void ShareObserver::deinitialize()
|
||||||
|
@ -62,8 +62,7 @@ void TestAutoType::init()
|
|||||||
m_db = QSharedPointer<Database>::create();
|
m_db = QSharedPointer<Database>::create();
|
||||||
m_dbList.clear();
|
m_dbList.clear();
|
||||||
m_dbList.append(m_db);
|
m_dbList.append(m_db);
|
||||||
m_group = new Group();
|
m_group = m_db->rootGroup();
|
||||||
m_db->setRootGroup(m_group);
|
|
||||||
|
|
||||||
AutoTypeAssociations::Association association;
|
AutoTypeAssociations::Association association;
|
||||||
|
|
||||||
|
@ -1799,7 +1799,8 @@ void TestCli::testMergeWithKeys()
|
|||||||
entry->setPassword("secretsecretsecret");
|
entry->setPassword("secretsecretsecret");
|
||||||
group->addEntry(entry);
|
group->addEntry(entry);
|
||||||
|
|
||||||
sourceDatabase->setRootGroup(rootGroup);
|
auto oldGroup = sourceDatabase->setRootGroup(rootGroup);
|
||||||
|
delete oldGroup;
|
||||||
|
|
||||||
auto* otherRootGroup = new Group();
|
auto* otherRootGroup = new Group();
|
||||||
otherRootGroup->setName("root");
|
otherRootGroup->setName("root");
|
||||||
@ -1815,7 +1816,8 @@ void TestCli::testMergeWithKeys()
|
|||||||
otherEntry->setPassword("secretsecretsecret 2");
|
otherEntry->setPassword("secretsecretsecret 2");
|
||||||
otherGroup->addEntry(otherEntry);
|
otherGroup->addEntry(otherEntry);
|
||||||
|
|
||||||
targetDatabase->setRootGroup(otherRootGroup);
|
oldGroup = targetDatabase->setRootGroup(otherRootGroup);
|
||||||
|
delete oldGroup;
|
||||||
|
|
||||||
sourceDatabase->saveAs(sourceDatabaseFilename);
|
sourceDatabase->saveAs(sourceDatabaseFilename);
|
||||||
targetDatabase->saveAs(targetDatabaseFilename);
|
targetDatabase->saveAs(targetDatabaseFilename);
|
||||||
|
@ -576,7 +576,9 @@ void TestKeePass2Format::testKdbxKeyChange()
|
|||||||
buffer.seek(0);
|
buffer.seek(0);
|
||||||
QSharedPointer<Database> db(new Database());
|
QSharedPointer<Database> db(new Database());
|
||||||
db->changeKdf(fastKdf(KeePass2::uuidToKdf(m_kdbxSourceDb->kdf()->uuid())));
|
db->changeKdf(fastKdf(KeePass2::uuidToKdf(m_kdbxSourceDb->kdf()->uuid())));
|
||||||
|
auto oldGroup =
|
||||||
db->setRootGroup(m_kdbxSourceDb->rootGroup()->clone(Entry::CloneNoFlags, Group::CloneIncludeEntries));
|
db->setRootGroup(m_kdbxSourceDb->rootGroup()->clone(Entry::CloneNoFlags, Group::CloneIncludeEntries));
|
||||||
|
delete oldGroup;
|
||||||
|
|
||||||
db->setKey(key1);
|
db->setKey(key1);
|
||||||
writeKdbx(&buffer, db.data(), hasError, errorString);
|
writeKdbx(&buffer, db.data(), hasError, errorString);
|
||||||
|
@ -1456,8 +1456,8 @@ Database* TestMerge::createTestDatabase()
|
|||||||
Database* TestMerge::createTestDatabaseStructureClone(Database* source, int entryFlags, int groupFlags)
|
Database* TestMerge::createTestDatabaseStructureClone(Database* source, int entryFlags, int groupFlags)
|
||||||
{
|
{
|
||||||
auto db = new Database();
|
auto db = new Database();
|
||||||
// the old root group is deleted by QObject::parent relationship
|
auto oldGroup = db->setRootGroup(source->rootGroup()->clone(static_cast<Entry::CloneFlag>(entryFlags),
|
||||||
db->setRootGroup(source->rootGroup()->clone(static_cast<Entry::CloneFlag>(entryFlags),
|
|
||||||
static_cast<Group::CloneFlag>(groupFlags)));
|
static_cast<Group::CloneFlag>(groupFlags)));
|
||||||
|
delete oldGroup;
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user