1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 02:36:34 +01:00

[AutoFill] Rewritten preferences to support multiple backends.

This commit is contained in:
nowrep 2013-05-14 22:45:20 +02:00
parent bd315afe9e
commit d42c66735e
8 changed files with 147 additions and 67 deletions

View File

@ -99,6 +99,11 @@ QVector<PasswordEntry> AutoFill::getFormData(const QUrl &url)
return m_manager->getEntries(url);
}
QVector<PasswordEntry> 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<PasswordEntry> 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<PasswordEntry> &list = getFormData(siteUrl);

View File

@ -19,7 +19,6 @@
#define AUTOFILLMODEL_H
#include <QObject>
#include <QList>
#include "qz_namespace.h"
@ -45,6 +44,7 @@ public:
void blockStoringforUrl(const QUrl &url);
QVector<PasswordEntry> getFormData(const QUrl &url);
QVector<PasswordEntry> 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<PasswordEntry> completePage(WebPage* page);

View File

@ -28,28 +28,44 @@ DatabasePasswordBackend::DatabasePasswordBackend()
QVector<PasswordEntry> 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<PasswordEntry> 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<PasswordEntry> DatabasePasswordBackend::getAllEntries()
{
QVector<PasswordEntry> list;
while (sqlQuery.next()) {
QSqlQuery query;
query.exec("SELECT id, server, username, password, data FROM autofill");
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<PasswordEntry> 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);
}

View File

@ -26,10 +26,14 @@ public:
explicit DatabasePasswordBackend();
QVector<PasswordEntry> getEntries(const QUrl &url);
QVector<PasswordEntry> 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

View File

@ -27,10 +27,14 @@ public:
virtual ~PasswordBackend() { }
virtual QVector<PasswordEntry> getEntries(const QUrl &url) = 0;
virtual QVector<PasswordEntry> 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

View File

@ -47,6 +47,12 @@ QVector<PasswordEntry> PasswordManager::getEntries(const QUrl &url)
return m_backend->getEntries(url);
}
QVector<PasswordEntry> 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) {

View File

@ -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<PasswordEntry> getEntries(const QUrl &url);
QVector<PasswordEntry> 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

View File

@ -17,6 +17,8 @@
* ============================================================ */
#include "autofillmanager.h"
#include "autofill.h"
#include "passwordmanager.h"
#include "mainapplication.h"
#include "ui_autofillmanager.h"
#include <QMenu>
@ -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<PasswordEntry> 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<PasswordEntry>(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<PasswordEntry>().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<PasswordEntry>();
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<PasswordEntry>();
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 oldPass = "=" + QUrl::toPercentEncoding(entry.password);
entry.data.replace(oldPass, "=" + QUrl::toPercentEncoding(text.toUtf8()));
entry.password = text;
QByteArray data = query.value(0).toByteArray();
QByteArray oldPass = "=" + QUrl::toPercentEncoding(query.value(1).toByteArray());
data.replace(oldPass, "=" + QUrl::toPercentEncoding(text.toUtf8()));
QVariant v;
v.setValue<PasswordEntry>(entry);
curItem->setData(0, Qt::UserRole + 10, v);
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();
mApp->autoFill()->updateEntry(entry);
if (m_passwordsShown) {
curItem->setText(2, text);
}
curItem->setData(0, Qt::UserRole + 11, text);
}
}