mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-01-13 08:19:50 -05:00
Add delete-entry command to Browser Integration API
This commit is contained in:
parent
e3c7b570ae
commit
4c10e516c3
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -22,6 +22,7 @@
|
||||
#include "BrowserShared.h"
|
||||
#include "config-keepassx.h"
|
||||
#include "core/Global.h"
|
||||
#include "core/Tools.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
@ -51,7 +52,8 @@ namespace
|
||||
ERROR_KEEPASS_NO_URL_PROVIDED = 14,
|
||||
ERROR_KEEPASS_NO_LOGINS_FOUND = 15,
|
||||
ERROR_KEEPASS_NO_GROUPS_FOUND = 16,
|
||||
ERROR_KEEPASS_CANNOT_CREATE_NEW_GROUP = 17
|
||||
ERROR_KEEPASS_CANNOT_CREATE_NEW_GROUP = 17,
|
||||
ERROR_KEEPASS_NO_VALID_UUID_PROVIDED = 18
|
||||
};
|
||||
}
|
||||
|
||||
@ -112,6 +114,8 @@ QJsonObject BrowserAction::handleAction(const QJsonObject& json)
|
||||
return handleCreateNewGroup(json, action);
|
||||
} else if (action.compare("get-totp", Qt::CaseSensitive) == 0) {
|
||||
return handleGetTotp(json, action);
|
||||
} else if (action.compare("delete-entry", Qt::CaseSensitive) == 0) {
|
||||
return handleDeleteEntry(json, action);
|
||||
}
|
||||
|
||||
// Action was not recognized
|
||||
@ -360,6 +364,10 @@ QJsonObject BrowserAction::handleSetLogin(const QJsonObject& json, const QString
|
||||
if (uuid.isEmpty()) {
|
||||
browserService()->addEntry(id, login, password, url, submitUrl, realm, group, groupUuid);
|
||||
} else {
|
||||
if (!Tools::isValidUuid(uuid)) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_NO_VALID_UUID_PROVIDED);
|
||||
}
|
||||
|
||||
result = browserService()->updateEntry(id, uuid, login, password, url, submitUrl);
|
||||
}
|
||||
|
||||
@ -490,6 +498,9 @@ QJsonObject BrowserAction::handleGetTotp(const QJsonObject& json, const QString&
|
||||
}
|
||||
|
||||
const QString uuid = decrypted.value("uuid").toString();
|
||||
if (!Tools::isValidUuid(uuid)) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_NO_VALID_UUID_PROVIDED);
|
||||
}
|
||||
|
||||
// Get the current TOTP
|
||||
const auto totp = browserService()->getCurrentTotp(uuid);
|
||||
@ -501,6 +512,39 @@ QJsonObject BrowserAction::handleGetTotp(const QJsonObject& json, const QString&
|
||||
return buildResponse(action, message, newNonce);
|
||||
}
|
||||
|
||||
QJsonObject BrowserAction::handleDeleteEntry(const QJsonObject& json, const QString& action)
|
||||
{
|
||||
const QString nonce = json.value("nonce").toString();
|
||||
const QString encrypted = json.value("message").toString();
|
||||
|
||||
if (!m_associated) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_ASSOCIATION_FAILED);
|
||||
}
|
||||
|
||||
const QJsonObject decrypted = decryptMessage(encrypted, nonce);
|
||||
if (decrypted.isEmpty()) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_CANNOT_DECRYPT_MESSAGE);
|
||||
}
|
||||
|
||||
QString command = decrypted.value("action").toString();
|
||||
if (command.isEmpty() || command.compare("delete-entry", Qt::CaseSensitive) != 0) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_INCORRECT_ACTION);
|
||||
}
|
||||
|
||||
const auto uuid = decrypted.value("uuid").toString();
|
||||
if (!Tools::isValidUuid(uuid)) {
|
||||
return getErrorReply(action, ERROR_KEEPASS_NO_VALID_UUID_PROVIDED);
|
||||
}
|
||||
|
||||
const auto result = browserService()->deleteEntry(uuid);
|
||||
|
||||
const QString newNonce = incrementNonce(nonce);
|
||||
QJsonObject message = buildMessage(newNonce);
|
||||
message["success"] = result ? TRUE_STR : FALSE_STR;
|
||||
|
||||
return buildResponse(action, message, newNonce);
|
||||
}
|
||||
|
||||
QJsonObject BrowserAction::getErrorReply(const QString& action, const int errorCode) const
|
||||
{
|
||||
QJsonObject response;
|
||||
@ -564,6 +608,8 @@ QString BrowserAction::getErrorMessage(const int errorCode) const
|
||||
return QObject::tr("No groups found");
|
||||
case ERROR_KEEPASS_CANNOT_CREATE_NEW_GROUP:
|
||||
return QObject::tr("Cannot create new group");
|
||||
case ERROR_KEEPASS_NO_VALID_UUID_PROVIDED:
|
||||
return QObject::tr("No valid UUID provided");
|
||||
default:
|
||||
return QObject::tr("Unknown error");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -43,6 +43,7 @@ private:
|
||||
QJsonObject handleGetDatabaseGroups(const QJsonObject& json, const QString& action);
|
||||
QJsonObject handleCreateNewGroup(const QJsonObject& json, const QString& action);
|
||||
QJsonObject handleGetTotp(const QJsonObject& json, const QString& action);
|
||||
QJsonObject handleDeleteEntry(const QJsonObject& json, const QString& action);
|
||||
|
||||
QJsonObject buildMessage(const QString& nonce) const;
|
||||
QJsonObject buildResponse(const QString& action, const QJsonObject& message, const QString& nonce);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -578,6 +578,32 @@ bool BrowserService::updateEntry(const QString& dbid,
|
||||
return result;
|
||||
}
|
||||
|
||||
bool BrowserService::deleteEntry(const QString& uuid)
|
||||
{
|
||||
auto db = selectedDatabase();
|
||||
if (!db) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto* entry = db->rootGroup()->findEntryByUuid(Tools::hexToUuid(uuid));
|
||||
if (!entry) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto dialogResult = MessageBox::warning(nullptr,
|
||||
tr("KeePassXC: Delete entry"),
|
||||
tr("A request for deleting entry \"%1\" has been received.\n"
|
||||
"Do you want to delete the entry?\n")
|
||||
.arg(entry->title()),
|
||||
MessageBox::Yes | MessageBox::No);
|
||||
if (dialogResult != MessageBox::Yes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
db->recycleEntry(entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
QList<Entry*>
|
||||
BrowserService::searchEntries(const QSharedPointer<Database>& db, const QString& siteUrlStr, const QString& formUrlStr)
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Francois Ferrand
|
||||
* Copyright (C) 2017 Sami Vänttinen <sami.vanttinen@protonmail.com>
|
||||
* Copyright (C) 2020 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -71,6 +71,7 @@ public:
|
||||
const QString& password,
|
||||
const QString& siteUrlStr,
|
||||
const QString& formUrlStr);
|
||||
bool deleteEntry(const QString& uuid);
|
||||
|
||||
QJsonArray findMatchingEntries(const QString& dbid,
|
||||
const QString& siteUrlStr,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
|
||||
* Copyright (C) 2017 Lennart Glauer <mail@lennart-glauer.de>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -317,6 +317,20 @@ namespace Tools
|
||||
return QUuid::fromRfc4122(QByteArray::fromHex(uuid.toLatin1()));
|
||||
}
|
||||
|
||||
bool isValidUuid(const QString& uuidStr)
|
||||
{
|
||||
if (uuidStr.isEmpty() || uuidStr.length() != 32 || !isHex(uuidStr.toLatin1())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto uuid = hexToUuid(uuidStr);
|
||||
if (uuid.isNull() || uuid.version() == QUuid::VerUnknown) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString envSubstitute(const QString& filepath, QProcessEnvironment environment)
|
||||
{
|
||||
QString subbed = filepath;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Felix Geyer <debfx@fobos.de>
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -40,6 +40,7 @@ namespace Tools
|
||||
bool checkUrlValid(const QString& urlField);
|
||||
QString uuidToHex(const QUuid& uuid);
|
||||
QUuid hexToUuid(const QString& uuid);
|
||||
bool isValidUuid(const QString& uuidStr);
|
||||
QRegularExpression convertToRegex(const QString& string,
|
||||
bool useWildcards = false,
|
||||
bool exactMatch = false,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -88,3 +88,20 @@ void TestTools::testEnvSubstitute()
|
||||
QCOMPARE(Tools::envSubstitute("start/$EMPTY$$EMPTY$HOME/end", environment), QString("start/$/home/user/end"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void TestTools::testValidUuid()
|
||||
{
|
||||
auto validUuid = Tools::uuidToHex(QUuid::createUuid());
|
||||
auto nonValidUuid = "1234567890abcdef1234567890abcdef";
|
||||
auto emptyUuid = QString();
|
||||
auto shortUuid = validUuid.left(10);
|
||||
auto longUuid = validUuid + "baddata";
|
||||
auto nonHexUuid = Tools::uuidToHex(QUuid::createUuid()).replace(0, 1, 'p');
|
||||
|
||||
QVERIFY(Tools::isValidUuid(validUuid));
|
||||
QVERIFY(not Tools::isValidUuid(nonValidUuid));
|
||||
QVERIFY(not Tools::isValidUuid(emptyUuid));
|
||||
QVERIFY(not Tools::isValidUuid(shortUuid));
|
||||
QVERIFY(not Tools::isValidUuid(longUuid));
|
||||
QVERIFY(not Tools::isValidUuid(nonHexUuid));
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
|
||||
* Copyright (C) 2021 KeePassXC Team <team@keepassxc.org>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -28,6 +28,7 @@ private slots:
|
||||
void testIsHex();
|
||||
void testIsBase64();
|
||||
void testEnvSubstitute();
|
||||
void testValidUuid();
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_TESTTOOLS_H
|
||||
|
Loading…
Reference in New Issue
Block a user