diff options
Diffstat (limited to 'src/cli/Clip.cpp')
-rw-r--r-- | src/cli/Clip.cpp | 72 |
1 files changed, 49 insertions, 23 deletions
diff --git a/src/cli/Clip.cpp b/src/cli/Clip.cpp index 482ad8a13..1bd5cc4ba 100644 --- a/src/cli/Clip.cpp +++ b/src/cli/Clip.cpp @@ -17,7 +17,6 @@ #include <chrono> #include <cstdlib> -#include <stdio.h> #include <thread> #include "Clip.h" @@ -28,14 +27,23 @@ #include "core/Entry.h" #include "core/Group.h" -const QCommandLineOption Clip::TotpOption = QCommandLineOption(QStringList() << "t" - << "totp", - QObject::tr("Copy the current TOTP to the clipboard.")); +const QCommandLineOption Clip::AttributeOption = QCommandLineOption( + QStringList() << "a" + << "attribute", + QObject::tr("Copy the given attribute to the clipboard. Defaults to \"password\" if not specified."), + "attr", + "password"); + +const QCommandLineOption Clip::TotpOption = + QCommandLineOption(QStringList() << "t" + << "totp", + QObject::tr("Copy the current TOTP to the clipboard (equivalent to \"-a totp\").")); Clip::Clip() { name = QString("clip"); - description = QObject::tr("Copy an entry's password to the clipboard."); + description = QObject::tr("Copy an entry's attribute to the clipboard."); + options.append(Clip::AttributeOption); options.append(Clip::TotpOption); positionalArguments.append( {QString("entry"), QObject::tr("Path of the entry to clip.", "clip = copy to clipboard"), QString("")}); @@ -45,41 +53,63 @@ Clip::Clip() int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer<QCommandLineParser> parser) { + auto& out = parser->isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT; + auto& err = Utils::STDERR; + const QStringList args = parser->positionalArguments(); const QString& entryPath = args.at(1); QString timeout; if (args.size() == 3) { timeout = args.at(2); } - bool clipTotp = parser->isSet(Clip::TotpOption); - TextStream errorTextStream(Utils::STDERR); int timeoutSeconds = 0; if (!timeout.isEmpty() && timeout.toInt() <= 0) { - errorTextStream << QObject::tr("Invalid timeout value %1.").arg(timeout) << endl; + err << QObject::tr("Invalid timeout value %1.").arg(timeout) << endl; return EXIT_FAILURE; } else if (!timeout.isEmpty()) { timeoutSeconds = timeout.toInt(); } - TextStream outputTextStream(parser->isSet(Command::QuietOption) ? Utils::DEVNULL : Utils::STDOUT, - QIODevice::WriteOnly); Entry* entry = database->rootGroup()->findEntryByPath(entryPath); if (!entry) { - errorTextStream << QObject::tr("Entry %1 not found.").arg(entryPath) << endl; + err << QObject::tr("Entry %1 not found.").arg(entryPath) << endl; + return EXIT_FAILURE; + } + + if (parser->isSet(AttributeOption) && parser->isSet(TotpOption)) { + err << QObject::tr("ERROR: Please specify one of --attribute or --totp, not both.") << endl; return EXIT_FAILURE; } + QString selectedAttribute = parser->value(AttributeOption); QString value; - if (clipTotp) { + bool found = false; + if (parser->isSet(TotpOption) || selectedAttribute == "totp") { if (!entry->hasTotp()) { - errorTextStream << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << endl; + err << QObject::tr("Entry with path %1 has no TOTP set up.").arg(entryPath) << endl; return EXIT_FAILURE; } + found = true; value = entry->totp(); } else { - value = entry->password(); + QStringList attrs = Utils::findAttributes(*entry->attributes(), selectedAttribute); + if (attrs.size() > 1) { + err << QObject::tr("ERROR: attribute %1 is ambiguous, it matches %2.") + .arg(selectedAttribute, QLocale().createSeparatedList(attrs)) + << endl; + return EXIT_FAILURE; + } else if (attrs.size() == 1) { + found = true; + selectedAttribute = attrs[0]; + value = entry->attributes()->value(selectedAttribute); + } + } + + if (!found) { + out << QObject::tr("Attribute \"%1\" not found.").arg(selectedAttribute) << endl; + return EXIT_FAILURE; } int exitCode = Utils::clipText(value); @@ -87,11 +117,7 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer< return exitCode; } - if (clipTotp) { - outputTextStream << QObject::tr("Entry's current TOTP copied to the clipboard!") << endl; - } else { - outputTextStream << QObject::tr("Entry's password copied to the clipboard!") << endl; - } + out << QObject::tr("Entry's \"%1\" attribute copied to the clipboard!").arg(selectedAttribute) << endl; if (!timeoutSeconds) { return exitCode; @@ -99,15 +125,15 @@ int Clip::executeWithDatabase(QSharedPointer<Database> database, QSharedPointer< QString lastLine = ""; while (timeoutSeconds > 0) { - outputTextStream << '\r' << QString(lastLine.size(), ' ') << '\r'; + out << '\r' << QString(lastLine.size(), ' ') << '\r'; lastLine = QObject::tr("Clearing the clipboard in %1 second(s)...", "", timeoutSeconds).arg(timeoutSeconds); - outputTextStream << lastLine << flush; + out << lastLine << flush; std::this_thread::sleep_for(std::chrono::milliseconds(1000)); --timeoutSeconds; } Utils::clipText(""); - outputTextStream << '\r' << QString(lastLine.size(), ' ') << '\r'; - outputTextStream << QObject::tr("Clipboard cleared!") << endl; + out << '\r' << QString(lastLine.size(), ' ') << '\r'; + out << QObject::tr("Clipboard cleared!") << endl; return EXIT_SUCCESS; } |