Implemented application login.

Minor UI improvement.
Fixed memory leaks.
print
Josef Rokos 9 years ago
parent 3d68281c87
commit c722fe743c

@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file>icons/login_32.png</file>
<file>icons/login_64.png</file>
</qresource>
</RCC>

@ -22,10 +22,13 @@ win32 {
SOURCES += main.cpp\
mainwindow.cpp \
logindialog.cpp
HEADERS += mainwindow.h
HEADERS += mainwindow.h \
logindialog.h
FORMS += mainwindow.ui
FORMS += mainwindow.ui \
logindialog.ui
unix {
@ -43,3 +46,6 @@ else:unix: LIBS += -L$$OUT_PWD/../core/ -lcore
INCLUDEPATH += $$PWD/../core
DEPENDPATH += $$PWD/../core
RESOURCES += \
appRc.qrc

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

@ -0,0 +1,45 @@
#include "logindialog.h"
#include "ui_logindialog.h"
#include "../core/core.h"
#include <QMessageBox>
LoginDialog::LoginDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::LoginDialog)
{
ui->setupUi(this);
}
LoginDialog::~LoginDialog()
{
delete ui;
}
QString LoginDialog::login() const
{
return ui->editLogin->text();
}
QString LoginDialog::password() const
{
return ui->editPassword->text();
}
void LoginDialog::reset()
{
ui->editLogin->setText("");
ui->editPassword->setText("");
}
void LoginDialog::accept()
{
PermissionService srv;
if (srv.checkLogin(ui->editLogin->text(), ui->editPassword->text()))
{
QDialog::accept();
}
else
{
QMessageBox::critical(this, "Bad login", "Bad login or password");
}
}

@ -0,0 +1,29 @@
#ifndef LOGINDIALOG_H
#define LOGINDIALOG_H
#include <QDialog>
namespace Ui {
class LoginDialog;
}
class LoginDialog : public QDialog
{
Q_OBJECT
public:
explicit LoginDialog(QWidget *parent = 0);
~LoginDialog();
QString login() const;
QString password() const;
void reset();
private:
Ui::LoginDialog *ui;
// QDialog interface
public slots:
void accept() override;
};
#endif // LOGINDIALOG_H

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LoginDialog</class>
<widget class="QDialog" name="LoginDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>408</width>
<height>220</height>
</rect>
</property>
<property name="windowTitle">
<string>Login</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widget" native="true">
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="appRc.qrc">:/icons/login_64.png</pixmap>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Login</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="editLogin"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="editPassword">
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources>
<include location="appRc.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>LoginDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>LoginDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -1,5 +1,6 @@
#include "mainwindow.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QStringList>
@ -7,6 +8,7 @@ int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.move(QApplication::desktop()->screen()->rect().center() - w.rect().center());
w.show();
return a.exec();

@ -13,6 +13,22 @@ MainWindow::MainWindow(QWidget *parent) :
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_lblUser = new QLabel(this);
ui->statusBar->addWidget(m_lblUser);
m_loginDialog = new LoginDialog(this);
connect(m_loginDialog, &LoginDialog::accepted, [this]{
PermissionService service;
QSharedPointer<User> u = service.loadUser(m_loginDialog->login());
m_lblUser->setText(u->name());
m_loginDialog->reset();
Context::instance().setCurrentUser(u);
});
connect(m_loginDialog, &LoginDialog::rejected, [this]{
close();
});
Context::instance().loadPlugins();
int i = 0;
@ -27,6 +43,11 @@ MainWindow::MainWindow(QWidget *parent) :
}
((QVBoxLayout*)ui->navigation->layout())->addStretch(1);
if (Context::instance().db() != NULL)
{
ui->navigation->setEnabled(true);
}
}
MainWindow::~MainWindow()
@ -59,13 +80,37 @@ void MainWindow::openPlugin()
void MainWindow::on_actionOpen_database_triggered()
{
QFileDialog dialog(this);
/*QFileDialog dialog(this);
dialog.setNameFilter(tr("Database Files (*.db)"));
dialog.setWindowTitle(tr("Open Database"));
Context::instance().openDb(dialog.getOpenFileName());
dialog.setWindowTitle(tr("Open Database"));*/
QString dbFile = QFileDialog::getOpenFileName(this, "Open Database", "", "Database Files (*.db)");
if (!dbFile.isEmpty())
{
Context::instance().openDb(dbFile);
ui->navigation->setEnabled(true);
on_actionLogin_triggered();
}
}
void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
ui->tabWidget->removeTab(index);
}
void MainWindow::on_actionLogin_triggered()
{
QSharedPointer<User> u;
Context::instance().setCurrentUser(u);
m_lblUser->setText("");
m_loginDialog->show();
}
void MainWindow::showEvent(QShowEvent *evt)
{
QWidget::showEvent(evt);
if (Context::instance().db() != NULL && Context::instance().currentUser().data() == NULL)
{
m_loginDialog->show();
}
}

@ -2,6 +2,9 @@
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include "logindialog.h"
#define PLUGIN_INDEX "plug_index"
@ -25,8 +28,16 @@ private slots:
void on_tabWidget_tabCloseRequested(int index);
void on_actionLogin_triggered();
private:
Ui::MainWindow *ui;
LoginDialog *m_loginDialog;
QLabel *m_lblUser;
// QWidget interface
protected:
void showEvent(QShowEvent *evt);
};
#endif // MAINWINDOW_H

@ -15,8 +15,17 @@
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="navigation" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2"/>
</widget>
</item>
@ -52,6 +61,8 @@
<string>File</string>
</property>
<addaction name="actionOpen_database"/>
<addaction name="actionLogin"/>
<addaction name="separator"/>
<addaction name="actionExit"/>
</widget>
<addaction name="menuFile"/>
@ -63,6 +74,7 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="actionLogin"/>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="actionExit">
@ -75,8 +87,19 @@
<string>Open database...</string>
</property>
</action>
<action name="actionLogin">
<property name="icon">
<iconset resource="appRc.qrc">
<normaloff>:/icons/login_32.png</normaloff>:/icons/login_32.png</iconset>
</property>
<property name="text">
<string>Login...</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<resources>
<include location="appRc.qrc"/>
</resources>
<connections/>
</ui>

@ -15,6 +15,11 @@
#include "roles/roles.h"
#include "permissionservice.h"
Context::~Context()
{
this->destroy();
}
Context &Context::instance()
{
static Context ctx;
@ -91,7 +96,10 @@ void Context::destroy()
m_dbOpened = false;
}
delete m_settings;
if (m_settings != NULL && m_settings->parent() == NULL)
{
delete m_settings;
}
foreach (IPlugin *plugin, m_plugins)
{
@ -112,6 +120,16 @@ Context::Context()
m_dbOpened = false;
}
QSharedPointer<User> Context::currentUser() const
{
return m_currentUser;
}
void Context::setCurrentUser(const QSharedPointer<User> &currentUser)
{
m_currentUser = currentUser;
}
void Context::checkDb(const QString &path)
{
{
@ -226,4 +244,6 @@ void Context::checkPermissions()
}
}
}
permService.checkForAdmin();
}

@ -7,10 +7,12 @@
#include <QSqlDatabase>
#include <QStringList>
#include <QSettings>
#include <QSharedPointer>
#include "define.h"
#include "core_global.h"
#include "transaction.h"
#include "data/core-data.h"
#include <odb/database.hxx>
#include <odb/session.hxx>
@ -20,6 +22,7 @@ class IPlugin;
class CORESHARED_EXPORT Context
{
public:
~Context();
static Context &instance();
QList<IPlugin*> plugins();
IPlugin *plugin(const QString &pluginId);
@ -31,6 +34,9 @@ public:
void destroy();
QStringList defaultPerms();
QSharedPointer<User> currentUser() const;
void setCurrentUser(const QSharedPointer<User> &currentUser);
private:
Context();
QList<IPlugin*> m_plugins;
@ -38,6 +44,7 @@ private:
QSettings *m_settings;
bool m_dbOpened;
odb::session m_session;
QSharedPointer<User> m_currentUser;
QStringList m_solved;

@ -7,5 +7,6 @@
#include "imetadataplugin.h"
#include "transaction.h"
#include "gridform.h"
#include "permissionservice.h"
#endif // CORE_H

@ -70,14 +70,11 @@
<property name="toolTip">
<string>Apply</string>
</property>
<property name="toolTipDuration">
<number>1</number>
</property>
<property name="text">
<string>Go</string>
</property>
<property name="icon">
<iconset>
<iconset resource="rc.qrc">
<normaloff>:/icons/ok.svg</normaloff>:/icons/ok.svg</iconset>
</property>
<property name="iconSize">
@ -119,14 +116,11 @@
<property name="toolTip">
<string>Save</string>
</property>
<property name="toolTipDuration">
<number>1</number>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="icon">
<iconset>
<iconset resource="rc.qrc">
<normaloff>:/icons/save.svg</normaloff>:/icons/save.svg</iconset>
</property>
<property name="iconSize">
@ -145,14 +139,11 @@
<property name="toolTip">
<string>Manage</string>
</property>
<property name="toolTipDuration">
<number>1</number>
</property>
<property name="text">
<string>Manage</string>
</property>
<property name="icon">
<iconset>
<iconset resource="rc.qrc">
<normaloff>:/icons/list.svg</normaloff>:/icons/list.svg</iconset>
</property>
<property name="iconSize">
@ -229,6 +220,8 @@
</property>
</action>
</widget>
<resources/>
<resources>
<include location="rc.qrc"/>
</resources>
<connections/>
</ui>

@ -30,6 +30,16 @@ public:
}
virtual ~GridForm()
{
if (m_form != NULL && m_form->parent() == NULL)
{
delete m_form;
}
if (m_tableModel != NULL && m_tableModel->parent() == NULL)
{
delete m_tableModel;
}
delete m_formHandler;
}

@ -19,6 +19,9 @@
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QToolButton" name="btnNew">
<property name="toolTip">
<string>Add record</string>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
@ -45,6 +48,9 @@
</item>
<item>
<widget class="QToolButton" name="btnEdit">
<property name="toolTip">
<string>Edit record</string>
</property>
<property name="text">
<string>E</string>
</property>
@ -65,6 +71,9 @@
</item>
<item>
<widget class="QToolButton" name="btnDelete">
<property name="toolTip">
<string>Delete record</string>
</property>
<property name="text">
<string>D</string>
</property>
@ -85,6 +94,9 @@
</item>
<item>
<widget class="QToolButton" name="btnFilter">
<property name="toolTip">
<string>Filter</string>
</property>
<property name="text">
<string>F</string>
</property>
@ -108,6 +120,9 @@
</item>
<item>
<widget class="QToolButton" name="btnPrint">
<property name="toolTip">
<string>Print</string>
</property>
<property name="text">
<string>P</string>
</property>

@ -21,6 +21,7 @@ IGridForm::IGridForm(QWidget *parent) :
IGridForm::~IGridForm()
{
delete ui;
}
void IGridForm::setPluginId(const QString &pluginId)

@ -10,14 +10,11 @@
IMetaDataPlugin::IMetaDataPlugin()
{
m_service = NULL;
m_ui = NULL;
}
IMetaDataPlugin::~IMetaDataPlugin()
{
if (m_service != NULL)
{
delete m_service;
}
}
QString IMetaDataPlugin::pluginName()

@ -10,7 +10,7 @@ class CORESHARED_EXPORT IMetaDataPlugin : public IPlugin
{
public:
IMetaDataPlugin();
~IMetaDataPlugin();
virtual ~IMetaDataPlugin();
// IPlugin interface
public:

@ -19,7 +19,18 @@ public:
m_service = NULL;
}
virtual ~IPlugin() { }
virtual ~IPlugin() {
if (m_service != NULL)
{
delete m_service;
}
if (m_ui != NULL && m_ui->parent() == NULL)
{
delete m_ui;
}
}
virtual QString pluginName() = 0;
virtual QString pluginId() = 0;
virtual QString pluginDescription() = 0;

@ -1,4 +1,9 @@
#include "core-odb.hxx"
#include "permissionservice.h"
#include <QCryptographicHash>
typedef odb::query<Permission> permQuery;
typedef odb::result<Permission> permResult;
PermissionService::PermissionService()
{
@ -36,3 +41,51 @@ QSharedPointer<Permission> PermissionService::forNameAndPlugin(const QString &na
return p;
}
bool PermissionService::checkLogin(const QString &login, const QString &password)
{
QSharedPointer<User> user = loadUser(login);
if (user.data())
{
return user->password() == encryptPassword(password) && user->active();
}
return false;
}
QSharedPointer<User> PermissionService::loadUser(const QString &login)
{
odb::database *db = Context::instance().db();
Transaction tr;
return db->query_one<User>("login = " + odb::query<User>::_ref(login));
}
void PermissionService::checkForAdmin()
{
odb::database *db = Context::instance().db();
Transaction tr;
odb::query<User> q(odb::query<User>::isAdmin == true);
odb::result<User> r = db->query<User>(q);
if (r.empty())
{
QSharedPointer<User> admin(new User);
admin->setLogin("admin");
admin->setName("Administrator");
admin->setIsAdmin(true);
admin->setPassword(encryptPassword("admin"));
admin->setActive(true);
db->persist(admin);
}
tr.commit();
}
QString PermissionService::encryptPassword(const QString &plainPasswd)
{
return QString(QCryptographicHash::hash(plainPasswd.toUtf8(),QCryptographicHash::Sha256).toBase64());
}

@ -2,8 +2,7 @@
#define PERMISSIONSERVICE_H
#include "service.h"
#include "permission.h"
#include "core-odb.hxx"
#include "data/core-data.h"
#include "core_global.h"
#include <odb/core.hxx>
#include <odb/database.hxx>
@ -14,9 +13,6 @@
#include <QSharedPointer>
#include <QString>
typedef odb::query<Permission> permQuery;
typedef odb::result<Permission> permResult;
class CORESHARED_EXPORT PermissionService : public Service<Permission>
{
public:
@ -25,6 +21,10 @@ public:
QList<QSharedPointer<Permission> > forPlugin(const QString &pluginId);
QSharedPointer<Permission> forNameAndPlugin(const QString &name, const QString &pluginId);
bool checkLogin(const QString &login, const QString &password);
QSharedPointer<User> loadUser(const QString &login);
void checkForAdmin();
QString encryptPassword(const QString &plainPasswd);
};
#endif // PERMISSIONSERVICE_H

@ -5,9 +5,9 @@
#include <QHeaderView>
#include "../data/core-data.h"
#include "../service.h"
#include "../permissionservice.h"
#include "../emptystringvalidator.h"
#include "../samestringvalidator.h"
#include <QCryptographicHash>
UserForm::UserForm(QWidget *parent) :
AutoForm<User>(parent),
@ -69,8 +69,9 @@ bool UserForm::bindOtherToData()
this->entity()->addRole(srv.loadById(ui->tableWidget->item(i,0)->data(Qt::UserRole).toInt()));
}
}
PermissionService permService;
if (m_passChanged){
this->entity()->setPassword(QString(QCryptographicHash::hash(ui->password->text().toUtf8(),QCryptographicHash::Sha256).toBase64()));
this->entity()->setPassword(permService.encryptPassword(ui->password->text()));
}
return true;
}

Loading…
Cancel
Save