[CLI] Add Option to show all attributes (Show command) (#8256)

* Adding --all option to Show
This commit is contained in:
louib 2022-08-20 22:38:58 -04:00 committed by GitHub
parent aa839e2619
commit 15b9e82f93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 7 deletions

View File

@ -16,7 +16,7 @@
= keepassxc-cli(1) = keepassxc-cli(1)
KeePassXC Team <team@keepassxc.org> KeePassXC Team <team@keepassxc.org>
:docdate: 2020-08-31 :docdate: 2022-08-20
:doctype: manpage :doctype: manpage
:mansource: KeePassXC {revnumber} :mansource: KeePassXC {revnumber}
:manmanual: General Commands Manual :manmanual: General Commands Manual
@ -252,6 +252,9 @@ The same password generation options as documented for the generate command can
If no attributes are specified and *-t* is not specified, a summary of the default attributes is given. If no attributes are specified and *-t* is not specified, a summary of the default attributes is given.
Protected attributes will be displayed in clear text if specified explicitly by this option. Protected attributes will be displayed in clear text if specified explicitly by this option.
*--all*::
Show all the attributes of the entry.
*-s*, *--show-protected*:: *-s*, *--show-protected*::
Shows the protected attributes in clear text. Shows the protected attributes in clear text.

View File

@ -7812,6 +7812,10 @@ Kernel: %3 %4</source>
<source>Please present or touch your YubiKey to continue.</source> <source>Please present or touch your YubiKey to continue.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Show all the attributes of the entry.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>QtIOCompressor</name> <name>QtIOCompressor</name>

View File

@ -32,6 +32,9 @@ const QCommandLineOption Show::ProtectedAttributesOption =
<< "show-protected", << "show-protected",
QObject::tr("Show the protected attributes in clear text.")); QObject::tr("Show the protected attributes in clear text."));
const QCommandLineOption Show::AllAttributesOption =
QCommandLineOption(QStringList() << "all", QObject::tr("Show all the attributes of the entry."));
const QCommandLineOption Show::AttachmentsOption = const QCommandLineOption Show::AttachmentsOption =
QCommandLineOption(QStringList() << "show-attachments", QObject::tr("Show the attachments of the entry.")); QCommandLineOption(QStringList() << "show-attachments", QObject::tr("Show the attachments of the entry."));
@ -51,6 +54,7 @@ Show::Show()
options.append(Show::TotpOption); options.append(Show::TotpOption);
options.append(Show::AttributesOption); options.append(Show::AttributesOption);
options.append(Show::ProtectedAttributesOption); options.append(Show::ProtectedAttributesOption);
options.append(Show::AllAttributesOption);
options.append(Show::AttachmentsOption); options.append(Show::AttachmentsOption);
positionalArguments.append({QString("entry"), QObject::tr("Name of the entry to show."), QString("")}); positionalArguments.append({QString("entry"), QObject::tr("Name of the entry to show."), QString("")});
} }
@ -64,6 +68,7 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
const QString& entryPath = args.at(1); const QString& entryPath = args.at(1);
bool showTotp = parser->isSet(Show::TotpOption); bool showTotp = parser->isSet(Show::TotpOption);
bool showProtectedAttributes = parser->isSet(Show::ProtectedAttributesOption); bool showProtectedAttributes = parser->isSet(Show::ProtectedAttributesOption);
bool showAllAttributes = parser->isSet(Show::AllAttributesOption);
QStringList attributes = parser->values(Show::AttributesOption); QStringList attributes = parser->values(Show::AttributesOption);
Entry* entry = database->rootGroup()->findEntryByPath(entryPath); Entry* entry = database->rootGroup()->findEntryByPath(entryPath);
@ -77,9 +82,24 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// If no attributes specified, output the default attribute set. bool attributesWereSpecified = true;
bool showDefaultAttributes = attributes.isEmpty() && !showTotp; if (showAllAttributes) {
if (showDefaultAttributes) { attributesWereSpecified = false;
attributes = EntryAttributes::DefaultAttributes;
for (QString fieldName : Utils::EntryFieldNames) {
attributes.append(fieldName);
}
// Adding the custom attributes after the default attributes so that
// the default attributes are always shown first.
for (QString attributeName : entry->attributes()->keys()) {
if (EntryAttributes::DefaultAttributes.contains(attributeName)) {
continue;
}
attributes.append(attributeName);
}
} else if (attributes.isEmpty() && !showTotp) {
// If no attributes are specified, output the default attribute set.
attributesWereSpecified = false;
attributes = EntryAttributes::DefaultAttributes; attributes = EntryAttributes::DefaultAttributes;
for (QString fieldName : Utils::EntryFieldNames) { for (QString fieldName : Utils::EntryFieldNames) {
attributes.append(fieldName); attributes.append(fieldName);
@ -90,7 +110,7 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
bool encounteredError = false; bool encounteredError = false;
for (const QString& attributeName : asConst(attributes)) { for (const QString& attributeName : asConst(attributes)) {
if (Utils::EntryFieldNames.contains(attributeName)) { if (Utils::EntryFieldNames.contains(attributeName)) {
if (showDefaultAttributes) { if (!attributesWereSpecified) {
out << attributeName << ": "; out << attributeName << ": ";
} }
out << Utils::getTopLevelField(entry, attributeName) << endl; out << Utils::getTopLevelField(entry, attributeName) << endl;
@ -110,10 +130,10 @@ int Show::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<
continue; continue;
} }
QString canonicalName = attrs[0]; QString canonicalName = attrs[0];
if (showDefaultAttributes) { if (!attributesWereSpecified) {
out << canonicalName << ": "; out << canonicalName << ": ";
} }
if (entry->attributes()->isProtected(canonicalName) && showDefaultAttributes && !showProtectedAttributes) { if (entry->attributes()->isProtected(canonicalName) && !attributesWereSpecified && !showProtectedAttributes) {
out << "PROTECTED" << endl; out << "PROTECTED" << endl;
} else { } else {
out << entry->resolveMultiplePlaceholders(entry->attributes()->value(canonicalName)) << endl; out << entry->resolveMultiplePlaceholders(entry->attributes()->value(canonicalName)) << endl;

View File

@ -28,6 +28,7 @@ public:
int executeWithDatabase(QSharedPointer<Database> db, QSharedPointer<QCommandLineParser> parser) override; int executeWithDatabase(QSharedPointer<Database> db, QSharedPointer<QCommandLineParser> parser) override;
static const QCommandLineOption TotpOption; static const QCommandLineOption TotpOption;
static const QCommandLineOption AllAttributesOption;
static const QCommandLineOption AttributesOption; static const QCommandLineOption AttributesOption;
static const QCommandLineOption ProtectedAttributesOption; static const QCommandLineOption ProtectedAttributesOption;
static const QCommandLineOption AttachmentsOption; static const QCommandLineOption AttachmentsOption;

View File

@ -2049,6 +2049,21 @@ void TestCli::testShow()
execCmd(showCmd, {"show", m_dbFile->fileName(), "-a", "Testattribute1", "/Sample Entry"}); execCmd(showCmd, {"show", m_dbFile->fileName(), "-a", "Testattribute1", "/Sample Entry"});
QCOMPARE(m_stdout->readAll(), QByteArray()); QCOMPARE(m_stdout->readAll(), QByteArray());
QVERIFY(m_stderr->readAll().contains("ERROR: attribute Testattribute1 is ambiguous")); QVERIFY(m_stderr->readAll().contains("ERROR: attribute Testattribute1 is ambiguous"));
setInput("a");
execCmd(showCmd, {"show", "--all", m_dbFile->fileName(), "/Sample Entry"});
QCOMPARE(m_stdout->readAll(),
QByteArray("Title: Sample Entry\n"
"UserName: User Name\n"
"Password: PROTECTED\n"
"URL: http://www.somesite.com/\n"
"Notes: Notes\n"
"Uuid: {9f4544c2-ab00-c74a-8a1a-6eaf26cf57e9}\n"
"Tags: \n"
"TOTP Seed: PROTECTED\n"
"TOTP Settings: 30;6\n"
"TestAttribute1: b\n"
"testattribute1: a\n"));
} }
void TestCli::testInvalidDbFiles() void TestCli::testInvalidDbFiles()