mirror of
https://invent.kde.org/network/falkon.git
synced 2024-12-20 02:36:34 +01:00
[AutoFill] Rewritten password management to support multiple backends.
This commit is contained in:
parent
b9e6fdac4b
commit
bd315afe9e
@ -874,7 +874,7 @@ DownloadManager* MainApplication::downManager()
|
||||
AutoFill* MainApplication::autoFill()
|
||||
{
|
||||
if (!m_autofill) {
|
||||
m_autofill = new AutoFill(getWindow());
|
||||
m_autofill = new AutoFill(this);
|
||||
}
|
||||
return m_autofill;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "pageformcompleter.h"
|
||||
#include "databasewriter.h"
|
||||
#include "settings.h"
|
||||
#include "passwordmanager.h"
|
||||
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QXmlStreamReader>
|
||||
@ -35,9 +36,9 @@
|
||||
#include <QUrlQuery>
|
||||
#endif
|
||||
|
||||
AutoFill::AutoFill(QupZilla* mainClass, QObject* parent)
|
||||
AutoFill::AutoFill(QObject* parent)
|
||||
: QObject(parent)
|
||||
, p_QupZilla(mainClass)
|
||||
, m_manager(new PasswordManager(this))
|
||||
, m_isStoring(false)
|
||||
{
|
||||
loadSettings();
|
||||
@ -57,21 +58,7 @@ bool AutoFill::isStored(const QUrl &url)
|
||||
return false;
|
||||
}
|
||||
|
||||
QString server = url.host();
|
||||
if (server.isEmpty()) {
|
||||
server = url.toString();
|
||||
}
|
||||
|
||||
QSqlQuery query;
|
||||
query.prepare("SELECT count(id) FROM autofill WHERE server=?");
|
||||
query.addBindValue(server);
|
||||
query.exec();
|
||||
|
||||
query.next();
|
||||
if (query.value(0).toInt() > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return !m_manager->getEntries(url).isEmpty();
|
||||
}
|
||||
|
||||
bool AutoFill::isStoringEnabled(const QUrl &url)
|
||||
@ -89,12 +76,9 @@ bool AutoFill::isStoringEnabled(const QUrl &url)
|
||||
query.prepare("SELECT count(id) FROM autofill_exceptions WHERE server=?");
|
||||
query.addBindValue(server);
|
||||
query.exec();
|
||||
|
||||
query.next();
|
||||
if (query.value(0).toInt() > 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
return query.value(0).toInt() <= 0;
|
||||
}
|
||||
|
||||
void AutoFill::blockStoringforUrl(const QUrl &url)
|
||||
@ -110,155 +94,60 @@ void AutoFill::blockStoringforUrl(const QUrl &url)
|
||||
mApp->dbWriter()->executeQuery(query);
|
||||
}
|
||||
|
||||
AutoFillData AutoFill::getFirstFormData(const QUrl &url)
|
||||
QVector<PasswordEntry> AutoFill::getFormData(const QUrl &url)
|
||||
{
|
||||
const QVector<AutoFillData> &list = getFormData(url, 1);
|
||||
|
||||
if (list.isEmpty()) {
|
||||
AutoFillData data;
|
||||
data.id = -1;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return list.first();
|
||||
return m_manager->getEntries(url);
|
||||
}
|
||||
|
||||
QVector<AutoFillData> AutoFill::getFormData(const QUrl &url, int limit)
|
||||
void AutoFill::updateLastUsed(const PasswordEntry &data)
|
||||
{
|
||||
QVector<AutoFillData> list;
|
||||
|
||||
QString server = url.host();
|
||||
if (server.isEmpty()) {
|
||||
server = url.toString();
|
||||
}
|
||||
|
||||
QString queryString = "SELECT id, username, password, data FROM autofill "
|
||||
"WHERE server=? ORDER BY last_used DESC";
|
||||
if (limit > 0) {
|
||||
queryString.append(QLatin1String(" LIMIT ?"));
|
||||
}
|
||||
|
||||
QSqlQuery query;
|
||||
query.prepare(queryString);
|
||||
query.addBindValue(server);
|
||||
|
||||
if (limit > 0) {
|
||||
query.addBindValue(limit);
|
||||
}
|
||||
|
||||
query.exec();
|
||||
|
||||
while (query.next()) {
|
||||
AutoFillData data;
|
||||
data.id = query.value(0).toInt();
|
||||
data.username = query.value(1).toString();
|
||||
data.password = query.value(2).toString();
|
||||
data.postData = query.value(3).toByteArray();
|
||||
|
||||
list.append(data);
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
m_manager->updateLastUsed(data);
|
||||
}
|
||||
|
||||
void AutoFill::updateLastUsed(int id)
|
||||
{
|
||||
if (id < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
QSqlQuery query;
|
||||
query.prepare("UPDATE autofill SET last_used=strftime('%s', 'now') WHERE id=?");
|
||||
query.addBindValue(id);
|
||||
query.exec();
|
||||
}
|
||||
|
||||
///HTTP Authorization
|
||||
// HTTP Authorization
|
||||
void AutoFill::addEntry(const QUrl &url, const QString &name, const QString &pass)
|
||||
{
|
||||
QSqlQuery query;
|
||||
QString server = url.host();
|
||||
if (server.isEmpty()) {
|
||||
server = url.toString();
|
||||
}
|
||||
PasswordEntry entry;
|
||||
entry.url = url;
|
||||
entry.username = name;
|
||||
entry.password = pass;
|
||||
|
||||
// Multiple-usernames for HTTP Authorization not supported
|
||||
query.prepare("SELECT username FROM autofill WHERE server=?");
|
||||
query.addBindValue(server);
|
||||
query.exec();
|
||||
|
||||
if (query.next()) {
|
||||
return;
|
||||
}
|
||||
|
||||
query.prepare("INSERT INTO autofill (server, username, password, last_used) "
|
||||
"VALUES (?,?,?,strftime('%s', 'now'))");
|
||||
query.bindValue(0, server);
|
||||
query.bindValue(1, name);
|
||||
query.bindValue(2, pass);
|
||||
mApp->dbWriter()->executeQuery(query);
|
||||
m_manager->addEntry(entry);
|
||||
}
|
||||
|
||||
///WEB Form
|
||||
// WEB Form
|
||||
void AutoFill::addEntry(const QUrl &url, const PageFormData &formData)
|
||||
{
|
||||
QString server = url.host();
|
||||
if (server.isEmpty()) {
|
||||
server = url.toString();
|
||||
}
|
||||
PasswordEntry entry;
|
||||
entry.url = url;
|
||||
entry.username = formData.username;
|
||||
entry.password = formData.password;
|
||||
|
||||
QSqlQuery query;
|
||||
query.prepare("INSERT INTO autofill (server, data, username, password, last_used) "
|
||||
"VALUES (?,?,?,?,strftime('%s', 'now'))");
|
||||
query.bindValue(0, server);
|
||||
query.bindValue(1, formData.postData);
|
||||
query.bindValue(2, formData.username);
|
||||
query.bindValue(3, formData.password);
|
||||
mApp->dbWriter()->executeQuery(query);
|
||||
m_manager->addEntry(entry);
|
||||
}
|
||||
|
||||
// HTTP Authorization
|
||||
void AutoFill::updateEntry(const QUrl &url, const QString &name, const QString &pass)
|
||||
{
|
||||
QSqlQuery query;
|
||||
QString server = url.host();
|
||||
if (server.isEmpty()) {
|
||||
server = url.toString();
|
||||
}
|
||||
PasswordEntry entry;
|
||||
entry.url = url;
|
||||
entry.username = name;
|
||||
entry.password = pass;
|
||||
|
||||
query.prepare("SELECT username FROM autofill WHERE server=?");
|
||||
query.addBindValue(server);
|
||||
query.exec();
|
||||
|
||||
if (!query.next()) {
|
||||
return;
|
||||
}
|
||||
|
||||
query.prepare("UPDATE autofill SET username=?, password=? WHERE server=?");
|
||||
query.bindValue(0, name);
|
||||
query.bindValue(1, pass);
|
||||
query.bindValue(2, server);
|
||||
mApp->dbWriter()->executeQuery(query);
|
||||
m_manager->updateEntry(entry);
|
||||
}
|
||||
|
||||
void AutoFill::updateEntry(const PageFormData &formData, const AutoFillData &updateData)
|
||||
// WEB Form
|
||||
void AutoFill::updateEntry(const PasswordEntry &entry)
|
||||
{
|
||||
QSqlQuery query;
|
||||
query.prepare("UPDATE autofill SET data=?, username=?, password=? WHERE id=?");
|
||||
query.addBindValue(formData.postData);
|
||||
query.addBindValue(formData.username);
|
||||
query.addBindValue(formData.password);
|
||||
query.addBindValue(updateData.id);
|
||||
|
||||
mApp->dbWriter()->executeQuery(query);
|
||||
m_manager->updateEntry(entry);
|
||||
}
|
||||
|
||||
// If password was filled in the page, returns all saved passwords on this page
|
||||
QVector<AutoFillData> AutoFill::completePage(WebPage* page)
|
||||
QVector<PasswordEntry> AutoFill::completePage(WebPage* page)
|
||||
{
|
||||
bool completed = false;
|
||||
QVector<AutoFillData> list;
|
||||
QVector<PasswordEntry> list;
|
||||
|
||||
if (!page) {
|
||||
return list;
|
||||
@ -272,10 +161,10 @@ QVector<AutoFillData> AutoFill::completePage(WebPage* page)
|
||||
list = getFormData(pageUrl);
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
const AutoFillData data = getFirstFormData(pageUrl);
|
||||
const PasswordEntry entry = list.first();
|
||||
|
||||
PageFormCompleter completer(page);
|
||||
completed = completer.completePage(data.postData);
|
||||
completed = completer.completePage(entry.data);
|
||||
}
|
||||
|
||||
if (!completed) {
|
||||
@ -311,24 +200,27 @@ void AutoFill::post(const QNetworkRequest &request, const QByteArray &outgoingDa
|
||||
PageFormCompleter completer(webPage);
|
||||
const PageFormData formData = completer.extractFormData(outgoingData);
|
||||
|
||||
if (!formData.found) {
|
||||
if (!formData.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoFillData updateData = { -1, QString(), QString(), QByteArray() };
|
||||
PasswordEntry updateData = { -1, QUrl(), QString(), QString(), QByteArray() };
|
||||
|
||||
if (isStored(siteUrl)) {
|
||||
const QVector<AutoFillData> &list = getFormData(siteUrl);
|
||||
const QVector<PasswordEntry> &list = getFormData(siteUrl);
|
||||
|
||||
foreach (const AutoFillData &data, list) {
|
||||
foreach (const PasswordEntry &data, list) {
|
||||
if (data.username == formData.username) {
|
||||
updateLastUsed(data.id);
|
||||
updateLastUsed(data);
|
||||
|
||||
if (data.password == formData.password) {
|
||||
return;
|
||||
}
|
||||
|
||||
updateData = data;
|
||||
updateData.username = formData.username;
|
||||
updateData.password = formData.password;
|
||||
updateData.data = formData.postData;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -29,23 +29,14 @@ class QNetworkRequest;
|
||||
|
||||
class QupZilla;
|
||||
class WebPage;
|
||||
class PasswordManager;
|
||||
struct PageFormData;
|
||||
|
||||
struct AutoFillData {
|
||||
int id;
|
||||
QString username;
|
||||
QString password;
|
||||
QByteArray postData;
|
||||
|
||||
bool isValid() const {
|
||||
return id > -1;
|
||||
}
|
||||
};
|
||||
struct PasswordEntry;
|
||||
|
||||
class QT_QUPZILLA_EXPORT AutoFill : public QObject
|
||||
{
|
||||
public:
|
||||
explicit AutoFill(QupZilla* mainClass, QObject* parent = 0);
|
||||
explicit AutoFill(QObject* parent = 0);
|
||||
|
||||
void loadSettings();
|
||||
|
||||
@ -53,30 +44,26 @@ public:
|
||||
bool isStoringEnabled(const QUrl &url);
|
||||
void blockStoringforUrl(const QUrl &url);
|
||||
|
||||
AutoFillData getFirstFormData(const QUrl &url);
|
||||
QVector<AutoFillData> getFormData(const QUrl &url, int limit = 0);
|
||||
QVector<PasswordEntry> getFormData(const QUrl &url);
|
||||
|
||||
void updateLastUsed(int id);
|
||||
void updateLastUsed(const PasswordEntry &data);
|
||||
|
||||
void addEntry(const QUrl &url, const QString &name, const QString &pass);
|
||||
void addEntry(const QUrl &url, const PageFormData &formData);
|
||||
|
||||
void updateEntry(const QUrl &url, const QString &name, const QString &pass);
|
||||
void updateEntry(const PageFormData &formData, const AutoFillData &updateData);
|
||||
void updateEntry(const PasswordEntry &entry);
|
||||
|
||||
void post(const QNetworkRequest &request, const QByteArray &outgoingData);
|
||||
QVector<AutoFillData> completePage(WebPage* page);
|
||||
QVector<PasswordEntry> completePage(WebPage* page);
|
||||
|
||||
static QByteArray exportPasswords();
|
||||
static bool importPasswords(const QByteArray &data);
|
||||
|
||||
private:
|
||||
QupZilla* p_QupZilla;
|
||||
PasswordManager* m_manager;
|
||||
bool m_isStoring;
|
||||
|
||||
};
|
||||
|
||||
// Hint to QVector to use std::realloc on item moving
|
||||
Q_DECLARE_TYPEINFO(AutoFillData, Q_MOVABLE_TYPE);
|
||||
|
||||
#endif // AUTOFILLMODEL_H
|
||||
|
@ -37,7 +37,7 @@ void AutoFillIcon::setWebView(WebView* view)
|
||||
m_view = view;
|
||||
}
|
||||
|
||||
void AutoFillIcon::setFormData(const QVector<AutoFillData> &data)
|
||||
void AutoFillIcon::setFormData(const QVector<PasswordEntry> &data)
|
||||
{
|
||||
m_data = data;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "qz_namespace.h"
|
||||
#include "clickablelabel.h"
|
||||
#include "autofill.h"
|
||||
#include "passwordmanager.h"
|
||||
|
||||
class WebView;
|
||||
|
||||
@ -32,7 +32,7 @@ public:
|
||||
explicit AutoFillIcon(QWidget* parent = 0);
|
||||
|
||||
void setWebView(WebView* view);
|
||||
void setFormData(const QVector<AutoFillData> &data);
|
||||
void setFormData(const QVector<PasswordEntry> &data);
|
||||
|
||||
private slots:
|
||||
void iconClicked();
|
||||
@ -43,7 +43,7 @@ private:
|
||||
|
||||
WebView* m_view;
|
||||
|
||||
QVector<AutoFillData> m_data;
|
||||
QVector<PasswordEntry> m_data;
|
||||
|
||||
};
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include "animatedwidget.h"
|
||||
#include "iconprovider.h"
|
||||
|
||||
AutoFillNotification::AutoFillNotification(const QUrl &url, const PageFormData &formData, const AutoFillData &updateData)
|
||||
AutoFillNotification::AutoFillNotification(const QUrl &url, const PageFormData &formData, const PasswordEntry &updateData)
|
||||
: AnimatedWidget(AnimatedWidget::Down, 300, 0)
|
||||
, ui(new Ui::AutoFillNotification)
|
||||
, m_url(url)
|
||||
@ -68,7 +68,7 @@ AutoFillNotification::AutoFillNotification(const QUrl &url, const PageFormData &
|
||||
|
||||
void AutoFillNotification::update()
|
||||
{
|
||||
mApp->autoFill()->updateEntry(m_formData, m_updateData);
|
||||
mApp->autoFill()->updateEntry(m_updateData);
|
||||
hide();
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "qz_namespace.h"
|
||||
#include "animatedwidget.h"
|
||||
#include "pageformcompleter.h"
|
||||
#include "passwordmanager.h"
|
||||
#include "autofill.h"
|
||||
|
||||
namespace Ui
|
||||
@ -39,7 +40,7 @@ class QT_QUPZILLA_EXPORT AutoFillNotification : public AnimatedWidget
|
||||
public:
|
||||
explicit AutoFillNotification(const QUrl &url,
|
||||
const PageFormData &formData,
|
||||
const AutoFillData &updateData);
|
||||
const PasswordEntry &updateData);
|
||||
~AutoFillNotification();
|
||||
|
||||
private slots:
|
||||
@ -52,7 +53,7 @@ private:
|
||||
|
||||
QUrl m_url;
|
||||
PageFormData m_formData;
|
||||
AutoFillData m_updateData;
|
||||
PasswordEntry m_updateData;
|
||||
};
|
||||
|
||||
#endif // AUTOFILLNOTIFICATION_H
|
||||
|
@ -33,12 +33,12 @@ AutoFillWidget::AutoFillWidget(WebView* view, QWidget* parent)
|
||||
ui->setupUi(this);
|
||||
}
|
||||
|
||||
void AutoFillWidget::setFormData(const QVector<AutoFillData> &data)
|
||||
void AutoFillWidget::setFormData(const QVector<PasswordEntry> &data)
|
||||
{
|
||||
m_data = data;
|
||||
|
||||
for (int i = 0; i < data.count(); ++i) {
|
||||
const AutoFillData d = data.at(i);
|
||||
const PasswordEntry d = data.at(i);
|
||||
if (d.username.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
@ -67,10 +67,10 @@ void AutoFillWidget::loginToPage()
|
||||
int index = button->property("data-index").toInt(&ok);
|
||||
|
||||
if (ok && QzTools::vectorContainsIndex(m_data, index)) {
|
||||
const AutoFillData data = m_data.at(index);
|
||||
const PasswordEntry entry = m_data.at(index);
|
||||
|
||||
PageFormCompleter completer(m_view->page());
|
||||
completer.completePage(data.postData);
|
||||
completer.completePage(entry.data);
|
||||
}
|
||||
|
||||
close();
|
||||
|
@ -30,7 +30,7 @@ class AutoFillWidget;
|
||||
}
|
||||
|
||||
class WebView;
|
||||
struct AutoFillData;
|
||||
struct PasswordEntry;
|
||||
|
||||
class QT_QUPZILLA_EXPORT AutoFillWidget : public LocationBarPopup
|
||||
{
|
||||
@ -40,7 +40,7 @@ public:
|
||||
explicit AutoFillWidget(WebView* view, QWidget* parent = 0);
|
||||
~AutoFillWidget();
|
||||
|
||||
void setFormData(const QVector<AutoFillData> &data);
|
||||
void setFormData(const QVector<PasswordEntry> &data);
|
||||
|
||||
private slots:
|
||||
void loginToPage();
|
||||
@ -49,7 +49,7 @@ private:
|
||||
Ui::AutoFillWidget* ui;
|
||||
|
||||
WebView* m_view;
|
||||
QVector<AutoFillData> m_data;
|
||||
QVector<PasswordEntry> m_data;
|
||||
};
|
||||
|
||||
#endif // AUTOFILLWIDGET_H
|
||||
|
125
src/lib/autofill/backends/databasepasswordbackend.cpp
Normal file
125
src/lib/autofill/backends/databasepasswordbackend.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "databasepasswordbackend.h"
|
||||
#include "mainapplication.h"
|
||||
#include "databasewriter.h"
|
||||
|
||||
#include <QVector>
|
||||
#include <QSqlQuery>
|
||||
|
||||
DatabasePasswordBackend::DatabasePasswordBackend()
|
||||
{
|
||||
}
|
||||
|
||||
QVector<PasswordEntry> DatabasePasswordBackend::getEntries(const QUrl &url)
|
||||
{
|
||||
QVector<PasswordEntry> list;
|
||||
|
||||
QString server = url.host();
|
||||
if (server.isEmpty()) {
|
||||
server = url.toString();
|
||||
}
|
||||
|
||||
QString query = "SELECT id, username, password, data FROM autofill "
|
||||
"WHERE server=? ORDER BY last_used DESC";
|
||||
|
||||
QSqlQuery sqlQuery;
|
||||
sqlQuery.prepare(query);
|
||||
sqlQuery.addBindValue(server);
|
||||
sqlQuery.exec();
|
||||
|
||||
while (sqlQuery.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();
|
||||
|
||||
list.append(data);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
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.exec();
|
||||
|
||||
if (query.next()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QSqlQuery query;
|
||||
query.prepare("INSERT INTO autofill (server, data, username, password, last_used) "
|
||||
"VALUES (?,?,?,?,strftime('%s', 'now'))");
|
||||
query.bindValue(0, server);
|
||||
query.bindValue(1, entry.data);
|
||||
query.bindValue(2, entry.username);
|
||||
query.bindValue(3, entry.password);
|
||||
|
||||
mApp->dbWriter()->executeQuery(query);
|
||||
}
|
||||
|
||||
void DatabasePasswordBackend::updateEntry(const PasswordEntry &entry)
|
||||
{
|
||||
QSqlQuery query;
|
||||
|
||||
// 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);
|
||||
}
|
||||
else {
|
||||
query.prepare("UPDATE autofill SET data=?, username=?, password=? WHERE id=?");
|
||||
query.addBindValue(entry.data);
|
||||
query.addBindValue(entry.username);
|
||||
query.addBindValue(entry.password);
|
||||
query.addBindValue(entry.id);
|
||||
}
|
||||
|
||||
mApp->dbWriter()->executeQuery(query);
|
||||
}
|
||||
|
||||
void DatabasePasswordBackend::updateLastUsed(const PasswordEntry &entry)
|
||||
{
|
||||
QSqlQuery query;
|
||||
query.prepare("UPDATE autofill SET last_used=strftime('%s', 'now') WHERE id=?");
|
||||
query.addBindValue(entry.id);
|
||||
|
||||
mApp->dbWriter()->executeQuery(query);
|
||||
}
|
35
src/lib/autofill/backends/databasepasswordbackend.h
Normal file
35
src/lib/autofill/backends/databasepasswordbackend.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef DATABASEPASSWORDBACKEND_H
|
||||
#define DATABASEPASSWORDBACKEND_H
|
||||
|
||||
#include "passwordbackend.h"
|
||||
|
||||
class DatabasePasswordBackend : public PasswordBackend
|
||||
{
|
||||
public:
|
||||
explicit DatabasePasswordBackend();
|
||||
|
||||
QVector<PasswordEntry> getEntries(const QUrl &url);
|
||||
|
||||
void addEntry(const PasswordEntry &entry);
|
||||
void updateEntry(const PasswordEntry &entry);
|
||||
void updateLastUsed(const PasswordEntry &entry);
|
||||
};
|
||||
|
||||
#endif // DATABASEPASSWORDBACKEND_H
|
36
src/lib/autofill/backends/passwordbackend.h
Normal file
36
src/lib/autofill/backends/passwordbackend.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef PASSWORDBACKEND_H
|
||||
#define PASSWORDBACKEND_H
|
||||
|
||||
#include "passwordmanager.h"
|
||||
|
||||
class PasswordBackend
|
||||
{
|
||||
public:
|
||||
explicit PasswordBackend() { }
|
||||
virtual ~PasswordBackend() { }
|
||||
|
||||
virtual QVector<PasswordEntry> getEntries(const QUrl &url) = 0;
|
||||
|
||||
virtual void addEntry(const PasswordEntry &entry) = 0;
|
||||
virtual void updateEntry(const PasswordEntry &entry) = 0;
|
||||
virtual void updateLastUsed(const PasswordEntry &entry) = 0;
|
||||
};
|
||||
|
||||
#endif // PASSWORDBACKEND_H
|
@ -37,7 +37,7 @@ PageFormData PageFormCompleter::extractFormData(const QByteArray &postData) cons
|
||||
QString passwordValue;
|
||||
|
||||
QByteArray data = convertWebKitFormBoundaryIfNecessary(postData);
|
||||
PageFormData formData = {false, QString(), QString(), data};
|
||||
PageFormData formData = {QString(), QString(), data};
|
||||
|
||||
if (data.isEmpty() || !data.contains('=')) {
|
||||
return formData;
|
||||
@ -83,7 +83,6 @@ PageFormData PageFormCompleter::extractFormData(const QByteArray &postData) cons
|
||||
return formData;
|
||||
}
|
||||
|
||||
formData.found = true;
|
||||
formData.username = usernameValue;
|
||||
formData.password = passwordValue;
|
||||
|
||||
|
@ -29,10 +29,13 @@ class QWebElement;
|
||||
class QWebElementCollection;
|
||||
|
||||
struct PageFormData {
|
||||
bool found;
|
||||
QString username;
|
||||
QString password;
|
||||
QByteArray postData;
|
||||
|
||||
bool isValid() const {
|
||||
return !password.isEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
class PageFormCompleter
|
||||
|
95
src/lib/autofill/passwordmanager.cpp
Normal file
95
src/lib/autofill/passwordmanager.cpp
Normal file
@ -0,0 +1,95 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#include "passwordmanager.h"
|
||||
#include "backends/passwordbackend.h"
|
||||
#include "backends/databasepasswordbackend.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QVector>
|
||||
|
||||
PasswordManager::PasswordManager(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_backend(0)
|
||||
, m_loaded(false)
|
||||
, m_databaseBackend(new DatabasePasswordBackend)
|
||||
{
|
||||
m_backends["database"] = m_databaseBackend;
|
||||
}
|
||||
|
||||
void PasswordManager::loadSettings()
|
||||
{
|
||||
Settings settings;
|
||||
settings.beginGroup("PasswordManager");
|
||||
QString backendId = settings.value("Backend", "database").toString();
|
||||
settings.endGroup();
|
||||
|
||||
m_backend = m_backends[m_backends.contains(backendId) ? backendId : "database"];
|
||||
}
|
||||
|
||||
QVector<PasswordEntry> PasswordManager::getEntries(const QUrl &url)
|
||||
{
|
||||
ensureLoaded();
|
||||
return m_backend->getEntries(url);
|
||||
}
|
||||
|
||||
void PasswordManager::addEntry(const PasswordEntry &entry)
|
||||
{
|
||||
ensureLoaded();
|
||||
m_backend->addEntry(entry);
|
||||
}
|
||||
|
||||
void PasswordManager::updateEntry(const PasswordEntry &entry)
|
||||
{
|
||||
ensureLoaded();
|
||||
m_backend->updateEntry(entry);
|
||||
}
|
||||
|
||||
void PasswordManager::updateLastUsed(const PasswordEntry &entry)
|
||||
{
|
||||
ensureLoaded();
|
||||
m_backend->updateLastUsed(entry);
|
||||
}
|
||||
|
||||
bool PasswordManager::registerBackend(const QString &id, PasswordBackend* backend)
|
||||
{
|
||||
if (m_backends.contains(id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_backends[id] = backend;
|
||||
return true;
|
||||
}
|
||||
|
||||
void PasswordManager::unregisterBackend(PasswordBackend* backend)
|
||||
{
|
||||
const QString &key = m_backends.key(backend);
|
||||
m_backends.remove(key);
|
||||
}
|
||||
|
||||
void PasswordManager::ensureLoaded()
|
||||
{
|
||||
if (!m_loaded) {
|
||||
loadSettings();
|
||||
m_loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
PasswordManager::~PasswordManager()
|
||||
{
|
||||
delete m_databaseBackend;
|
||||
}
|
74
src/lib/autofill/passwordmanager.h
Normal file
74
src/lib/autofill/passwordmanager.h
Normal file
@ -0,0 +1,74 @@
|
||||
/* ============================================================
|
||||
* QupZilla - WebKit based browser
|
||||
* Copyright (C) 2013 David Rosca <nowrep@gmail.com>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */
|
||||
#ifndef PASSWORDMANAGER_H
|
||||
#define PASSWORDMANAGER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include <QVariant>
|
||||
|
||||
#include "qz_namespace.h"
|
||||
|
||||
class PasswordBackend;
|
||||
class DatabasePasswordBackend;
|
||||
|
||||
struct PasswordEntry {
|
||||
QVariant id;
|
||||
QUrl url;
|
||||
QString username;
|
||||
QString password;
|
||||
QByteArray data;
|
||||
|
||||
bool isValid() const {
|
||||
return !password.isEmpty();
|
||||
}
|
||||
};
|
||||
|
||||
class QT_QUPZILLA_EXPORT PasswordManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PasswordManager(QObject* parent = 0);
|
||||
~PasswordManager();
|
||||
|
||||
void loadSettings();
|
||||
|
||||
QVector<PasswordEntry> getEntries(const QUrl &url);
|
||||
|
||||
void addEntry(const PasswordEntry &entry);
|
||||
void updateEntry(const PasswordEntry &entry);
|
||||
void updateLastUsed(const PasswordEntry &entry);
|
||||
|
||||
|
||||
bool registerBackend(const QString &id, PasswordBackend* backend);
|
||||
void unregisterBackend(PasswordBackend* backend);
|
||||
|
||||
private:
|
||||
void ensureLoaded();
|
||||
|
||||
PasswordBackend* m_backend;
|
||||
bool m_loaded;
|
||||
|
||||
DatabasePasswordBackend* m_databaseBackend;
|
||||
QHash<QString, PasswordBackend*> m_backends;
|
||||
};
|
||||
|
||||
// Hint to QVector to use std::realloc on item moving
|
||||
Q_DECLARE_TYPEINFO(PasswordEntry, Q_MOVABLE_TYPE);
|
||||
|
||||
#endif // PASSWORDMANAGER_H
|
@ -215,7 +215,9 @@ SOURCES += \
|
||||
tools/actioncopy.cpp \
|
||||
network/pac/proxyautoconfig.cpp \
|
||||
network/pac/pacmanager.cpp \
|
||||
tools/delayedfilewatcher.cpp
|
||||
tools/delayedfilewatcher.cpp \
|
||||
autofill/passwordmanager.cpp \
|
||||
autofill/backends/databasepasswordbackend.cpp
|
||||
|
||||
HEADERS += \
|
||||
webview/tabpreview.h \
|
||||
@ -391,7 +393,10 @@ HEADERS += \
|
||||
network/pac/proxyautoconfig.h \
|
||||
network/pac/pacmanager.h \
|
||||
network/pac/pacdatetime.h \
|
||||
tools/delayedfilewatcher.h
|
||||
tools/delayedfilewatcher.h \
|
||||
autofill/passwordmanager.h \
|
||||
autofill/backends/passwordbackend.h \
|
||||
autofill/backends/databasepasswordbackend.h
|
||||
|
||||
FORMS += \
|
||||
preferences/autofillmanager.ui \
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "acceptlanguage.h"
|
||||
#include "cabundleupdater.h"
|
||||
#include "settings.h"
|
||||
#include "passwordmanager.h"
|
||||
#include "schemehandlers/adblockschemehandler.h"
|
||||
#include "schemehandlers/qupzillaschemehandler.h"
|
||||
#include "schemehandlers/fileschemehandler.h"
|
||||
@ -291,13 +292,13 @@ void NetworkManager::authentication(QNetworkReply* reply, QAuthenticator* auth)
|
||||
QString storedUser;
|
||||
QString storedPassword;
|
||||
if (fill->isStored(reply->url())) {
|
||||
const AutoFillData &data = fill->getFirstFormData(reply->url());
|
||||
const QVector<PasswordEntry> &data = fill->getFormData(reply->url());
|
||||
|
||||
if (data.isValid()) {
|
||||
if (!data.isEmpty()) {
|
||||
save->setChecked(true);
|
||||
shouldUpdateEntry = true;
|
||||
storedUser = data.username;
|
||||
storedPassword = data.password;
|
||||
storedUser = data.first().username;
|
||||
storedPassword = data.first().password;
|
||||
user->setText(storedUser);
|
||||
pass->setText(storedPassword);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "widget.h"
|
||||
#include "qztools.h"
|
||||
#include "speeddial.h"
|
||||
#include "autofill.h"
|
||||
#include "popupwebpage.h"
|
||||
#include "popupwebview.h"
|
||||
#include "networkmanagerproxy.h"
|
||||
@ -254,7 +255,7 @@ void WebPage::finished()
|
||||
}
|
||||
|
||||
// Autofill
|
||||
m_autoFillData = mApp->autoFill()->completePage(this);
|
||||
m_passwordEntries = mApp->autoFill()->completePage(this);
|
||||
|
||||
// AdBlock
|
||||
cleanBlockedObjects();
|
||||
@ -593,12 +594,12 @@ QVector<WebPage::AdBlockedEntry> WebPage::adBlockedEntries() const
|
||||
|
||||
bool WebPage::hasMultipleUsernames() const
|
||||
{
|
||||
return m_autoFillData.count() > 1;
|
||||
return m_passwordEntries.count() > 1;
|
||||
}
|
||||
|
||||
QVector<AutoFillData> WebPage::autoFillData() const
|
||||
QVector<PasswordEntry> WebPage::autoFillData() const
|
||||
{
|
||||
return m_autoFillData;
|
||||
return m_passwordEntries;
|
||||
}
|
||||
|
||||
void WebPage::cleanBlockedObjects()
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <QVector>
|
||||
|
||||
#include "qz_namespace.h"
|
||||
#include "autofill.h"
|
||||
#include "passwordmanager.h"
|
||||
|
||||
class QWebSecurityOrigin;
|
||||
class QEventLoop;
|
||||
@ -67,7 +67,7 @@ public:
|
||||
QVector<AdBlockedEntry> adBlockedEntries() const;
|
||||
|
||||
bool hasMultipleUsernames() const;
|
||||
QVector<AutoFillData> autoFillData() const;
|
||||
QVector<PasswordEntry> autoFillData() const;
|
||||
|
||||
void scheduleAdjustPage();
|
||||
bool isRunningLoop();
|
||||
@ -138,7 +138,7 @@ private:
|
||||
QSslCertificate m_sslCert;
|
||||
QVector<QSslCertificate> m_rejectedSslCerts;
|
||||
QVector<AdBlockedEntry> m_adBlockedEntries;
|
||||
QVector<AutoFillData> m_autoFillData;
|
||||
QVector<PasswordEntry> m_passwordEntries;
|
||||
|
||||
QWebPage::NavigationType m_lastRequestType;
|
||||
QUrl m_lastRequestUrl;
|
||||
|
Loading…
Reference in New Issue
Block a user