Skip to content

Commit

Permalink
Improve AutoOpen
Browse files Browse the repository at this point in the history
* Add support for 'ifDevice' feature, closes keepassxreboot#2871
* Resolve placeholders for username and password to support references, fixes keepassxreboot#2078
* Add support for open databases from an entry when the url starts with 'kdbx://'. Uses the same syntax as AutoOpen. Closes keepassxreboot#1536.
  • Loading branch information
droidmonkey committed Jun 4, 2020
1 parent b7104be commit f129768
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 26 deletions.
89 changes: 63 additions & 26 deletions src/gui/DatabaseWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <QFile>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QHostInfo>
#include <QKeyEvent>
#include <QLabel>
#include <QLineEdit>
Expand Down Expand Up @@ -891,6 +892,8 @@ void DatabaseWidget::openUrlForEntry(Entry* entry)
getMainWindow()->minimizeOrHide();
}
}
} else if (cmdString.startsWith("kdbx://")) {
openDatabaseFromEntry(entry, false);
} else {
QUrl url = QUrl::fromUserInput(entry->resolveMultiplePlaceholders(entry->url()));
if (!url.isEmpty()) {
Expand Down Expand Up @@ -2021,39 +2024,73 @@ void DatabaseWidget::processAutoOpen()
if (entry->url().isEmpty() || (entry->password().isEmpty() && entry->username().isEmpty())) {
continue;
}
QFileInfo filepath;
QFileInfo keyfile;
QString databaseUrl = entry->resolveMultiplePlaceholders(entry->url());

if (databaseUrl.startsWith("file://")) {
QUrl url(databaseUrl);
filepath.setFile(url.toLocalFile());
} else {
filepath.setFile(databaseUrl);
if (filepath.isRelative()) {
QFileInfo currentpath(m_db->filePath());
filepath.setFile(currentpath.absoluteDir(), databaseUrl);
// Support ifDevice advanced entry, a comma separated list of computer names
// that control whether to perform AutoOpen on this entry or not. Can be
// negated using '!'
auto ifDevice = entry->attribute("ifDevice");
if (!ifDevice.isEmpty()) {
bool loadDb = false;
auto hostName = QHostInfo::localHostName();
for (auto& dev : ifDevice.split(",")) {
dev = dev.trimmed();
if (dev.startsWith("!") && dev.mid(1).compare(hostName, Qt::CaseInsensitive) == 0) {
// Machine name matched an exclusion, don't load this database
loadDb = false;
break;
} else if (dev.compare(hostName, Qt::CaseInsensitive) == 0) {
loadDb = true;
}
}
if (!loadDb) {
continue;
}
}

if (!filepath.isFile()) {
continue;
openDatabaseFromEntry(entry);
}
}

void DatabaseWidget::openDatabaseFromEntry(const Entry* entry, bool inBackground)
{
auto keyFile = entry->resolveMultiplePlaceholders(entry->username());
auto password = entry->resolveMultiplePlaceholders(entry->password());
auto databaseUrl = entry->resolveMultiplePlaceholders(entry->url());
if (databaseUrl.startsWith("kdbx://")) {
databaseUrl = databaseUrl.mid(7);
}

QFileInfo dbFileInfo;
if (databaseUrl.startsWith("file://")) {
QUrl url(databaseUrl);
dbFileInfo.setFile(url.toLocalFile());
} else {
dbFileInfo.setFile(databaseUrl);
if (dbFileInfo.isRelative()) {
QFileInfo currentpath(m_db->filePath());
dbFileInfo.setFile(currentpath.absoluteDir(), databaseUrl);
}
}

if (!entry->username().isEmpty()) {
if (entry->username().startsWith("file://")) {
QUrl keyfileUrl(entry->username());
keyfile.setFile(keyfileUrl.toLocalFile());
} else {
keyfile.setFile(entry->username());
if (keyfile.isRelative()) {
QFileInfo currentpath(m_db->filePath());
keyfile.setFile(currentpath.absoluteDir(), entry->username());
}
if (!dbFileInfo.isFile()) {
showErrorMessage(tr("Could not find database file: %1").arg(databaseUrl));
return;
}

QFileInfo keyFileInfo;
if (!keyFile.isEmpty()) {
if (keyFile.startsWith("file://")) {
QUrl keyfileUrl(keyFile);
keyFileInfo.setFile(keyfileUrl.toLocalFile());
} else {
keyFileInfo.setFile(keyFile);
if (keyFileInfo.isRelative()) {
QFileInfo currentpath(m_db->filePath());
keyFileInfo.setFile(currentpath.absoluteDir(), keyFile);
}
}

// Request to open the database file in the background with a password and keyfile
emit requestOpenDatabase(filepath.canonicalFilePath(), true, entry->password(), keyfile.canonicalFilePath());
}

// Request to open the database file in the background with a password and keyfile
emit requestOpenDatabase(dbFileInfo.canonicalFilePath(), inBackground, password, keyFileInfo.canonicalFilePath());
}
1 change: 1 addition & 0 deletions src/gui/DatabaseWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ private slots:
int addChildWidget(QWidget* w);
void setClipboardTextAndMinimize(const QString& text);
void processAutoOpen();
void openDatabaseFromEntry(const Entry* entry, bool inBackground = true);
bool confirmDeleteEntries(QList<Entry*> entries, bool permanent);
void performIconDownloads(const QList<Entry*>& entries, bool force = false);
Entry* currentSelectedEntry();
Expand Down

0 comments on commit f129768

Please sign in to comment.