Commit 69df657a authored by Martin Straka's avatar Martin Straka Committed by Karel Slaný

Added change username rollback if an error

parent 91edda35
......@@ -8,7 +8,7 @@
*
* 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
* 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
......@@ -39,7 +39,7 @@ Item {
property bool isNewAccount: (userName == "")
property string sLoginMethod: "pwd"
property string originUserName
property string oldUserName
Component.onCompleted: {
if (!isNewAccount) {
......@@ -103,8 +103,11 @@ Item {
passwordTextField.text.toString(),
testAccount.checked, rememberPassword.checked,
useLS.checked, certPathLabelId.text.toString(),
originUserName)) {
oldUserName)) {
settings.saveAllSettings(accountModel)
if (userNameTextField.text.toString() !== oldUserName) {
isds.doIsdsAction("getAccountInfo", userNameTextField.text.toString())
}
}
pageView.pop(StackView.Immediate)
}
......@@ -320,7 +323,7 @@ Item {
useLS.checked = storeToDisk
certPathLabelId.text = certPath
loginMethodComboBox.selectCurrentKey(loginMethod)
originUserName = userName
oldUserName = userName
testAccount.enabled = false
headerBar.title = qsTr("Account settings")
}
......
......@@ -8,7 +8,7 @@
*
* 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
* 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
......@@ -193,7 +193,7 @@ bool Accounts::createAccount(const QVariant &acntModelVariant,
bool Accounts::updateAccount(const QVariant &acntModelVariant,
const QString &loginMetod, const QString &acntName, const QString &newUserName,
const QString &pwd, bool isTestAccount, bool rememberPwd, bool storeToDisk,
const QString &certPath, const QString &originUserName)
const QString &certPath, const QString &oldUserName)
{
debugFuncCall();
......@@ -223,17 +223,15 @@ bool Accounts::updateAccount(const QVariant &acntModelVariant,
QString userName = newUserName.trimmed();
if (userName != originUserName) {
bool success = changeAccountUserName(originUserName,
userName.trimmed(), acntName);
/* User name is changed */
if (userName != oldUserName) {
return changeAccountUserName(accountModel, loginMetod,
acntName.trimmed(), userName, pwd.trimmed(), isTestAccount,
rememberPwd, storeToDisk, certPath, oldUserName);
}
if (!success) {
return false;
}
} else {
if (!GlobInstcs::acntMapPtr->contains(userName)) {
return false;
}
if (!GlobInstcs::acntMapPtr->contains(userName)) {
return false;
}
AcntData &acntData((*GlobInstcs::acntMapPtr)[userName]);
......@@ -419,12 +417,18 @@ void Accounts::loadModelCounters(AccountListModel *accountModel)
}
}
bool Accounts::changeAccountUserName(const QString &originUserName,
const QString &newUserName, const QString &acntName)
bool Accounts::changeAccountUserName(AccountListModel *accountModel,
const QString &loginMetod, const QString &acntName,
const QString &newUserName, const QString &password,
bool isTestAccount, bool rememberPwd, bool storeToDisk,
const QString &certPath, const QString &oldUserName)
{
QString errTxt;
/* Show confirm dialogue about use name changing */
int msgResponse = Dialogues::message(Dialogues::QUESTION,
tr("Change user name: %1").arg(originUserName),
tr("Do you want to change user name from '%1' to '%2' of account '%3'?").arg(originUserName).arg(newUserName).arg(acntName),
tr("Change user name: %1").arg(oldUserName),
tr("Do you want to change user name from '%1' to '%2' of account '%3'?").arg(oldUserName).arg(newUserName).arg(acntName),
tr("Note: It will also change all related local database names and account information."),
Dialogues::NO | Dialogues::YES, Dialogues::NO);
if (msgResponse == Dialogues::NO) {
......@@ -433,97 +437,134 @@ bool Accounts::changeAccountUserName(const QString &originUserName,
/* Check if new user name has correct length */
if (newUserName.length() != 6) {
logErrorNL("Username '%s' has wrong length!",
errTxt = tr("User name '%1' has wrong length.").arg(newUserName);
logErrorNL("User name '%s' has wrong length.",
newUserName.toUtf8().constData());
return false;
goto fail;
}
/* Check if new user name is not exists in the database */
/* Check if new user name does not exist in the database */
if (GlobInstcs::acntMapPtr->contains(newUserName)) {
logErrorNL("Username '%s' already exists!",
errTxt = tr("User name '%1' already exists.").arg(newUserName);
logErrorNL("User name '%s' already exists.",
newUserName.toUtf8().constData());
return false;
goto fail;
}
/* Change user name in the account database */
if (!GlobInstcs::accountDbPtr->changeUserName(originUserName, newUserName)) {
logErrorNL("%s", "Could not change user name in the account database.");
return false;
/* First: Change user name in the account database (user_info, account_info) */
if (!GlobInstcs::accountDbPtr->changeUserName(oldUserName, newUserName)) {
errTxt = tr("Cannot change user name '%1' in the account database.").arg(newUserName);
logErrorNL("%s", "Cannot change user name in the account database.");
goto fail;
}
/* Update user name in the account map and settings */
AcntData &acntData((*GlobInstcs::acntMapPtr)[originUserName]);
acntData.setUserName(newUserName);
/* Second: Change file database name or rollback in an error */
{
FileDb *fDb = GlobInstcs::fileDbsPtr->accessFileDb(
GlobInstcs::setPtr->dbsLocation, oldUserName, storeToDisk);
if (fDb == Q_NULLPTR) {
errTxt = tr("Cannot access file database for the user name '%1'.").arg(oldUserName);
logErrorNL("Cannot access file database for %s.",
oldUserName.toUtf8().constData());
goto backAccountChanges;
}
QString currentDbFileName = fDb->fileName();
currentDbFileName.replace(oldUserName, newUserName);
if (!fDb->moveDb(currentDbFileName)) {
errTxt = tr("Cannot change file database on the user name '%1'.").arg(newUserName);
logErrorNL("Cannot change file database on the user name %s.",
newUserName.toUtf8().constData());
goto backAccountChanges;
}
}
/* Third: Change message database name or rollback in an error */
{
/* Change message database name */
MessageDb *msgDb = GlobInstcs::messageDbsPtr->accessMessageDb(
GlobInstcs::setPtr->dbsLocation, originUserName,
(*GlobInstcs::acntMapPtr)[originUserName].storeToDisk());
GlobInstcs::setPtr->dbsLocation, oldUserName, storeToDisk);
if (msgDb == Q_NULLPTR) {
errTxt = tr("Cannot access message database for user name '%1'.").arg(oldUserName);
logErrorNL("Cannot access message database for %s.",
originUserName.toUtf8().constData());
goto backAccount;
oldUserName.toUtf8().constData());
goto backFilesChanges;
}
QString currentDbFileName = msgDb->fileName();
currentDbFileName.replace(originUserName, newUserName);
currentDbFileName.replace(oldUserName, newUserName);
if (!msgDb->moveDb(currentDbFileName)) {
goto backAccount;
errTxt = tr("Cannot change message database on the user name '%1'.").arg(newUserName);
logErrorNL("Cannot change message database on the user name %s.",
newUserName.toUtf8().constData());
goto backFilesChanges;
}
}
/* Final: Create new account with new user name and insert to map */
{
/* Change file database name */
FileDb *fDb = GlobInstcs::fileDbsPtr->accessFileDb(
GlobInstcs::setPtr->dbsLocation, originUserName,
(*GlobInstcs::acntMapPtr)[originUserName].storeToDisk());
if (fDb == Q_NULLPTR) {
logErrorNL("Cannot access file database for %s.",
originUserName.toUtf8().constData());
goto backMessage;
}
QString currentDbFileName = fDb->fileName();
currentDbFileName.replace(originUserName, newUserName);
if (!fDb->moveDb(currentDbFileName)) {
goto backMessage;
AcntData acntData;
acntData.setAccountName(acntName);
acntData.setUserName(newUserName);
acntData.setPassword(password);
acntData.setLoginMethod(loginMetod);
acntData.setTestAccount(isTestAccount);
acntData.setRememberPwd(rememberPwd);
acntData.setStoreToDisk(storeToDisk);
acntData.setCertPath(certPath);
/* Add account data to model */
if (accountModel->addAccount(acntData) == AccountListModel::AA_SUCCESS) {
/* Delete isds session context of old account */
emit removeIsdsCtx(oldUserName);
/* Remove old account */
accountModel->deleteAccount(oldUserName);
/* Load message counters of new account */
loadModelCounters(accountModel);
}
}
logInfoNL("Username has been changed on '%s'.",
newUserName.toUtf8().constData());
Dialogues::errorMessage(Dialogues::INFORMATION,
tr("Change user name: %1").arg(oldUserName),
tr("The new user name '%1' for account '%2' has been set.").arg(newUserName).arg(acntName),
tr("Account will use the new settings."));
return true;
backMessage:
backFilesChanges:
{
/* Change back message database name */
MessageDb *msgDb = GlobInstcs::messageDbsPtr->accessMessageDb(
GlobInstcs::setPtr->dbsLocation, newUserName,
(*GlobInstcs::acntMapPtr)[newUserName].storeToDisk());
if (msgDb == Q_NULLPTR) {
logErrorNL("Cannot access message database for %s.",
/* Change back file database name */
FileDb *fDb = GlobInstcs::fileDbsPtr->accessFileDb(
GlobInstcs::setPtr->dbsLocation, newUserName, storeToDisk);
if (fDb == Q_NULLPTR) {
logErrorNL("Cannot access file database for %s.",
newUserName.toUtf8().constData());
}
QString currentDbFileName = msgDb->fileName();
currentDbFileName.replace(newUserName, originUserName);
msgDb->moveDb(currentDbFileName);
QString currentDbFileName = fDb->fileName();
currentDbFileName.replace(newUserName, oldUserName);
if (!fDb->moveDb(currentDbFileName)) {
logErrorNL("Cannot change back file database name %s.",
oldUserName.toUtf8().constData());
}
}
backAccount:
backAccountChanges:
/* Change back user name in the account database */
if (!GlobInstcs::accountDbPtr->changeUserName(newUserName, originUserName)) {
logErrorNL("%s", "Could not change user name in the account database.");
if (!GlobInstcs::accountDbPtr->changeUserName(newUserName, oldUserName)) {
logErrorNL("%s", "Cannot change back user name in the account database.");
}
fail:
Dialogues::errorMessage(Dialogues::CRITICAL,
tr("User name problem: %1").arg(originUserName),
tr("User name problem: %1").arg(oldUserName),
tr("The new user name '%1' for account '%2' has not been set!").arg(newUserName).arg(acntName),
tr("Account will use the origin settings."));
errTxt + " " +tr("Account will use the original settings."));
return false;
}
......@@ -8,7 +8,7 @@
*
* 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
* 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
......@@ -122,7 +122,7 @@ public:
* @param[in] rememberPwd True if remember password.
* @param[in] storeToDisk True if database store to local storage.
* @param[in] certPath Certificate path (can be null).
* @param[in] originUserName Origin user name of account.
* @param[in] oldUserName Original user name of account.
* @return True if success.
*/
Q_INVOKABLE
......@@ -130,7 +130,7 @@ public:
const QString &loginMetod, const QString &acntName,
const QString &newUserName, const QString &pwd, bool isTestAccount,
bool rememberPwd, bool storeToDisk, const QString &certPath,
const QString &originUserName);
const QString &oldUserName);
/*!
* @brief Remove account.
......@@ -178,13 +178,23 @@ signals:
private:
/*!
* @brief Change account user name.
* @brief Change account user name and update account settings.
*
* @param[in] originUserName Origin user name of account.
* @param[in] newUserName New user name of account.
* @param[in,out] accountModel Holding account model.
* @param[in] loginMetod User name identifying account.
* @param[in] acntName Account name.
* @param[in] newUserName User name identifying account.
* @param[in] password Password.
* @param[in] isTestAccount True if account is isds test enveiroment.
* @param[in] rememberPwd True if remember password.
* @param[in] storeToDisk True if database store to local storage.
* @param[in] certPath Certificate path (can be null).
* @param[in] oldUserName Original user name of account.
* @return True if success.
*/
bool changeAccountUserName(const QString &originUserName,
const QString &newUserName, const QString &acntName);
bool changeAccountUserName(AccountListModel *accountModel,
const QString &loginMetod, const QString &acntName,
const QString &newUserName, const QString &password,
bool isTestAccount, bool rememberPwd, bool storeToDisk,
const QString &certPath, const QString &oldUserName);
};
......@@ -8,7 +8,7 @@
*
* 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
* 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
......
......@@ -8,7 +8,7 @@
*
* 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
* 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
......@@ -727,24 +727,25 @@ void AccountListModel::saveAccountsToSettings(const QString &pinVal,
}
}
int AccountListModel::addAccount(const AcntData &acntData, QModelIndex *idx)
enum AccountListModel::AddAcntResult AccountListModel::addAccount(
const AcntData &acntData, QModelIndex *idx)
{
if (Q_UNLIKELY(m_accountsPtr == Q_NULLPTR)) {
Q_ASSERT(0);
return -1;
return AA_ERR;
}
const QString userName(acntData.userName());
if (userName.isEmpty()) {
Q_ASSERT(0);
return -1;
return AA_ERR;
}
if (m_accountsPtr->contains(userName)) {
logWarningNL("Account with username '%s' already exists.",
userName.toUtf8().constData());
return -2;
return AA_EXISTS;
}
Q_ASSERT(!m_userNames.contains(userName));
......@@ -761,7 +762,7 @@ int AccountListModel::addAccount(const AcntData &acntData, QModelIndex *idx)
*idx = index(m_userNames.size() - 1, 0, QModelIndex());
}
return 0;
return AA_SUCCESS;
}
void AccountListModel::deleteAccount(const QString &userName)
......
......@@ -8,7 +8,7 @@
*
* 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
* 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
......@@ -152,6 +152,15 @@ public:
};
Q_ENUM(Roles)
/*!
* @brief Return add account result.
*/
enum AddAcntResult {
AA_SUCCESS = 0, /*!< Operation was successful. */
AA_EXISTS, /*!< Account already exists in the model. */
AA_ERR /*!< Internal error. */
};
/* Don't forget to declare various properties to the QML system. */
static
void declareQML(void);
......@@ -239,12 +248,11 @@ public:
* @brief Add account.
*
* @patam[in] acntSettings Settings data to be added into the model.
* @param[out] idx Index of newly added account if specified.
* @return -2 if account already exists,
* -1 if account could not be added,
* 0 if account was added.
* @param[out] idx Index of newly added account if specified.
* @return Error state.
*/
int addAccount(const AcntData &acntData, QModelIndex *idx = Q_NULLPTR);
enum AddAcntResult addAccount(const AcntData &acntData,
QModelIndex *idx = Q_NULLPTR);
/*!
* @brief Delete account.
......
......@@ -8,7 +8,7 @@
*
* 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
* 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
......
......@@ -8,7 +8,7 @@
*
* 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
* 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
......
......@@ -8,7 +8,7 @@
*
* 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
* 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
......
......@@ -8,7 +8,7 @@
*
* 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
* 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
......
......@@ -8,7 +8,7 @@
*
* 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
* 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
......
......@@ -8,7 +8,7 @@
*
* 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
* 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
......
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