Adding top-level fields to CLI commands

The top-level fields are currently not accessible from the CLI, which
makes it impossible to select entries or groups based on the UUID.
There are other top-level fields I believe, like the expiry date,
but I only added the two most critical fields for the moment.
This commit is contained in:
louib 2022-07-05 09:07:39 -04:00 committed by Jonathan White
parent a6d3f973fa
commit aa839e2619
6 changed files with 57 additions and 4 deletions

View File

@ -118,6 +118,9 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
found = true;
value = entry->totp();
} else if (Utils::EntryFieldNames.contains(selectedAttribute)) {
value = Utils::getTopLevelField(entry, selectedAttribute);
found = true;
} else {
QStringList attrs = Utils::findAttributes(*entry->attributes(), selectedAttribute);
if (attrs.size() > 1) {

View File

@ -81,11 +81,22 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
bool showDefaultAttributes = attributes.isEmpty() && !showTotp;
if (showDefaultAttributes) {
attributes = EntryAttributes::DefaultAttributes;
for (QString fieldName : Utils::EntryFieldNames) {
attributes.append(fieldName);
}
}
// Iterate over the attributes and output them line-by-line.
bool encounteredError = false;
for (const QString& attributeName : asConst(attributes)) {
if (Utils::EntryFieldNames.contains(attributeName)) {
if (showDefaultAttributes) {
out << attributeName << ": ";
}
out << Utils::getTopLevelField(entry, attributeName) << endl;
continue;
}
QStringList attrs = Utils::findAttributes(*entry->attributes(), attributeName);
if (attrs.isEmpty()) {
encounteredError = true;

View File

@ -18,6 +18,7 @@
#include "Utils.h"
#include "core/Database.h"
#include "core/Entry.h"
#include "core/EntryAttributes.h"
#include "keys/FileKey.h"
#ifdef WITH_XC_YUBIKEY
@ -368,6 +369,17 @@ namespace Utils
return result;
}
QString getTopLevelField(const Entry* entry, const QString& fieldName)
{
if (fieldName == UuidFieldName) {
return entry->uuid().toString();
}
if (fieldName == TagsFieldName) {
return entry->tags();
}
return QString("");
}
QStringList findAttributes(const EntryAttributes& attributes, const QString& name)
{
QStringList result;

View File

@ -22,6 +22,7 @@
class CompositeKey;
class Database;
class Entry;
class EntryAttributes;
class FileKey;
class PasswordKey;
@ -33,6 +34,10 @@ namespace Utils
extern QTextStream STDIN;
extern QTextStream DEVNULL;
static const QString UuidFieldName = "Uuid";
static const QString TagsFieldName = "Tags";
static const QStringList EntryFieldNames(QStringList() << UuidFieldName << TagsFieldName);
void setDefaultTextStreams();
void setStdinEcho(bool enable);
@ -55,6 +60,10 @@ namespace Utils
* (case-insensitive).
*/
QStringList findAttributes(const EntryAttributes& attributes, const QString& name);
/**
* Get the value of a top-level Entry field using its name.
*/
QString getTopLevelField(const Entry* entry, const QString& fieldName);
}; // namespace Utils
#endif // KEEPASSXC_UTILS_H

View File

@ -30,7 +30,6 @@ const QString EntryAttributes::URLKey = "URL";
const QString EntryAttributes::NotesKey = "Notes";
const QStringList EntryAttributes::DefaultAttributes(QStringList()
<< TitleKey << UserNameKey << PasswordKey << URLKey << NotesKey);
const QString EntryAttributes::WantedFieldGroupName = "WantedField";
const QString EntryAttributes::SearchInGroupName = "SearchIn";
const QString EntryAttributes::SearchTextGroupName = "SearchText";

View File

@ -662,6 +662,11 @@ void TestCli::testClip()
execCmd(clipCmd, {"clip", m_dbFile->fileName(), "/Sample Entry", "0", "-a", "username"});
QTRY_COMPARE(clipboard->text(), QString("User Name"));
// Uuid (top-level field)
setInput("a");
execCmd(clipCmd, {"clip", m_dbFile->fileName(), "/Sample Entry", "0", "-a", "Uuid"});
QTRY_COMPARE(clipboard->text(), QString("{9f4544c2-ab00-c74a-8a1a-6eaf26cf57e9}"));
// TOTP
setInput("a");
execCmd(clipCmd, {"clip", m_dbFile->fileName(), "/Sample Entry", "0", "--totp"});
@ -1937,7 +1942,9 @@ void TestCli::testShow()
"UserName: User Name\n"
"Password: PROTECTED\n"
"URL: http://www.somesite.com/\n"
"Notes: Notes\n"));
"Notes: Notes\n"
"Uuid: {9f4544c2-ab00-c74a-8a1a-6eaf26cf57e9}\n"
"Tags: \n"));
setInput("a");
execCmd(showCmd, {"show", "-s", m_dbFile->fileName(), "/Sample Entry"});
@ -1946,7 +1953,9 @@ void TestCli::testShow()
"UserName: User Name\n"
"Password: Password\n"
"URL: http://www.somesite.com/\n"
"Notes: Notes\n"));
"Notes: Notes\n"
"Uuid: {9f4544c2-ab00-c74a-8a1a-6eaf26cf57e9}\n"
"Tags: \n"));
setInput("a");
execCmd(showCmd, {"show", m_dbFile->fileName(), "-q", "/Sample Entry"});
@ -1956,7 +1965,9 @@ void TestCli::testShow()
"UserName: User Name\n"
"Password: PROTECTED\n"
"URL: http://www.somesite.com/\n"
"Notes: Notes\n"));
"Notes: Notes\n"
"Uuid: {9f4544c2-ab00-c74a-8a1a-6eaf26cf57e9}\n"
"Tags: \n"));
setInput("a");
execCmd(showCmd, {"show", m_dbFile->fileName(), "--show-attachments", "/Sample Entry"});
@ -1968,6 +1979,8 @@ void TestCli::testShow()
"Password: PROTECTED\n"
"URL: http://www.somesite.com/\n"
"Notes: Notes\n"
"Uuid: {9f4544c2-ab00-c74a-8a1a-6eaf26cf57e9}\n"
"Tags: \n"
"\n"
"Attachments:\n"
" Sample attachment.txt (15.0 B)\n"));
@ -1982,6 +1995,8 @@ void TestCli::testShow()
"Password: PROTECTED\n"
"URL: https://www.bank.com\n"
"Notes: Important note\n"
"Uuid: {20b183fd-6878-4506-a50b-06d30792aa10}\n"
"Tags: \n"
"\n"
"No attachments present.\n"));
@ -1993,6 +2008,10 @@ void TestCli::testShow()
execCmd(showCmd, {"show", "-a", "Password", m_dbFile->fileName(), "/Sample Entry"});
QCOMPARE(m_stdout->readAll(), QByteArray("Password\n"));
setInput("a");
execCmd(showCmd, {"show", "-a", "Uuid", m_dbFile->fileName(), "/Sample Entry"});
QCOMPARE(m_stdout->readAll(), QByteArray("{9f4544c2-ab00-c74a-8a1a-6eaf26cf57e9}\n"));
setInput("a");
execCmd(showCmd, {"show", "-a", "Title", "-a", "URL", m_dbFile->fileName(), "/Sample Entry"});
QCOMPARE(m_stdout->readAll(),