Skip to content

Commit

Permalink
Simple Password Management / AutoFill
Browse files Browse the repository at this point in the history
Issue: 119

AutoFillManager
A basic form manager that will store form element information when a
 post is made.  When it gets a post it will attempt to determine which
 form on the webpage the data came from and if it can will remember the
 data so that next time the page is loaded it can load the data into
 that page.

AutoFillManagerDialog
A front end to AutoFillManager it is a simple dialog with filtering
and the ability to show form data from passwords or not
  • Loading branch information
icefox committed Sep 24, 2009
1 parent 68c9eaf commit e2070e9
Show file tree
Hide file tree
Showing 16 changed files with 1,059 additions and 0 deletions.
191 changes: 191 additions & 0 deletions src/autofilldialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/**
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Benjamin Meyer nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#include "autofilldialog.h"

#include "autofillmanager.h"
#include "browserapplication.h"

#include <qdebug.h>

AutoFillPasswordProxyModel::AutoFillPasswordProxyModel(bool showPasswords, QObject *parent)
: QSortFilterProxyModel(parent)
, m_showPasswords(showPasswords)
{
}

int AutoFillPasswordProxyModel::columnCount(const QModelIndex &parent) const
{
if (m_showPasswords)
return qMin(2, QSortFilterProxyModel::columnCount(parent));
else
return qMin(1, QSortFilterProxyModel::columnCount(parent));
}

bool AutoFillPasswordProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex idx = sourceModel()->index(sourceRow, 0, sourceParent);
bool hasPassword = idx.data(Qt::UserRole).toBool();
return (m_showPasswords == hasPassword);
}

AutoFillModel::AutoFillModel(QObject *parent)
: QAbstractTableModel(parent)
{
AutoFillManager *manager = BrowserApplication::instance()->autoFillManager();
Q_ASSERT(manager);
connect(manager, SIGNAL(autoFillChanged()), this, SLOT(autoFillChanged()));
autoFillChanged();
}

void AutoFillModel::autoFillChanged()
{
AutoFillManager *manager = BrowserApplication::instance()->autoFillManager();
m_forms = manager->forms();
reset();
}

QVariant AutoFillModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal
&& role == Qt::DisplayRole) {
switch (section) {
case 0: return tr("WebSite");
case 1: return tr("User Name");
}
}
return QAbstractTableModel::headerData(section, orientation, role);
}

QVariant AutoFillModel::data(const QModelIndex &index, int role) const
{
if (index.row() < 0 || index.row() >= m_forms.size())
return QVariant();

switch (role) {
case Qt::UserRole:
return m_forms[index.row()].hasAPassword;
case Qt::DisplayRole:
case Qt::EditRole: {
switch (index.column()) {
case 0:
return m_forms[index.row()].url.host();
case 1: {
QStringList help;
foreach (const AutoFillManager::Element &element, m_forms[index.row()].elements) {
QString key = element.first.toLower();
if (key.contains(QLatin1String("user"))
|| key.contains(QLatin1String("email"))
|| key.contains(QLatin1String("login"))
|| key == QLatin1String("u"))
return element.second;
help.append(element.first);
}
qWarning() << "AutoFillModel: Unknown user id, choices:" << help;
return help.join(QLatin1String(","));
}
}
}
default:
break;
}
return QVariant();
}

int AutoFillModel::columnCount(const QModelIndex &parent) const
{
return (parent.isValid()) ? 0 : 2;
}

int AutoFillModel::rowCount(const QModelIndex &parent) const
{
return (parent.isValid()) ? 0 : m_forms.count();
}

bool AutoFillModel::removeRows(int row, int count, const QModelIndex &parent)
{
if (parent.isValid())
return false;
int lastRow = row + count - 1;
beginRemoveRows(parent, row, lastRow);
for (int i = lastRow; i >= row; --i)
m_forms.removeAt(i);
AutoFillManager *manager = BrowserApplication::instance()->autoFillManager();
disconnect(manager, SIGNAL(autoFillChanged()), this, SLOT(autoFillChanged()));
manager->setForms(m_forms);
connect(manager, SIGNAL(autoFillChanged()), this, SLOT(autoFillChanged()));
endRemoveRows();
return true;
}

AutoFillDialog::AutoFillDialog(bool onlyShowPasswords, QWidget *parent, Qt::WindowFlags flags)
: QDialog(parent, flags)
{
setupUi(this);
setWindowFlags(Qt::Sheet);
connect(removeButton, SIGNAL(clicked()), tableView, SLOT(removeSelected()));
connect(removeAllButton, SIGNAL(clicked()), tableView, SLOT(removeAll()));
tableView->verticalHeader()->hide();
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setAlternatingRowColors(true);
tableView->setTextElideMode(Qt::ElideMiddle);
tableView->setShowGrid(false);
tableView->setSortingEnabled(true);

AutoFillModel *model = new AutoFillModel();
QSortFilterProxyModel *m_proxyModel = new QSortFilterProxyModel(this);
connect(search, SIGNAL(textChanged(QString)),
m_proxyModel, SLOT(setFilterFixedString(QString)));
AutoFillPasswordProxyModel *passwordProxy = new AutoFillPasswordProxyModel(onlyShowPasswords, this);
passwordProxy->setSourceModel(model);
m_proxyModel->setSourceModel(passwordProxy);
tableView->setModel(m_proxyModel);

QFont f = font();
f.setPointSize(10);
QFontMetrics fm(f);
int height = fm.height() + fm.height() / 3;
tableView->verticalHeader()->setDefaultSectionSize(height);
tableView->verticalHeader()->setMinimumSectionSize(-1);
for (int i = 0; i < model->columnCount(); ++i) {
int header = tableView->horizontalHeader()->sectionSizeHint(i);
switch (i) {
case 0:
header = fm.width(QLatin1String("averagehost.domain.com"));
break;
case 1:
header = fm.width(QLatin1String("_session_id"));
break;
}
int buffer = fm.width(QLatin1String("xx"));
header += buffer;
tableView->horizontalHeader()->resizeSection(i, header);
}
tableView->horizontalHeader()->setStretchLastSection(true);
}

86 changes: 86 additions & 0 deletions src/autofilldialog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Copyright (c) 2009, Benjamin C. Meyer <ben@meyerhome.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Benjamin Meyer nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/

#ifndef AUTOFILLDIALOG_H
#define AUTOFILLDIALOG_H

#include <qdialog.h>
#include "ui_autofilldialog.h"

#include "autofillmanager.h"

#include <qsortfilterproxymodel.h>

class AutoFillPasswordProxyModel : public QSortFilterProxyModel
{
Q_OBJECT

public:
AutoFillPasswordProxyModel(bool showPasswords, QObject *parent = 0);
int columnCount(const QModelIndex &parent = QModelIndex()) const;

protected:
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;

private:
bool m_showPasswords;
};

class AutoFillModel : public QAbstractTableModel
{
Q_OBJECT

public:
AutoFillModel(QObject *parent = 0);
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());

private slots:
void autoFillChanged();

private:
QList<AutoFillManager::Form> m_forms;
};


class AutoFillDialog : public QDialog, public Ui_AutoFillDialog
{
Q_OBJECT

public:
AutoFillDialog(bool onlyShowPasswords = false, QWidget *parent = 0, Qt::WindowFlags flags = 0);

private:

};

#endif // AUTOFILLDIALOG_H

Loading

0 comments on commit e2070e9

Please sign in to comment.