Skip to content

Commit

Permalink
Add support for multiple URLs
Browse files Browse the repository at this point in the history
  • Loading branch information
varjolintu authored and droidmonkey committed Oct 5, 2019
1 parent a93b22f commit 1f32c6c
Show file tree
Hide file tree
Showing 11 changed files with 500 additions and 59 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ add_subdirectory(proxy)
if(WITH_XC_BROWSER)
set(keepassxcbrowser_LIB keepassxcbrowser)
set(keepassx_SOURCES ${keepassx_SOURCES} gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp)
set(keepassx_SOURCES ${keepassx_SOURCES} gui/entry/EntryURLModel.cpp)
endif()

add_subdirectory(autotype)
Expand Down
92 changes: 60 additions & 32 deletions src/browser/BrowserService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,18 @@
#include "gui/macutils/MacUtils.h"
#endif

const char BrowserService::KEEPASSXCBROWSER_NAME[] = "KeePassXC-Browser Settings";
const char BrowserService::KEEPASSXCBROWSER_OLD_NAME[] = "keepassxc-browser Settings";
const char BrowserService::ASSOCIATE_KEY_PREFIX[] = "KPXC_BROWSER_";
static const char KEEPASSXCBROWSER_GROUP_NAME[] = "KeePassXC-Browser Passwords";
const QString BrowserService::KEEPASSXCBROWSER_NAME = QStringLiteral("KeePassXC-Browser Settings");
const QString BrowserService::KEEPASSXCBROWSER_OLD_NAME = QStringLiteral("keepassxc-browser Settings");
const QString BrowserService::ASSOCIATE_KEY_PREFIX = QStringLiteral("KPXC_BROWSER_");
static const QString KEEPASSXCBROWSER_GROUP_NAME = QStringLiteral("KeePassXC-Browser Passwords");
static int KEEPASSXCBROWSER_DEFAULT_ICON = 1;
// These are for the settings and password conversion
const char BrowserService::LEGACY_ASSOCIATE_KEY_PREFIX[] = "Public Key: ";
static const char KEEPASSHTTP_NAME[] = "KeePassHttp Settings";
static const char KEEPASSHTTP_GROUP_NAME[] = "KeePassHttp Passwords";
const QString BrowserService::LEGACY_ASSOCIATE_KEY_PREFIX = QStringLiteral("Public Key: ");
static const QString KEEPASSHTTP_NAME = QStringLiteral("KeePassHttp Settings");
static const QString KEEPASSHTTP_GROUP_NAME = QStringLiteral("KeePassHttp Passwords");
// Extra entry related options saved in custom data
const char BrowserService::OPTION_SKIP_AUTO_SUBMIT[] = "BrowserSkipAutoSubmit";
const char BrowserService::OPTION_HIDE_ENTRY[] = "BrowserHideEntry";
const QString BrowserService::OPTION_SKIP_AUTO_SUBMIT = QStringLiteral("BrowserSkipAutoSubmit");
const QString BrowserService::OPTION_HIDE_ENTRY = QStringLiteral("BrowserHideEntry");

BrowserService::BrowserService(DatabaseTabWidget* parent)
: m_dbTabWidget(parent)
Expand Down Expand Up @@ -320,7 +320,7 @@ QString BrowserService::storeKey(const QString& key)
return {};
}

contains = db->metadata()->customData()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX) + id);
contains = db->metadata()->customData()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX.toUtf8()) + id);
if (contains) {
dialogResult = MessageBox::warning(nullptr,
tr("KeePassXC: Overwrite existing key?"),
Expand All @@ -333,7 +333,7 @@ QString BrowserService::storeKey(const QString& key)
} while (contains && dialogResult == MessageBox::Cancel);

hideWindow();
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX) + id, key);
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX.toUtf8()) + id, key);
return id;
}

Expand All @@ -344,7 +344,7 @@ QString BrowserService::getKey(const QString& id)
return {};
}

return db->metadata()->customData()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + id);
return db->metadata()->customData()->value(QLatin1String(ASSOCIATE_KEY_PREFIX.toUtf8()) + id);
}

QJsonArray BrowserService::findMatchingEntries(const QString& id,
Expand Down Expand Up @@ -377,9 +377,9 @@ QJsonArray BrowserService::findMatchingEntries(const QString& id,
// Check entries for authorization
QList<Entry*> pwEntriesToConfirm;
QList<Entry*> pwEntries;
for (Entry* entry : searchEntries(url, keyList)) {
if (entry->customData()->contains(BrowserService::OPTION_HIDE_ENTRY) &&
entry->customData()->value(BrowserService::OPTION_HIDE_ENTRY) == "true") {
for (auto* entry : searchEntries(url, keyList)) {
if (entry->customData()->contains(BrowserService::OPTION_HIDE_ENTRY)
&& entry->customData()->value(BrowserService::OPTION_HIDE_ENTRY) == "true") {
continue;
}

Expand Down Expand Up @@ -425,7 +425,7 @@ QJsonArray BrowserService::findMatchingEntries(const QString& id,
pwEntries = sortEntries(pwEntries, host, submitUrl);

// Fill the list
for (Entry* entry : pwEntries) {
for (auto* entry : pwEntries) {
result.append(prepareEntry(entry));
}

Expand Down Expand Up @@ -588,8 +588,7 @@ BrowserService::searchEntries(const QSharedPointer<Database>& db, const QString&
return entries;
}

for (Entry* entry : EntrySearcher().search(baseDomain(hostname), rootGroup)) {
QString entryUrl = entry->url();
auto handleURL = [&](const QString entryUrl) {
QUrl entryQUrl(entryUrl);
QString entryScheme = entryQUrl.scheme();
QUrl qUrl(url);
Expand All @@ -598,13 +597,42 @@ BrowserService::searchEntries(const QSharedPointer<Database>& db, const QString&
if ((entryQUrl.port() > 0 && entryQUrl.port() != qUrl.port())
|| (browserSettings()->matchUrlScheme() && !entryScheme.isEmpty()
&& entryScheme.compare(qUrl.scheme()) != 0)) {
continue;
return false;
}

// Filter to match hostname in URL field
if ((!entryUrl.isEmpty() && hostname.contains(entryUrl))
|| (matchUrlScheme(entryUrl) && hostname.endsWith(entryQUrl.host()))) {
entries.append(entry);
return true;
}
return false;
};

// Search host from URL fields
for (auto* entry : EntrySearcher().search(baseDomain(hostname), rootGroup)) {
if (!handleURL(entry->url())) {
continue;
}

entries.append(entry);
}

// Search for additional URL's starting with KP2A_URL
for (const auto group : rootGroup->groupsRecursive(true)) {
if (group->isRecycled() || !group->resolveSearchingEnabled()) {
continue;
}

for (auto* entry : group->entries()) {
if (entry->isRecycled() || !entry->attributes()->keys().contains("KP2A_URL")) {
continue;
}

for (const auto& key : entry->attributes()->keys()) {
if (key.contains("KP2A_URL") && handleURL(entry->attributes()->value(key))) {
entries.append(entry);
}
}
}
}

Expand All @@ -616,8 +644,7 @@ QList<Entry*> BrowserService::searchEntries(const QString& url, const StringPair
// Check if database is connected with KeePassXC-Browser
auto databaseConnected = [&](const QSharedPointer<Database>& db) {
for (const StringPair& keyPair : keyList) {
QString key =
db->metadata()->customData()->value(QLatin1String(ASSOCIATE_KEY_PREFIX) + keyPair.first);
QString key = db->metadata()->customData()->value(ASSOCIATE_KEY_PREFIX + keyPair.first);
if (!key.isEmpty() && keyPair.second == key) {
return true;
}
Expand Down Expand Up @@ -669,7 +696,7 @@ void BrowserService::convertAttributesToCustomData(const QSharedPointer<Database

int counter = 0;
int keyCounter = 0;
for (Entry* entry : entries) {
for (auto* entry : entries) {
if (progress.wasCanceled()) {
return;
}
Expand Down Expand Up @@ -722,10 +749,10 @@ void BrowserService::convertAttributesToCustomData(const QSharedPointer<Database
return;
}

const QString keePassBrowserGroupName = QLatin1String(KEEPASSXCBROWSER_GROUP_NAME);
const QString keePassHttpGroupName = QLatin1String(KEEPASSHTTP_GROUP_NAME);
const QString keePassBrowserGroupName = QLatin1String(KEEPASSXCBROWSER_GROUP_NAME.toUtf8());
const QString keePassHttpGroupName = QLatin1String(KEEPASSHTTP_GROUP_NAME.toUtf8());

for (Group* g : rootGroup->groupsRecursive(true)) {
for (auto* g : rootGroup->groupsRecursive(true)) {
if (g->name() == keePassHttpGroupName) {
g->setName(keePassBrowserGroupName);
break;
Expand All @@ -746,7 +773,7 @@ QList<Entry*> BrowserService::sortEntries(QList<Entry*>& pwEntries, const QStrin

// Build map of prioritized entries
QMultiMap<int, Entry*> priorities;
for (Entry* entry : pwEntries) {
for (auto* entry : pwEntries) {
priorities.insert(sortPriority(entry, host, submitUrl, baseSubmitUrl), entry);
}

Expand Down Expand Up @@ -802,7 +829,7 @@ bool BrowserService::confirmEntries(QList<Entry*>& pwEntriesToConfirm,

int res = accessControlDialog.exec();
if (accessControlDialog.remember()) {
for (Entry* entry : pwEntriesToConfirm) {
for (auto* entry : pwEntriesToConfirm) {
BrowserEntryConfig config;
config.load(entry);
if (res == QDialog::Accepted) {
Expand Down Expand Up @@ -854,7 +881,7 @@ QJsonObject BrowserService::prepareEntry(const Entry* entry)
if (browserSettings()->supportKphFields()) {
const EntryAttributes* attr = entry->attributes();
QJsonArray stringFields;
for (const QString& key : attr->keys()) {
for (const auto& key : attr->keys()) {
if (key.startsWith(QLatin1String("KPH: "))) {
QJsonObject sField;
sField[key] = entry->resolveMultiplePlaceholders(attr->value(key));
Expand Down Expand Up @@ -900,7 +927,7 @@ Group* BrowserService::getDefaultEntryGroup(const QSharedPointer<Database>& sele
return nullptr;
}

const QString groupName = QLatin1String(KEEPASSXCBROWSER_GROUP_NAME);
const QString groupName = QLatin1String(KEEPASSXCBROWSER_GROUP_NAME.toUtf8());

for (auto* g : rootGroup->groupsRecursive(true)) {
if (g->name() == groupName && !g->isRecycled()) {
Expand Down Expand Up @@ -1081,8 +1108,9 @@ int BrowserService::moveKeysToCustomData(Entry* entry, const QSharedPointer<Data
publicKey.remove(LEGACY_ASSOCIATE_KEY_PREFIX);

// Add key to database custom data
if (db && !db->metadata()->customData()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX) + publicKey)) {
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX) + publicKey,
if (db
&& !db->metadata()->customData()->contains(QLatin1String(ASSOCIATE_KEY_PREFIX.toUtf8()) + publicKey)) {
db->metadata()->customData()->set(QLatin1String(ASSOCIATE_KEY_PREFIX.toUtf8()) + publicKey,
entry->attributes()->value(key));
++keyCounter;
}
Expand Down
12 changes: 6 additions & 6 deletions src/browser/BrowserService.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ class BrowserService : public QObject
void convertAttributesToCustomData(const QSharedPointer<Database>& currentDb = {});

public:
static const char KEEPASSXCBROWSER_NAME[];
static const char KEEPASSXCBROWSER_OLD_NAME[];
static const char ASSOCIATE_KEY_PREFIX[];
static const char LEGACY_ASSOCIATE_KEY_PREFIX[];
static const char OPTION_SKIP_AUTO_SUBMIT[];
static const char OPTION_HIDE_ENTRY[];
static const QString KEEPASSXCBROWSER_NAME;
static const QString KEEPASSXCBROWSER_OLD_NAME;
static const QString ASSOCIATE_KEY_PREFIX;
static const QString LEGACY_ASSOCIATE_KEY_PREFIX;
static const QString OPTION_SKIP_AUTO_SUBMIT;
static const QString OPTION_HIDE_ENTRY;

public slots:
QJsonArray findMatchingEntries(const QString& id,
Expand Down
Loading

0 comments on commit 1f32c6c

Please sign in to comment.