mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-02-25 17:01:17 -05:00
Merge remote-tracking branch 'origin/develop' into release/2.2.0
This commit is contained in:
commit
9a7e6850d6
@ -55,8 +55,7 @@ int Clip::execute(int argc, char** argv)
|
|||||||
const QStringList args = parser.positionalArguments();
|
const QStringList args = parser.positionalArguments();
|
||||||
if (args.size() != 2) {
|
if (args.size() != 2) {
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
parser.showHelp();
|
parser.showHelp(EXIT_FAILURE);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Database* db = nullptr;
|
Database* db = nullptr;
|
||||||
|
@ -44,8 +44,7 @@ int Extract::execute(int argc, char** argv)
|
|||||||
|
|
||||||
const QStringList args = parser.positionalArguments();
|
const QStringList args = parser.positionalArguments();
|
||||||
if (args.size() != 1) {
|
if (args.size() != 1) {
|
||||||
parser.showHelp();
|
parser.showHelp(EXIT_FAILURE);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "Insert the database password\n> ";
|
out << "Insert the database password\n> ";
|
||||||
|
@ -44,6 +44,9 @@ int List::execute(int argc, char** argv)
|
|||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
parser.setApplicationDescription(QCoreApplication::translate("main", "List database entries."));
|
parser.setApplicationDescription(QCoreApplication::translate("main", "List database entries."));
|
||||||
parser.addPositionalArgument("database", QCoreApplication::translate("main", "Path of the database."));
|
parser.addPositionalArgument("database", QCoreApplication::translate("main", "Path of the database."));
|
||||||
|
parser.addPositionalArgument("group",
|
||||||
|
QCoreApplication::translate("main", "Path of the group to list. Default is /"),
|
||||||
|
QString("[group]"));
|
||||||
QCommandLineOption printUuidsOption(
|
QCommandLineOption printUuidsOption(
|
||||||
QStringList() << "u"
|
QStringList() << "u"
|
||||||
<< "print-uuids",
|
<< "print-uuids",
|
||||||
@ -57,10 +60,9 @@ int List::execute(int argc, char** argv)
|
|||||||
parser.process(arguments);
|
parser.process(arguments);
|
||||||
|
|
||||||
const QStringList args = parser.positionalArguments();
|
const QStringList args = parser.positionalArguments();
|
||||||
if (args.size() != 1) {
|
if (args.size() != 1 && args.size() != 2) {
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
parser.showHelp();
|
parser.showHelp(EXIT_FAILURE);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Database* db = nullptr;
|
Database* db = nullptr;
|
||||||
@ -76,7 +78,17 @@ int List::execute(int argc, char** argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
out << db->rootGroup()->print(parser.isSet("print-uuids"));
|
Group* group = db->rootGroup();
|
||||||
|
if (args.size() == 2) {
|
||||||
|
QString groupPath = args.at(1);
|
||||||
|
group = db->rootGroup()->findGroupByPath(groupPath);
|
||||||
|
if (group == nullptr) {
|
||||||
|
qCritical("Cannot find group %s.", qPrintable(groupPath));
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out << group->print(parser.isSet("print-uuids"));
|
||||||
out.flush();
|
out.flush();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -61,8 +61,7 @@ int Merge::execute(int argc, char** argv)
|
|||||||
const QStringList args = parser.positionalArguments();
|
const QStringList args = parser.positionalArguments();
|
||||||
if (args.size() != 2) {
|
if (args.size() != 2) {
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
parser.showHelp();
|
parser.showHelp(EXIT_FAILURE);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Database* db1;
|
Database* db1;
|
||||||
|
@ -63,10 +63,15 @@ void PasswordInput::setStdinEcho(bool enable = true)
|
|||||||
QString PasswordInput::getPassword()
|
QString PasswordInput::getPassword()
|
||||||
{
|
{
|
||||||
static QTextStream inputTextStream(stdin, QIODevice::ReadOnly);
|
static QTextStream inputTextStream(stdin, QIODevice::ReadOnly);
|
||||||
|
static QTextStream outputTextStream(stdout, QIODevice::WriteOnly);
|
||||||
|
|
||||||
setStdinEcho(false);
|
setStdinEcho(false);
|
||||||
QString line = inputTextStream.readLine();
|
QString line = inputTextStream.readLine();
|
||||||
setStdinEcho(true);
|
setStdinEcho(true);
|
||||||
|
|
||||||
|
// The new line was also not echoed, but we do want to echo it.
|
||||||
|
outputTextStream << "\n";
|
||||||
|
outputTextStream.flush();
|
||||||
|
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
@ -44,8 +44,7 @@ int Show::execute(int argc, char** argv)
|
|||||||
|
|
||||||
const QStringList args = parser.positionalArguments();
|
const QStringList args = parser.positionalArguments();
|
||||||
if (args.size() != 2) {
|
if (args.size() != 2) {
|
||||||
parser.showHelp();
|
parser.showHelp(EXIT_FAILURE);
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "Insert the database password\n> ";
|
out << "Insert the database password\n> ";
|
||||||
|
@ -486,7 +486,6 @@ QList<Entry*> Group::entriesRecursive(bool includeHistoryItems) const
|
|||||||
|
|
||||||
Entry* Group::findEntry(QString entryId)
|
Entry* Group::findEntry(QString entryId)
|
||||||
{
|
{
|
||||||
Q_ASSERT(!entryId.isEmpty());
|
|
||||||
Q_ASSERT(!entryId.isNull());
|
Q_ASSERT(!entryId.isNull());
|
||||||
|
|
||||||
if (Uuid::isUuid(entryId)) {
|
if (Uuid::isUuid(entryId)) {
|
||||||
@ -527,12 +526,11 @@ Entry* Group::findEntryByUuid(const Uuid& uuid)
|
|||||||
Entry* Group::findEntryByPath(QString entryPath, QString basePath)
|
Entry* Group::findEntryByPath(QString entryPath, QString basePath)
|
||||||
{
|
{
|
||||||
|
|
||||||
Q_ASSERT(!entryPath.isEmpty());
|
|
||||||
Q_ASSERT(!entryPath.isNull());
|
Q_ASSERT(!entryPath.isNull());
|
||||||
|
|
||||||
for (Entry* entry : asConst(m_entries)) {
|
for (Entry* entry : asConst(m_entries)) {
|
||||||
QString currentEntryPath = basePath + entry->title();
|
QString currentEntryPath = basePath + entry->title();
|
||||||
if (entryPath == currentEntryPath) {
|
if (entryPath == currentEntryPath || entryPath == QString("/" + currentEntryPath)) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,6 +545,39 @@ Entry* Group::findEntryByPath(QString entryPath, QString basePath)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Group* Group::findGroupByPath(QString groupPath, QString basePath)
|
||||||
|
{
|
||||||
|
|
||||||
|
Q_ASSERT(!groupPath.isNull());
|
||||||
|
|
||||||
|
QStringList possiblePaths;
|
||||||
|
possiblePaths << groupPath;
|
||||||
|
if (!groupPath.startsWith("/")) {
|
||||||
|
possiblePaths << QString("/" + groupPath);
|
||||||
|
}
|
||||||
|
if (!groupPath.endsWith("/")) {
|
||||||
|
possiblePaths << QString(groupPath + "/");
|
||||||
|
}
|
||||||
|
if (!groupPath.endsWith("/") && !groupPath.endsWith("/")) {
|
||||||
|
possiblePaths << QString("/" + groupPath + "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (possiblePaths.contains(basePath)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Group* innerGroup : children()) {
|
||||||
|
QString innerBasePath = basePath + innerGroup->name() + "/";
|
||||||
|
Group* group = innerGroup->findGroupByPath(groupPath, innerBasePath);
|
||||||
|
if (group != nullptr) {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QString Group::print(bool printUuids, QString baseName, int depth)
|
QString Group::print(bool printUuids, QString baseName, int depth)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -79,10 +79,11 @@ public:
|
|||||||
static const int DefaultIconNumber;
|
static const int DefaultIconNumber;
|
||||||
static const int RecycleBinIconNumber;
|
static const int RecycleBinIconNumber;
|
||||||
|
|
||||||
|
Group* findChildByName(const QString& name);
|
||||||
Entry* findEntry(QString entryId);
|
Entry* findEntry(QString entryId);
|
||||||
Entry* findEntryByUuid(const Uuid& uuid);
|
Entry* findEntryByUuid(const Uuid& uuid);
|
||||||
Entry* findEntryByPath(QString entryPath, QString basePath = QString(""));
|
Entry* findEntryByPath(QString entryPath, QString basePath = QString(""));
|
||||||
Group* findChildByName(const QString& name);
|
Group* findGroupByPath(QString groupPath, QString basePath = QString("/"));
|
||||||
void setUuid(const Uuid& uuid);
|
void setUuid(const Uuid& uuid);
|
||||||
void setName(const QString& name);
|
void setName(const QString& name);
|
||||||
void setNotes(const QString& notes);
|
void setNotes(const QString& notes);
|
||||||
|
@ -599,6 +599,15 @@ void TestGroup::testFindEntry()
|
|||||||
QVERIFY(entry != nullptr);
|
QVERIFY(entry != nullptr);
|
||||||
QCOMPARE(entry->title(), QString("entry1"));
|
QCOMPARE(entry->title(), QString("entry1"));
|
||||||
|
|
||||||
|
// We also can find the entry with the leading slash.
|
||||||
|
entry = db->rootGroup()->findEntry(QString("/entry1"));
|
||||||
|
QVERIFY(entry != nullptr);
|
||||||
|
QCOMPARE(entry->title(), QString("entry1"));
|
||||||
|
|
||||||
|
// But two slashes should not be accepted.
|
||||||
|
entry = db->rootGroup()->findEntry(QString("//entry1"));
|
||||||
|
QVERIFY(entry == nullptr);
|
||||||
|
|
||||||
entry = db->rootGroup()->findEntry(entry2->uuid().toHex());
|
entry = db->rootGroup()->findEntry(entry2->uuid().toHex());
|
||||||
QVERIFY(entry != nullptr);
|
QVERIFY(entry != nullptr);
|
||||||
QCOMPARE(entry->title(), QString("entry2"));
|
QCOMPARE(entry->title(), QString("entry2"));
|
||||||
@ -607,6 +616,14 @@ void TestGroup::testFindEntry()
|
|||||||
QVERIFY(entry != nullptr);
|
QVERIFY(entry != nullptr);
|
||||||
QCOMPARE(entry->title(), QString("entry2"));
|
QCOMPARE(entry->title(), QString("entry2"));
|
||||||
|
|
||||||
|
entry = db->rootGroup()->findEntry(QString("/entry2"));
|
||||||
|
QVERIFY(entry == nullptr);
|
||||||
|
|
||||||
|
// We also can find the entry with the leading slash.
|
||||||
|
entry = db->rootGroup()->findEntry(QString("/group1/entry2"));
|
||||||
|
QVERIFY(entry != nullptr);
|
||||||
|
QCOMPARE(entry->title(), QString("entry2"));
|
||||||
|
|
||||||
// Should also find the entry only by title.
|
// Should also find the entry only by title.
|
||||||
entry = db->rootGroup()->findEntry(QString("entry2"));
|
entry = db->rootGroup()->findEntry(QString("entry2"));
|
||||||
QVERIFY(entry != nullptr);
|
QVERIFY(entry != nullptr);
|
||||||
@ -629,6 +646,70 @@ void TestGroup::testFindEntry()
|
|||||||
delete db;
|
delete db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestGroup::testFindGroupByPath()
|
||||||
|
{
|
||||||
|
Database* db = new Database();
|
||||||
|
|
||||||
|
Group* group1 = new Group();
|
||||||
|
group1->setName("group1");
|
||||||
|
group1->setParent(db->rootGroup());
|
||||||
|
|
||||||
|
Group* group2 = new Group();
|
||||||
|
group2->setName("group2");
|
||||||
|
group2->setParent(group1);
|
||||||
|
|
||||||
|
Group* group;
|
||||||
|
|
||||||
|
group = db->rootGroup()->findGroupByPath("/");
|
||||||
|
QVERIFY(group != nullptr);
|
||||||
|
QCOMPARE(group->uuid(), db->rootGroup()->uuid());
|
||||||
|
|
||||||
|
// We also accept it if the leading slash is missing.
|
||||||
|
group = db->rootGroup()->findGroupByPath("");
|
||||||
|
QVERIFY(group != nullptr);
|
||||||
|
QCOMPARE(group->uuid(), db->rootGroup()->uuid());
|
||||||
|
|
||||||
|
group = db->rootGroup()->findGroupByPath("/group1/");
|
||||||
|
QVERIFY(group != nullptr);
|
||||||
|
QCOMPARE(group->uuid(), group1->uuid());
|
||||||
|
|
||||||
|
// We also accept it if the leading slash is missing.
|
||||||
|
group = db->rootGroup()->findGroupByPath("group1/");
|
||||||
|
QVERIFY(group != nullptr);
|
||||||
|
QCOMPARE(group->uuid(), group1->uuid());
|
||||||
|
|
||||||
|
// Too many slashes at the end
|
||||||
|
group = db->rootGroup()->findGroupByPath("group1//");
|
||||||
|
QVERIFY(group == nullptr);
|
||||||
|
|
||||||
|
// Missing a slash at the end.
|
||||||
|
group = db->rootGroup()->findGroupByPath("/group1");
|
||||||
|
QVERIFY(group != nullptr);
|
||||||
|
QCOMPARE(group->uuid(), group1->uuid());
|
||||||
|
|
||||||
|
// Too many slashes at the start
|
||||||
|
group = db->rootGroup()->findGroupByPath("//group1");
|
||||||
|
QVERIFY(group == nullptr);
|
||||||
|
|
||||||
|
group = db->rootGroup()->findGroupByPath("/group1/group2/");
|
||||||
|
QVERIFY(group != nullptr);
|
||||||
|
QCOMPARE(group->uuid(), group2->uuid());
|
||||||
|
|
||||||
|
// We also accept it if the leading slash is missing.
|
||||||
|
group = db->rootGroup()->findGroupByPath("group1/group2/");
|
||||||
|
QVERIFY(group != nullptr);
|
||||||
|
QCOMPARE(group->uuid(), group2->uuid());
|
||||||
|
|
||||||
|
group = db->rootGroup()->findGroupByPath("group1/group2");
|
||||||
|
QVERIFY(group != nullptr);
|
||||||
|
QCOMPARE(group->uuid(), group2->uuid());
|
||||||
|
|
||||||
|
group = db->rootGroup()->findGroupByPath("invalid");
|
||||||
|
QVERIFY(group == nullptr);
|
||||||
|
|
||||||
|
delete db;
|
||||||
|
}
|
||||||
|
|
||||||
void TestGroup::testPrint()
|
void TestGroup::testPrint()
|
||||||
{
|
{
|
||||||
Database* db = new Database();
|
Database* db = new Database();
|
||||||
|
@ -40,6 +40,7 @@ private slots:
|
|||||||
void testMergeDatabase();
|
void testMergeDatabase();
|
||||||
void testMergeConflictKeepBoth();
|
void testMergeConflictKeepBoth();
|
||||||
void testFindEntry();
|
void testFindEntry();
|
||||||
|
void testFindGroupByPath();
|
||||||
void testPrint();
|
void testPrint();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user