From d42c66735e4f0a60ef168ad0f506e2b41c9b00b1 Mon Sep 17 00:00:00 2001 From: nowrep Date: Tue, 14 May 2013 22:45:20 +0200 Subject: [PATCH] [AutoFill] Rewritten preferences to support multiple backends. --- src/lib/autofill/autofill.cpp | 23 +++++- src/lib/autofill/autofill.h | 5 +- .../backends/databasepasswordbackend.cpp | 79 ++++++++++++------- .../backends/databasepasswordbackend.h | 4 + src/lib/autofill/backends/passwordbackend.h | 4 + src/lib/autofill/passwordmanager.cpp | 29 +++++++ src/lib/autofill/passwordmanager.h | 9 ++- src/lib/preferences/autofillmanager.cpp | 65 +++++++-------- 8 files changed, 149 insertions(+), 69 deletions(-) diff --git a/src/lib/autofill/autofill.cpp b/src/lib/autofill/autofill.cpp index 8b5849c09..d27e83b34 100644 --- a/src/lib/autofill/autofill.cpp +++ b/src/lib/autofill/autofill.cpp @@ -99,6 +99,11 @@ QVector AutoFill::getFormData(const QUrl &url) return m_manager->getEntries(url); } +QVector AutoFill::getAllFormData() +{ + return m_manager->getAllEntries(); +} + void AutoFill::updateLastUsed(const PasswordEntry &data) { m_manager->updateLastUsed(data); @@ -108,7 +113,7 @@ void AutoFill::updateLastUsed(const PasswordEntry &data) void AutoFill::addEntry(const QUrl &url, const QString &name, const QString &pass) { PasswordEntry entry; - entry.url = url; + entry.host = PasswordManager::createHost(url); entry.username = name; entry.password = pass; @@ -119,7 +124,7 @@ void AutoFill::addEntry(const QUrl &url, const QString &name, const QString &pas void AutoFill::addEntry(const QUrl &url, const PageFormData &formData) { PasswordEntry entry; - entry.url = url; + entry.host = PasswordManager::createHost(url); entry.username = formData.username; entry.password = formData.password; @@ -130,7 +135,7 @@ void AutoFill::addEntry(const QUrl &url, const PageFormData &formData) void AutoFill::updateEntry(const QUrl &url, const QString &name, const QString &pass) { PasswordEntry entry; - entry.url = url; + entry.host = PasswordManager::createHost(url); entry.username = name; entry.password = pass; @@ -143,6 +148,16 @@ void AutoFill::updateEntry(const PasswordEntry &entry) m_manager->updateEntry(entry); } +void AutoFill::removeEntry(const PasswordEntry &entry) +{ + m_manager->removeEntry(entry); +} + +void AutoFill::removeAllEntries() +{ + m_manager->removeAllEntries(); +} + // If password was filled in the page, returns all saved passwords on this page QVector AutoFill::completePage(WebPage* page) { @@ -204,7 +219,7 @@ void AutoFill::post(const QNetworkRequest &request, const QByteArray &outgoingDa return; } - PasswordEntry updateData = { -1, QUrl(), QString(), QString(), QByteArray() }; + PasswordEntry updateData = { -1, QString(), QString(), QString(), QByteArray() }; if (isStored(siteUrl)) { const QVector &list = getFormData(siteUrl); diff --git a/src/lib/autofill/autofill.h b/src/lib/autofill/autofill.h index 6ac429466..78ed02d11 100644 --- a/src/lib/autofill/autofill.h +++ b/src/lib/autofill/autofill.h @@ -19,7 +19,6 @@ #define AUTOFILLMODEL_H #include -#include #include "qz_namespace.h" @@ -45,6 +44,7 @@ public: void blockStoringforUrl(const QUrl &url); QVector getFormData(const QUrl &url); + QVector getAllFormData(); void updateLastUsed(const PasswordEntry &data); @@ -54,6 +54,9 @@ public: void updateEntry(const QUrl &url, const QString &name, const QString &pass); void updateEntry(const PasswordEntry &entry); + void removeEntry(const PasswordEntry &entry); + void removeAllEntries(); + void post(const QNetworkRequest &request, const QByteArray &outgoingData); QVector completePage(WebPage* page); diff --git a/src/lib/autofill/backends/databasepasswordbackend.cpp b/src/lib/autofill/backends/databasepasswordbackend.cpp index 0e1174d56..2de328e5c 100644 --- a/src/lib/autofill/backends/databasepasswordbackend.cpp +++ b/src/lib/autofill/backends/databasepasswordbackend.cpp @@ -28,28 +28,44 @@ DatabasePasswordBackend::DatabasePasswordBackend() QVector DatabasePasswordBackend::getEntries(const QUrl &url) { + const QString &host = PasswordManager::createHost(url); + + QSqlQuery query; + query.prepare("SELECT id, username, password, data FROM autofill " + "WHERE server=? ORDER BY last_used DESC"); + query.addBindValue(host); + query.exec(); + QVector list; - QString server = url.host(); - if (server.isEmpty()) { - server = url.toString(); + while (query.next()) { + PasswordEntry data; + data.id = query.value(0); + data.host = host; + data.username = query.value(1).toString(); + data.password = query.value(2).toString(); + data.data = query.value(3).toByteArray(); + + list.append(data); } - QString query = "SELECT id, username, password, data FROM autofill " - "WHERE server=? ORDER BY last_used DESC"; + return list; +} - QSqlQuery sqlQuery; - sqlQuery.prepare(query); - sqlQuery.addBindValue(server); - sqlQuery.exec(); +QVector DatabasePasswordBackend::getAllEntries() +{ + QVector list; + + QSqlQuery query; + query.exec("SELECT id, server, username, password, data FROM autofill"); - while (sqlQuery.next()) { + while (query.next()) { PasswordEntry data; - data.id = sqlQuery.value(0); - data.url = url; - data.username = sqlQuery.value(1).toString(); - data.password = sqlQuery.value(2).toString(); - data.data = sqlQuery.value(3).toByteArray(); + data.id = query.value(0); + data.host = query.value(1).toString(); + data.username = query.value(2).toString(); + data.password = query.value(3).toString(); + data.data = query.value(4).toByteArray(); list.append(data); } @@ -59,17 +75,12 @@ QVector DatabasePasswordBackend::getEntries(const QUrl &url) void DatabasePasswordBackend::addEntry(const PasswordEntry &entry) { - QString server = entry.url.host(); - if (server.isEmpty()) { - server = entry.url.toString(); - } - // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { // Multiple-usernames for HTTP/FTP authorization not supported QSqlQuery query; query.prepare("SELECT username FROM autofill WHERE server=?"); - query.addBindValue(server); + query.addBindValue(entry.host); query.exec(); if (query.next()) { @@ -80,7 +91,7 @@ void DatabasePasswordBackend::addEntry(const PasswordEntry &entry) QSqlQuery query; query.prepare("INSERT INTO autofill (server, data, username, password, last_used) " "VALUES (?,?,?,?,strftime('%s', 'now'))"); - query.bindValue(0, server); + query.bindValue(0, entry.host); query.bindValue(1, entry.data); query.bindValue(2, entry.username); query.bindValue(3, entry.password); @@ -94,15 +105,10 @@ void DatabasePasswordBackend::updateEntry(const PasswordEntry &entry) // Data is empty only for HTTP/FTP authorization if (entry.data.isEmpty()) { - QString server = entry.url.host(); - if (server.isEmpty()) { - server = entry.url.toString(); - } - query.prepare("UPDATE autofill SET username=?, password=? WHERE server=?"); query.bindValue(0, entry.username); query.bindValue(1, entry.password); - query.bindValue(2, server); + query.bindValue(2, entry.host); } else { query.prepare("UPDATE autofill SET data=?, username=?, password=? WHERE id=?"); @@ -123,3 +129,20 @@ void DatabasePasswordBackend::updateLastUsed(const PasswordEntry &entry) mApp->dbWriter()->executeQuery(query); } + +void DatabasePasswordBackend::removeEntry(const PasswordEntry &entry) +{ + QSqlQuery query; + query.prepare("DELETE FROM autofill WHERE id=?"); + query.addBindValue(entry.id); + + mApp->dbWriter()->executeQuery(query); +} + +void DatabasePasswordBackend::removeAll() +{ + QSqlQuery query; + query.prepare("DELETE FROM autofill"); + + mApp->dbWriter()->executeQuery(query); +} diff --git a/src/lib/autofill/backends/databasepasswordbackend.h b/src/lib/autofill/backends/databasepasswordbackend.h index 930bc724f..a6994cd7c 100644 --- a/src/lib/autofill/backends/databasepasswordbackend.h +++ b/src/lib/autofill/backends/databasepasswordbackend.h @@ -26,10 +26,14 @@ public: explicit DatabasePasswordBackend(); QVector getEntries(const QUrl &url); + QVector getAllEntries(); void addEntry(const PasswordEntry &entry); void updateEntry(const PasswordEntry &entry); void updateLastUsed(const PasswordEntry &entry); + + void removeEntry(const PasswordEntry &entry); + void removeAll(); }; #endif // DATABASEPASSWORDBACKEND_H diff --git a/src/lib/autofill/backends/passwordbackend.h b/src/lib/autofill/backends/passwordbackend.h index 766167a58..f4b990b9b 100644 --- a/src/lib/autofill/backends/passwordbackend.h +++ b/src/lib/autofill/backends/passwordbackend.h @@ -27,10 +27,14 @@ public: virtual ~PasswordBackend() { } virtual QVector getEntries(const QUrl &url) = 0; + virtual QVector getAllEntries() = 0; virtual void addEntry(const PasswordEntry &entry) = 0; virtual void updateEntry(const PasswordEntry &entry) = 0; virtual void updateLastUsed(const PasswordEntry &entry) = 0; + + virtual void removeEntry(const PasswordEntry &entry) = 0; + virtual void removeAll() = 0; }; #endif // PASSWORDBACKEND_H diff --git a/src/lib/autofill/passwordmanager.cpp b/src/lib/autofill/passwordmanager.cpp index fab351912..b4d8e6198 100644 --- a/src/lib/autofill/passwordmanager.cpp +++ b/src/lib/autofill/passwordmanager.cpp @@ -47,6 +47,12 @@ QVector PasswordManager::getEntries(const QUrl &url) return m_backend->getEntries(url); } +QVector PasswordManager::getAllEntries() +{ + ensureLoaded(); + return m_backend->getAllEntries(); +} + void PasswordManager::addEntry(const PasswordEntry &entry) { ensureLoaded(); @@ -65,6 +71,18 @@ void PasswordManager::updateLastUsed(const PasswordEntry &entry) m_backend->updateLastUsed(entry); } +void PasswordManager::removeEntry(const PasswordEntry &entry) +{ + ensureLoaded(); + m_backend->removeEntry(entry); +} + +void PasswordManager::removeAllEntries() +{ + ensureLoaded(); + m_backend->removeAll(); +} + bool PasswordManager::registerBackend(const QString &id, PasswordBackend* backend) { if (m_backends.contains(id)) { @@ -81,6 +99,17 @@ void PasswordManager::unregisterBackend(PasswordBackend* backend) m_backends.remove(key); } +QString PasswordManager::createHost(const QUrl &url) +{ + QString host = url.host(); + + if (host.isEmpty()) { + host = url.toString(); + } + + return host; +} + void PasswordManager::ensureLoaded() { if (!m_loaded) { diff --git a/src/lib/autofill/passwordmanager.h b/src/lib/autofill/passwordmanager.h index 2e66425f3..b74c461de 100644 --- a/src/lib/autofill/passwordmanager.h +++ b/src/lib/autofill/passwordmanager.h @@ -29,7 +29,7 @@ class DatabasePasswordBackend; struct PasswordEntry { QVariant id; - QUrl url; + QString host; QString username; QString password; QByteArray data; @@ -49,15 +49,20 @@ public: void loadSettings(); QVector getEntries(const QUrl &url); + QVector getAllEntries(); void addEntry(const PasswordEntry &entry); void updateEntry(const PasswordEntry &entry); void updateLastUsed(const PasswordEntry &entry); + void removeEntry(const PasswordEntry &entry); + void removeAllEntries(); bool registerBackend(const QString &id, PasswordBackend* backend); void unregisterBackend(PasswordBackend* backend); + static QString createHost(const QUrl &url); + private: void ensureLoaded(); @@ -71,4 +76,6 @@ private: // Hint to QVector to use std::realloc on item moving Q_DECLARE_TYPEINFO(PasswordEntry, Q_MOVABLE_TYPE); +Q_DECLARE_METATYPE(PasswordEntry) + #endif // PASSWORDMANAGER_H diff --git a/src/lib/preferences/autofillmanager.cpp b/src/lib/preferences/autofillmanager.cpp index c0349311d..f40d37789 100644 --- a/src/lib/preferences/autofillmanager.cpp +++ b/src/lib/preferences/autofillmanager.cpp @@ -17,6 +17,8 @@ * ============================================================ */ #include "autofillmanager.h" #include "autofill.h" +#include "passwordmanager.h" +#include "mainapplication.h" #include "ui_autofillmanager.h" #include @@ -58,20 +60,22 @@ void AutoFillManager::loadPasswords() ui->showPasswords->setText(tr("Show Passwords")); m_passwordsShown = false; - QSqlQuery query; - query.exec("SELECT server, username, password, id FROM autofill"); - ui->treePass->clear(); + QVector allEntries = mApp->autoFill()->getAllFormData(); - while (query.next()) { + ui->treePass->clear(); + foreach (const PasswordEntry &entry, allEntries) { QTreeWidgetItem* item = new QTreeWidgetItem(ui->treePass); - item->setText(0, query.value(0).toString()); - item->setText(1, query.value(1).toString()); + item->setText(0, entry.host); + item->setText(1, entry.username); item->setText(2, "*****"); - item->setData(0, Qt::UserRole + 10, query.value(3).toString()); - item->setData(0, Qt::UserRole + 11, query.value(2).toString()); + + QVariant v; + v.setValue(entry); + item->setData(0, Qt::UserRole + 10, v); ui->treePass->addTopLevelItem(item); } + QSqlQuery query; query.exec("SELECT server, id FROM autofill_exceptions"); ui->treeExcept->clear(); while (query.next()) { @@ -116,7 +120,7 @@ void AutoFillManager::showPasswords() continue; } - item->setText(2, item->data(0, Qt::UserRole + 11).toString()); + item->setText(2, item->data(0, Qt::UserRole + 10).value().password); } ui->showPasswords->setText(tr("Hide Passwords")); @@ -128,11 +132,9 @@ void AutoFillManager::removePass() if (!curItem) { return; } - QString id = curItem->data(0, Qt::UserRole + 10).toString(); - QSqlQuery query; - query.prepare("DELETE FROM autofill WHERE id=?"); - query.addBindValue(id); - query.exec(); + + PasswordEntry entry = curItem->data(0, Qt::UserRole + 10).value(); + mApp->autoFill()->removeEntry(entry); delete curItem; } @@ -145,9 +147,7 @@ void AutoFillManager::removeAllPass() return; } - QSqlQuery query; - query.exec("DELETE FROM autofill"); - + mApp->autoFill()->removeAllEntries(); ui->treePass->clear(); } @@ -157,31 +157,26 @@ void AutoFillManager::editPass() if (!curItem) { return; } + + PasswordEntry entry = curItem->data(0, Qt::UserRole + 10).value(); + bool ok; - QString text = QInputDialog::getText(this, tr("Edit password"), tr("Change password:"), QLineEdit::Normal, curItem->data(0, Qt::UserRole + 11).toString(), &ok); + QString text = QInputDialog::getText(this, tr("Edit password"), tr("Change password:"), QLineEdit::Normal, entry.password, &ok); if (ok && !text.isEmpty()) { - QSqlQuery query; - query.prepare("SELECT data, password FROM autofill WHERE id=?"); - query.addBindValue(curItem->data(0, Qt::UserRole + 10).toString()); - query.exec(); - query.next(); - - QByteArray data = query.value(0).toByteArray(); - QByteArray oldPass = "=" + QUrl::toPercentEncoding(query.value(1).toByteArray()); - data.replace(oldPass, "=" + QUrl::toPercentEncoding(text.toUtf8())); - - query.prepare("UPDATE autofill SET data=?, password=? WHERE id=?"); - query.bindValue(0, data); - query.bindValue(1, text); - query.bindValue(2, curItem->data(0, Qt::UserRole + 10).toString()); - query.exec(); + QByteArray oldPass = "=" + QUrl::toPercentEncoding(entry.password); + entry.data.replace(oldPass, "=" + QUrl::toPercentEncoding(text.toUtf8())); + entry.password = text; + + QVariant v; + v.setValue(entry); + curItem->setData(0, Qt::UserRole + 10, v); + + mApp->autoFill()->updateEntry(entry); if (m_passwordsShown) { curItem->setText(2, text); } - - curItem->setData(0, Qt::UserRole + 11, text); } }