Commit 653c8340 authored by Martin Straka's avatar Martin Straka

Updated PIN management and settings

parent 75a5cb68
......@@ -53,6 +53,8 @@ ApplicationWindow {
property Component accountSettingsPage: AccountSettingsPage {}
property Component settingsPage: SettingsPage {}
property Component aboutPage: AboutPage {}
property Component pinPage: PinPage {}
// header background color
property string mainHeaderBgColor: "#00539b"
......@@ -178,12 +180,6 @@ ApplicationWindow {
settings.verifyPin(pinCodeInput.text.toString())
}
}
Button {
text: qsTr("Exit")
onClicked: {
Qt.quit()
}
}
}
}
Connections {
......
......@@ -75,24 +75,14 @@ Component {
implicitWidth: 800 // Chosen to be large enough
MenuItem {
text: qsTr("Add account")
//iconSource: "qrc:/ui/account-plus.svg"
onTriggered: {
gUserName = ""
pageView.push(accountSettingsPage, StackView.Immediate)
}
}
MenuItem {
text: qsTr("Settings")
//iconSource: "qrc:/ui/settings.svg"
onTriggered: {
gUserName = ""
pageView.push(settingsPage, StackView.Immediate)
}
}
MenuItem {
id: syncAllMenu
text: qsTr("Synchronize all")
//iconSource: "qrc:/ui/sync-all.svg"
onTriggered: {
statusBarText.text = ""
isds.syncAllAccounts()
......@@ -101,12 +91,25 @@ Component {
MenuItem {
id: vacuumAllMenu
text: qsTr("Vacuum databases")
//iconSource: "qrc:/ui/sync-all.svg"
onTriggered: {
statusBarText.text = ""
files.vacuumFileDbs()
}
}
MenuItem {
text: qsTr("Settings")
onTriggered: {
gUserName = ""
pageView.push(settingsPage, StackView.Immediate)
}
}
MenuItem {
text: qsTr("PIN")
onTriggered: {
gUserName = ""
pageView.push(pinPage, StackView.Immediate)
}
}
}
MouseArea {
anchors.fill: parent
......
/*
* Copyright (C) 2014-2016 CZ.NIC
*
* 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/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
import QtQuick 2.7
import QtQuick.Controls 2.0
Component {
id: pinPage
Item {
id: mainItem
Component.onCompleted: {
settings.loadPinSettings()
}
property string currentPIN: ""
property string actionName: "blank"
property int myWidht: mainItem.width - 2 * defaultMargin
Component {
id: pinComponent
Column {
spacing: formItemVerticalSpacing
Text {
id: pageLabel
anchors.horizontalCenter: parent.horizontalCenter
font.bold: true
color: datovkaPalette.text
text: qsTr("PIN settings")
}
Column {
spacing: formItemVerticalSpacing
Text {
id: pinLabel
color: datovkaPalette.mid
width: myWidht
text: qsTr("You must enter the PIN code on application start-up.")
wrapMode: Text.Wrap
}
Button {
id: setPinCodeButton
text: qsTr("Set PIN")
onClicked: {
actionName = "new"
actionButton.visible = true
setPinCodeButton.visible = false
pinLabel.text = qsTr("Enter your new PIN code below:")
setPinCodeString.visible = true
setPinCodeString.focus = true
getPinCodeString.visible = false
}
}
Button {
id: changePinCodeButton
text: qsTr("Change PIN")
onClicked: {
actionName = "change"
actionButton.visible = true
changePinCodeButton.visible = false
disablePinCodeButton.visible = false
pinLabel.text = qsTr("For PIN change you must enter current amd new PIN code below:")
getPinCodeString.visible = true
getPinCodeString.focus = true
setPinCodeString.visible = true
}
}
Button {
id: disablePinCodeButton
text: qsTr("Disable PIN")
onClicked: {
actionName = "disable"
actionButton.visible = true
disablePinCodeButton.visible = false
changePinCodeButton.visible = false
pinLabel.text = qsTr("For PIN deactivating you must enter current PIN code below:")
getPinCodeString.visible = true
getPinCodeString.focus = true
}
}
TextField {
id: getPinCodeString
visible: false
width: myWidht
echoMode: TextInput.Password
passwordMaskDelay: 500 // milliseconds
inputMethodHints: Qt.ImhDigitsOnly
placeholderText: qsTr("Enter your current PIN code")
text: ""
}
TextField {
id: setPinCodeString
visible: false
width: myWidht
echoMode: TextInput.Password
passwordMaskDelay: 500 // milliseconds
inputMethodHints: Qt.ImhDigitsOnly
placeholderText: qsTr("Enter new PIN code")
text: ""
}
Text {
id: errorLabel
visible: false
anchors.horizontalCenter: parent.horizontalCenter
font.bold: true
color: datovkaPalette.text
text: "" }
}
Connections {
target: settings
onSendPinData: {
currentPIN = currentPinCode
if (currentPIN == "") {
setPinCodeButton.visible = true
changePinCodeButton.visible = false
disablePinCodeButton.visible = false
} else {
setPinCodeButton.visible = false
changePinCodeButton.visible = true
disablePinCodeButton.visible = true
}
}
}
Row {
spacing: formButtonHorizontalSpacing
anchors.horizontalCenter: parent.horizontalCenter
Button {
id: actionButton
text: if (actionName == "new") {
qsTr("Set PIN")
} else if (actionName == "change") {
qsTr("Change PIN")
} else if (actionName == "disable") {
qsTr("Disable PIN")
} else {
actionButton.visible = false
}
onClicked: {
/* set new pin code */
if (actionName == "new") {
if (setPinCodeString.text == "") {
errorLabel.text = qsTr("Error: PIN code missing!")
errorLabel.visible = true
} else {
errorLabel.visible = false
settings.updatePinSettings(true, setPinCodeString.text.toString())
pageView.pop(StackView.Immediate)
}
/* change current pin code */
} else if (actionName == "change") {
if (getPinCodeString.text == currentPIN) {
errorLabel.visible = false
if (setPinCodeString.text == "") {
errorLabel.text = qsTr("Error: New PIN code missing!")
errorLabel.visible = true
} else {
errorLabel.visible = false
settings.updatePinSettings(true, setPinCodeString.text.toString())
pageView.pop(StackView.Immediate)
}
} else {
errorLabel.text = qsTr("Error: Current PIN is wrong! Try again.")
errorLabel.visible = true
}
/* remove/disable current pin code */
} else if (actionName == "disable") {
if (getPinCodeString.text == currentPIN) {
errorLabel.visible = false
settings.updatePinSettings(false, "")
pageView.pop(StackView.Immediate)
} else {
errorLabel.text = qsTr("Error: Current PIN is wrong! Try again.")
errorLabel.visible = true
}
}
}
}
Button {
text: qsTr("Cancel")
onClicked: {
pageView.pop(StackView.Immediate)
}
}
}
}
}
ListModel {
id: pinModel
ListElement {
text: ""
}
}
ListView {
id: settingsList
anchors.fill: parent
anchors.margins: defaultMargin
clip: true
spacing: 0
opacity: 1
visible: true
interactive: true
model: pinModel
delegate: pinComponent
}
}
}
......@@ -233,38 +233,6 @@ Component {
wrapMode: Text.Wrap
}
}
Text {
id: sectionLabelSecurity
font.bold: true
color: datovkaPalette.text
text: qsTr("Security")
}
Column {
spacing: 1
CheckBox {
id: iusePinCode
text: qsTr("Use PIN code")
checked: false
onClicked: {
ipinCodeString.visible = iusePinCode.checked
}
}
Text {
color: datovkaPalette.mid
width: myWidht
text: qsTr("You must enter the PIN code on application start-up.")
wrapMode: Text.Wrap
}
TextField {
id: ipinCodeString
visible: false
width: myWidht
echoMode: TextInput.Password
passwordMaskDelay: 500 // milliseconds
inputMethodHints: Qt.ImhDigitsOnly
placeholderText: qsTr("Enter PIN code")
}
}
Connections {
target: settings
onSendSettingsData: {
......@@ -272,11 +240,8 @@ Component {
idownloadCompleteMsgs.checked = downloadCompleteMsgs
messageLifeSpinBox.setVal(msgLifeDays)
attachLifeSpinBox.setVal(fileLifeDays)
iusePinCode.checked = usePinCode
ipinCodeString.text = pinCodeString
languageComboBoxId.currentIndex = langIndex
fontSizeSpinBox.setVal(fontSize)
ipinCodeString.visible = usePinCode
}
}
Row {
......@@ -285,17 +250,12 @@ Component {
Button {
text: qsTr("Apply")
onClicked: {
if (iusePinCode.checked && ipinCodeString.text == "") {
iusePinCode.checked = false
}
settings.updateSettings(sLang,
fontSizeSpinBox.val().toString(),
idownloadOnlyNewMsgs.checked,
idownloadCompleteMsgs.checked,
messageLifeSpinBox.val().toString(),
attachLifeSpinBox.val().toString(),
iusePinCode.checked,
ipinCodeString.text.toString())
attachLifeSpinBox.val().toString())
pageView.pop(StackView.Immediate)
}
}
......
......@@ -101,5 +101,6 @@
<file>datovka.png</file>
<file>cznic.png</file>
<file>ui/datovka@2x.png</file>
<file>../qml/pages/PinPage.qml</file>
</qresource>
</RCC>
......@@ -58,6 +58,7 @@ static const struct {
{ "AccountSettingsPage", 1, 0 },
{ "SettingsPage", 1, 0 },
{ "AboutPage", 1, 0 },
{ "PinPage", 1, 0 },
};
......@@ -196,13 +197,10 @@ int main(int argc, char *argv[])
/* load UI (QML) */
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
/* show PIN screen if needed */
emit settings.showPinScreen(globSet.usePinCode);
/* OpenSSL support test */
if (QSslSocket::supportsSsl()) {
/* set last update text to status bar */
if (!globSet.lastUpdate.isEmpty()) {
if (!globSet.lastUpdate.isEmpty() && !globSet.usePinCode) {
emit isds.statusBarTextChanged(
QObject::tr("Last synchronisation: %1").
arg(globSet.lastUpdate), false);
......@@ -228,6 +226,9 @@ int main(int argc, char *argv[])
/* Load counters. */
Accounts::loadModelCounters();
/* show PIN screen if needed */
emit settings.showPinScreen(globSet.usePinCode);
/* Run app main event loop */
int ret = app.exec();
......
......@@ -69,7 +69,13 @@ void Settings::saveGlobalSettingsToFile(QSettings &settings) const
settings.setValue(SETTINGS_FILE_LIFETIME_IN_DAYS,
globSet.fileLifeTimeInDays);
settings.setValue(SETTINGS_USE_PIN_CODE, globSet.usePinCode);
settings.setValue(SETTINGS_PIN_CODE_STRING, globSet.pinCodeString);
if (globSet.usePinCode) {
QByteArray ba;
ba.append(pinCodeString);
settings.setValue(SETTINGS_PIN_CODE_STRING, ba.toBase64());
} else {
settings.setValue(SETTINGS_PIN_CODE_STRING, "");
}
settings.setValue(SETTINGS_LAST_UPDATE, globSet.lastUpdate);
settings.endGroup();
}
......@@ -101,8 +107,8 @@ void Settings::loadGlobalSettingsFromFile(const QSettings &settings)
DEFAULT_FILE_LIFETIME).toInt();
globSet.usePinCode = settings.value(
SETTINGS_GLOBAL_GROUP "/" SETTINGS_USE_PIN_CODE, false).toBool();
globSet.pinCodeString = settings.value(
SETTINGS_GLOBAL_GROUP "/" SETTINGS_PIN_CODE_STRING).toString();
globSet.pinCodeString = QByteArray::fromBase64(settings.value(
SETTINGS_GLOBAL_GROUP "/" SETTINGS_PIN_CODE_STRING).toByteArray());
globSet.lastUpdate = settings.value(
SETTINGS_GLOBAL_GROUP "/" SETTINGS_LAST_UPDATE).toString();
}
......
......@@ -71,8 +71,19 @@ void GlobalSettingsQmlWrapper::loadSettings(void)
/* Send data to QML */
emit sendSettingsData(langugeComboBoxIndex, globSet.fontSize,
globSet.downloadOnlyNewMsgs, globSet.downloadCompleteMsgs,
globSet.msgLifeTimeInDays, globSet.fileLifeTimeInDays,
globSet.usePinCode, globSet.pinCodeString);
globSet.msgLifeTimeInDays, globSet.fileLifeTimeInDays);
}
/* ========================================================================= */
/*
* Slot: Load current Pin settings from global structure.
*/
void GlobalSettingsQmlWrapper::loadPinSettings(void)
/* ========================================================================= */
{
/* Send PIN data to QML */
emit sendPinData(globSet.usePinCode, globSet.pinCodeString);
}
......@@ -82,8 +93,7 @@ void GlobalSettingsQmlWrapper::loadSettings(void)
*/
void GlobalSettingsQmlWrapper::updateSettings(const QString &language,
const QString &fontSize, bool downloadOnlyNewMsgs, bool downloadCompleteMsgs,
const QString &msgLifeDays, const QString &fileLifeDays, bool usePinCode,
const QString &pinCodeString)
const QString &msgLifeDays, const QString &fileLifeDays)
/* ========================================================================= */
{
globSet.language = language;
......@@ -92,12 +102,25 @@ void GlobalSettingsQmlWrapper::updateSettings(const QString &language,
globSet.downloadCompleteMsgs = downloadCompleteMsgs;
globSet.msgLifeTimeInDays = msgLifeDays.toInt();
globSet.fileLifeTimeInDays = fileLifeDays.toInt();
QSettings settings(Settings::settingsPath(), QSettings::IniFormat);
globSet.saveGlobalSettingsToFile(settings);
settings.sync();
}
/* ========================================================================= */
/*
* Slot: Set and save PIN settings from QML to global structure.
*/
void GlobalSettingsQmlWrapper::updatePinSettings(bool usePinCode,
const QString &pinCodeString)
/* ========================================================================= */
{
globSet.usePinCode = usePinCode;
if (usePinCode) {
QByteArray ba;
ba.append(pinCodeString);
ba.toBase64();
globSet.pinCodeString = ba.toBase64();
globSet.pinCodeString = pinCodeString;
} else {
globSet.pinCodeString = "";
}
......@@ -115,8 +138,11 @@ void GlobalSettingsQmlWrapper::updateSettings(const QString &language,
void GlobalSettingsQmlWrapper::verifyPin(const QString &pinCodeString)
/* ========================================================================= */
{
QByteArray pin = QByteArray::fromBase64(globSet.pinCodeString.toUtf8());
QString pinString(pin);
emit sendPinReply(pinCodeString == globSet.pinCodeString);
emit sendPinReply(pinCodeString == pinString);
if ((pinCodeString == globSet.pinCodeString) && !globSet.lastUpdate.isEmpty()) {
emit statusBarTextChanged(
QObject::tr("Last synchronisation: %1").
arg(globSet.lastUpdate), false);
}
}
......@@ -57,13 +57,23 @@ public:
*/
Q_INVOKABLE void loadSettings(void);
/*!
* @brief Load current PIN settings.
*/
Q_INVOKABLE void loadPinSettings(void);
/*!
* @brief Save global settings from QML.
*/
Q_INVOKABLE void updateSettings(const QString &language,
const QString &fontSize, bool downloadOnlyNewMsgs,
bool downloadCompleteMsgs, const QString &msgLifeDays,
const QString &fileLifeDays, bool usePinCode,
const QString &fileLifeDays);
/*!
* @brief Save PIN settings from QML.
*/
Q_INVOKABLE void updatePinSettings(bool usePinCode,
const QString &pinCodeString);
/*!
......@@ -83,8 +93,12 @@ signals:
*/
void sendSettingsData(int langIndex, int fontSize,
bool downloadOnlyNewMsgs, bool downloadCompleteMsgs,
int msgLifeDays, int fileLifeDays,
bool usePinCode, QString pinCodeString);
int msgLifeDays, int fileLifeDays);
/*!
* @brief Send current PIN settings to QML.
*/
void sendPinData(bool usePinCode, QString currentPinCode);
/*!
* @brief Send PIN verification result to QML.
......@@ -95,6 +109,15 @@ signals:
* @brief Show PIN screen to QML.
*/
void showPinScreen(bool show);
/*!
* @brief Set new statusbar text and active busy indicator to QML.
*
* @param[in] txt - text message for statusbar.
* @param[in] busy - true means the statusbar busy indicator is active
* and shown, false = disabled and hidden
*/
void statusBarTextChanged(QString txt, bool busy);
};
#endif // SETWRAPPER_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment