Commit 1afd9baa authored by Martin Straka's avatar Martin Straka

Added change isds password qml page

parent a6781030
......@@ -211,3 +211,6 @@ winphone|winrt: include(winrt/winrt.pri)
include(deployment.pri)
OTHER_FILES +=
DISTFILES += \
qml/pages/PageChangePassword.qml
......@@ -58,7 +58,7 @@ ApplicationWindow {
// define all pages for stackview
property Component pageAboutApp: PageAboutApp {}
property Component pageAccountDetail: PageAccountDetail {}
// property Component pageAccountList: PageAccountList {}
property Component pageChangePassword: PageChangePassword {}
property Component pageMenuAccount: PageMenuAccount {}
property Component pageMenuDatovkaSettings: PageMenuDatovkaSettings {}
property Component pageMenuMessage: PageMenuMessage {}
......
/*
* Copyright (C) 2014-2017 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.Layouts 1.3
import QtQuick.Controls 2.1
import cz.nic.mobileDatovka 1.0
Item {
id: pageChangePassword
/* These properties must be set by caller. */
property var pageView
property var statusBar
property string acntName
property string userName
property var accountModel: null
Component.onCompleted: {
}
PageHeader {
id: headerBar
title: acntName + " (" + userName + ")" + "\n" + qsTr("Change password")
Item {
anchors.left: parent.left
width: parent.width * 0.5
height: parent.height
MouseArea {
anchors.fill: parent
onClicked: {
pageView.pop(StackView.Immediate)
}
}
}
Row {
anchors.verticalCenter: parent.verticalCenter
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
Image {
id: actionButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeight
source: "qrc:/ui/checkbox-marked-circle.svg"
MouseArea {
anchors.fill: parent
onClicked: {
if (newPwd.text.toString() == newPwdAgain.text.toString()) {
if (isds.isCorrectPassword(newPwd.text.toString())) {
errLineText.visible = false
isds.doIsdsAction("changePassword", userName)
} else {
errLineText.text = qsTr("Wrong password format! The new password must contain at least 8 characters including at least 1 number and at least 1 upper-case letter.")
errLineText.visible = true
}
} else {
errLineText.text = qsTr("The entered new passwords do not match!")
errLineText.visible = true
}
}
}
Connections {
target: isds
onRunChangePasswordSig: {
if (isds.changePassword(userName, oldPwd.text.toString(), newPwd.text.toString(), otpCode.text.toString())) {
settings.saveAllSettings(accountModel)
}
}
}
}
}
} // PageHeader
Flickable {
id: flickable
z: 0
anchors.top: headerBar.bottom
anchors.right: parent.right
anchors.left: parent.left
anchors.bottom: parent.bottom
contentHeight: flickContent.implicitHeight
Pane {
id: flickContent
anchors.fill: parent
Column {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
Text {
id: topLineText
anchors.horizontalCenter: parent.horizontalCenter
color: datovkaPalette.mid
width: parent.width
text: qsTr("Enter current password and twice a new password.")
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
TextField {
id: oldPwd
anchors.horizontalCenter: parent.horizontalCenter
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
echoMode: TextInput.Password
passwordMaskDelay: 500 // milliseconds
inputMethodHints: Qt.ImhDigitsOnly
placeholderText: qsTr("Current password")
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
TextField {
id: newPwd
anchors.horizontalCenter: parent.horizontalCenter
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
echoMode: TextInput.Password
passwordMaskDelay: 500 // milliseconds
inputMethodHints: Qt.ImhDigitsOnly
placeholderText: qsTr("New password")
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
TextField {
id: newPwdAgain
anchors.horizontalCenter: parent.horizontalCenter
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
echoMode: TextInput.Password
passwordMaskDelay: 500 // milliseconds
inputMethodHints: Qt.ImhDigitsOnly
placeholderText: qsTr("Confirm new password")
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
TextField {
id: otpCode
anchors.horizontalCenter: parent.horizontalCenter
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
echoMode: TextInput.Normal
passwordMaskDelay: 500 // milliseconds
inputMethodHints: Qt.ImhDigitsOnly
placeholderText: qsTr("Enter OTP code")
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
Text {
id: errLineText
visible: false
anchors.horizontalCenter: parent.horizontalCenter
font.bold: true
color: datovkaPalette.text
width: parent.width
text: ""
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
} // Column layout
} // Pane
ScrollIndicator.vertical: ScrollIndicator {}
} // Flickable
} // Item
......@@ -163,9 +163,13 @@ Component {
} else if (index == 2) {
files.deleteFileDb(userName)
} else if (index == 3) {
if (isds.changePassword(userName, acntName)) {
settings.saveAllSettings(accountModel)
}
pageView.replace(pageChangePassword, {
"pageView": pageView,
"statusBar": statusBar,
"acntName": acntName,
"userName": userName,
"accountModel": accountModel
}, StackView.Immediate)
} else if (index == 4) {
if (accounts.removeAccount(accountModel, userName, true)) {
settings.saveAllSettings(accountModel)
......
......@@ -121,5 +121,6 @@
<file>../qml/pages/PageSettingsStorage.qml</file>
<file>../qml/pages/PageSettingsSync.qml</file>
<file>../qml/main.qml</file>
<file>../qml/pages/PageChangePassword.qml</file>
</qresource>
</RCC>
......@@ -79,6 +79,7 @@ const struct QmlTypeEntry qmlPages[] = {
{ "PageAboutApp", 1, 0 },
{ "PageAccountDetail", 1, 0 },
{ "PageAccountList", 1, 0 },
{ "PageChangePassword", 1, 0 },
{ "PageMenuAccount", 1, 0 },
{ "PageMenuDatovkaSettings", 1, 0 },
{ "PageMenuMessage", 1, 0 },
......
......@@ -78,81 +78,27 @@ IsdsWrapper::~IsdsWrapper(void)
m_workPool.stop();
}
bool IsdsWrapper::changePassword(const QString &userName,
const QString &accountName)
void IsdsWrapper::changePassword(const QString &userName, const QString &oldPwd,
const QString &newPwd, const QString &otpCode)
{
qDebug("%s()", __func__);
bool success = false;
QString errTxt = tr("Wrong username");
QString oldPwd = m_isdsSession.isdsCtxMap[userName].password;
if (userName.isEmpty()) {
Dialogues::errorMessage(Dialogues::CRITICAL,
tr("Error"), errTxt, tr("Internal error"));
return false;
return;
}
if (!isLoggedToIsds(userName)) {
return false;
}
bool ok;
QString newPwd = Dialogues::getText(Q_NULLPTR,
tr("New password: %1").arg(userName),
tr("Enter new password for account\n'%1'").arg(accountName),
Dialogues::EM_NORMAL, QString(), tr("Enter password"), &ok);
if (!ok) {
return false;
}
if (!isCorrectPassword(newPwd)) {
Dialogues::errorMessage(Dialogues::CRITICAL,
tr("Change password: %1").arg(userName),
tr("Wrong password format for username '%1'.").arg(userName),
tr("The new password must contain at least 8 characters including "
"at least 1 number and at least 1 upper-case letter."));
return false;
return;
}
if (m_isdsSession.isdsCtxMap[userName].login_method == USERNAME_PWD_TOTP) {
/* Show SMS request dialogue. */
int msgResponse = Dialogues::message(Dialogues::QUESTION,
tr("SMS code: %1").arg(userName),
tr("Account '%1' requires authentication with SMS code.").arg(accountName),
tr("Do you want to send SMS code now?"),
Dialogues::NO | Dialogues::YES, Dialogues::YES);
if (msgResponse == Dialogues::NO) {
return false;
}
TaskSendSMS *taskSMS;
taskSMS = new (std::nothrow) TaskSendSMS(
m_isdsSession.isdsCtxMap[userName], &m_netLayer);
taskSMS->setAutoDelete(false);
m_workPool.runSingle(taskSMS);
success = TaskSendSMS::DL_SUCCESS == taskSMS->m_result;
delete taskSMS;
if (!success) {
Dialogues::errorMessage(Dialogues::CRITICAL,
tr("Change password: %1").arg(userName),
tr("Failed to send SMS code for username '%1'.").arg(userName),
m_isdsSession.isdsCtxMap[userName].last_isds_msg);
return false;
}
QString text = Dialogues::getText(Q_NULLPTR,
tr("SMS code: %1").arg(userName),
tr("SMS code for '%1' required").arg(accountName),
Dialogues::EM_NORMAL, QString(), tr("Enter SMS code"),
&ok, Qt::ImhDigitsOnly);
if (ok && !text.isEmpty()) {
m_isdsSession.isdsCtxMap[userName].pass_phrase = text;
} else {
return false;
}
m_isdsSession.isdsCtxMap[userName].pass_phrase = otpCode;
TaskChangePassword *task;
task = new (std::nothrow) TaskChangePassword(
m_isdsSession.isdsCtxMap[userName], &m_netLayer, OTP_TYPE_TOTP,
......@@ -163,17 +109,8 @@ bool IsdsWrapper::changePassword(const QString &userName,
delete task;
} else if (m_isdsSession.isdsCtxMap[userName].login_method == USERNAME_PWD_HOTP) {
QString text = Dialogues::getText(Q_NULLPTR,
tr("Security code: %1").arg(userName),
tr("Security code for '%1' required").arg(accountName),
Dialogues::EM_NORMAL, QString(),
tr("Enter security code"), &ok, Qt::ImhDigitsOnly);
if (ok && !text.isEmpty()) {
m_isdsSession.isdsCtxMap[userName].pass_phrase = text;
} else {
return false;
}
m_isdsSession.isdsCtxMap[userName].pass_phrase = otpCode;
TaskChangePassword *task;
task = new (std::nothrow) TaskChangePassword(
m_isdsSession.isdsCtxMap[userName], &m_netLayer, OTP_TYPE_HOTP,
......@@ -200,7 +137,7 @@ bool IsdsWrapper::changePassword(const QString &userName,
tr("Change password: %1").arg(userName),
tr("Failed to change password for username '%1'.").arg(userName),
m_isdsSession.isdsCtxMap[userName].last_isds_msg);
return false;
return;
}
emit statusBarTextChanged(
......@@ -210,8 +147,6 @@ bool IsdsWrapper::changePassword(const QString &userName,
AcntData &acntData(AccountListModel::globAccounts[userName]);
acntData.setPassword(newPwd);
return true;
}
void IsdsWrapper::doIsdsAction(const QString &isdsAction,
......@@ -323,6 +258,27 @@ void IsdsWrapper::getDeliveryInfo(const QString &userName, qint64 msgId)
}
}
bool IsdsWrapper::isCorrectPassword(const QString &password)
{
if (password.isEmpty()) {
return false;
}
if (password.length() < 8 || password.length() > 32) {
return false;
}
if (!password.contains(QRegExp(".*[a-z]+.*"))) {
return false;
}
if (!password.contains(QRegExp(".*[A-Z]+.*"))) {
return false;
}
if (!password.contains(QRegExp(".*[0-9]+.*"))) {
return false;
}
return true;
}
void IsdsWrapper::returnInputDialogText(const QString &isdsAction,
const QString &pwdType, const QString &userName, const QString &pwd)
{
......@@ -623,27 +579,6 @@ bool IsdsWrapper::hasCtxAllLoginData(const QString &isdsAction,
return true;
}
bool IsdsWrapper::isCorrectPassword(const QString &password)
{
if (password.isEmpty()) {
return false;
}
if (password.length() < 8 || password.length() > 32) {
return false;
}
if (!password.contains(QRegExp(".*[a-z]+.*"))) {
return false;
}
if (!password.contains(QRegExp(".*[A-Z]+.*"))) {
return false;
}
if (!password.contains(QRegExp(".*[0-9]+.*"))) {
return false;
}
return true;
}
bool IsdsWrapper::isLoggedToIsds(const QString &userName)
{
qDebug("%s()", __func__);
......
......@@ -50,11 +50,13 @@ public:
* @brief Change ISDS login password.
*
* @param[in] userName Account username string.
* @param[in] accountName Account name.
* @param[in] oldPwd Current/old password string.
* @param[in] newPwd New password string.
* @param[in] otpCode OTP code string (may be null).
*/
Q_INVOKABLE
bool changePassword(const QString &userName,
const QString &accountName);
void changePassword(const QString &userName, const QString &oldPwd,
const QString &newPwd, const QString &otpCode);
/*!
* @brief Do an isds action from QML.
......@@ -96,6 +98,15 @@ public:
Q_INVOKABLE
void getDeliveryInfo(const QString &userName, qint64 msgId);
/*!
* @brief Check if new password is valid for ISDS.
*
* @param[in] password Password to be checked.
* @return true if password is correct.
*/
Q_INVOKABLE
bool isCorrectPassword(const QString &password);
/*!
* @brief Password string from QML input dialog.
*
......@@ -357,14 +368,6 @@ private:
bool hasCtxAllLoginData(const QString &isdsAction,
const QString &userName);
/*!
* @brief Check if new password is valid for ISDS.
*
* @param[in] password Password to be checked.
* @return true if password is correct.
*/
bool isCorrectPassword(const QString &password);
/*!
* @brief Test if user is connected to databox.
*
......
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