accounts.cpp 12 KB
Newer Older
1
/*
2
 * Copyright (C) 2014-2017 CZ.NIC
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 *
 * 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.
 */

#include <QDebug>
#include <QSettings>
#include <QUrl>

#include "src/accounts.h"
#include "src/common.h"
30
#include "src/dialogues/dialogues.h"
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
#include "src/net/isds_wrapper.h"
#include "src/net/isds_session.h"
#include "src/settings.h"
#include "src/sqlite/account_db.h"
#include "src/models/accountmodel.h"
#include "src/sqlite/message_db_container.h"
#include "src/sqlite/file_db_container.h"

Accounts::Accounts(QObject *parent) : QObject(parent)
{
}

/* ========================================================================= */
/*
 * Slot: Update new message counter.
 */
void Accounts::updateNewMessageCounter(const QString &userName)
/* ========================================================================= */
{
	qDebug("%s()", __func__);

	MessageDb *msgDb = NULL;
53 54
	msgDb = globMessageDbsPtr->accessMessageDb(globSet.dbsLocation, userName,
	    AccountListModel::globAccounts[userName].storeToDisk());
55 56
	if (msgDb == NULL) {
		qDebug() << "ERROR: Message database cannot open!";
57
		return;
58 59 60
	}

	globAccountsModelPtr->updateCounters(userName,
61 62
	    msgDb->getCntOfNewMsgs(MessageDb::TYPE_RECEIVED), -1,
	    msgDb->getCntOfNewMsgs(MessageDb::TYPE_SENT), -1);
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
}


/* ========================================================================= */
/*
 * Slot: Remove account.
 */
void Accounts::getAccountData(const QString &userName)
/* ========================================================================= */
{
	qDebug("%s()", __func__);

	if (!AccountListModel::globAccounts.contains(userName)) {
		return;
	}

	const AcntData &acntData(AccountListModel::globAccounts[userName]);

	/* Set login method model index for combobox in QML page.
	 * See AccountSettingsPage.qml for logim method order. Default is:
	 *    0 .. Username + Password
	 *    1 .. Certificate + Password
	 *    2 .. Password + Security code
	 *    3 .. Password + Security SMS
	 */
	int qmlLoginMethodIndex = 0;
	if (acntData.loginMethod() == USERNAME_PWD_CERT) {
		qmlLoginMethodIndex = 1;
	} else if (acntData.loginMethod() == USERNAME_PWD_HOTP) {
		qmlLoginMethodIndex = 2;
	} else if (acntData.loginMethod() == USERNAME_PWD_TOTP) {
		qmlLoginMethodIndex = 3;
	}

	emit sendAccountData(acntData.accountName(), userName,
	    qmlLoginMethodIndex, acntData.password(), acntData.isTestAccount(),
	    acntData.rememberPwd(), acntData.storeToDisk(), acntData.certPath());
}


/* ========================================================================= */
/*
 * Slot: Remove account.
 */
107
bool Accounts::removeAccount(const QString &userName, bool showDialog)
108 109 110 111
/* ========================================================================= */
{
	qDebug("%s()", __func__);

112
	if (showDialog) {
113
		int msgResponse = Dialogues::message(Dialogues::QUESTION,
114 115 116
		    tr("Remove account: %1").arg(userName),
		    tr("Do you want to remove the account '%1'?").arg(userName),
		    tr("Note: It will also remove all related local databases and account information."),
117 118
		    Dialogues::NO | Dialogues::YES, Dialogues::NO);
		if (msgResponse == Dialogues::NO) {
119
			return false;
120
		}
121 122 123
	}

	if (!AccountListModel::globAccounts.contains(userName)) {
124
		return false;
125 126 127 128
	}

	/* Delete file database */
	FileDb *fDb = NULL;
129 130
	fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation, userName,
	    AccountListModel::globAccounts[userName].storeToDisk());
131 132
	if (fDb == NULL) {
		qDebug() << "ERROR: File database open error!";
133
		return false;
134 135 136
	}
	if (!globFileDbsPtr->deleteDb(fDb)) {
		qDebug() << "ERROR: File database could not delete!";
137
		return false;
138 139 140 141
	}

	/* Delete message database */
	MessageDb *msgDb = NULL;
142 143
	msgDb = globMessageDbsPtr->accessMessageDb(globSet.dbsLocation, userName,
	    AccountListModel::globAccounts[userName].storeToDisk());
144 145
	if (msgDb == NULL) {
		qDebug() << "ERROR: Message database open error!";
146
		return false;
147 148 149
	}
	if (!globMessageDbsPtr->deleteDb(msgDb)) {
		qDebug() << "ERROR: Message database could not delete!";
150
		return false;
151 152 153 154 155
	}

	/* Delete account info from account database */
	if (!globAccountDbPtr->deleteAccountInfoFromDb(userName)) {
		qDebug() << "ERROR: Account info could not delete!";
156
		return false;
157 158
	}

159 160 161
	/* Delete user info from account database */
	if (!globAccountDbPtr->deleteUserInfoFromDb(userName)) {
		qDebug() << "ERROR: User info could not delete!";
162
		return false;
163 164
	}

165 166 167 168 169 170
	/* Delete isds session context */
	emit removeIsdsCtx(userName);

	/* Delete account from settings */
	globAccountsModelPtr->deleteAccount(userName);
	saveAllSettings();
171 172

	return true;
173 174 175 176 177 178 179 180 181
}


/* ========================================================================= */
/*
 * Slot: Update account.
 */
void Accounts::updateAccount(const QString &loginMetod,
    const QString &acntName, const QString &userName,
182
    const QString &pwd, bool isTestAccount, bool rememberPwd,
183 184 185 186 187 188
    bool storeToDisk, const QString &certPath)
/* ========================================================================= */
{
	qDebug("%s()", __func__);

	if (acntName.isEmpty()) {
189
		Dialogues::errorMessage(Dialogues::CRITICAL,
190
		    tr("Problem while updating account"),
191
		    tr("Account name has not been specified!"),
192
		    tr("This field must be filled in."));
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
		return;
	}

	if (!AccountListModel::globAccounts.contains(userName)) {
		return;
	}

	AcntData &acntData(AccountListModel::globAccounts[userName]);

	/* update account map */
	acntData.setLoginMethod(loginMetod);
	acntData.setAccountName(acntName.trimmed());
	acntData.setPassword(pwd.trimmed());
	acntData.setTestAccount(isTestAccount);
	acntData.setRememberPwd(rememberPwd);
208

209
	bool oldStoreToDisk = acntData.storeToDisk();
210
	/* Reopen database if storeToDisk changed. */
211 212
	if (acntData.storeToDisk() != storeToDisk) {
		MessageDb *mDb = globMessageDbsPtr->accessMessageDb(
213
		    globSet.dbsLocation, userName, oldStoreToDisk);
214 215 216
		if (mDb != NULL) {
			QString mDbFileName(mDb->fileName());
			/* Reopen database. */
217 218 219 220
			globMessageDbsPtr->deleteDb(mDb);
			globMessageDbsPtr->accessMessageDb(globSet.dbsLocation,
			    userName, storeToDisk);
			if (oldStoreToDisk) {
221 222 223 224
				/* Delete databases from storage. */
				QFile::remove(mDbFileName);
			}
		}
225
		FileDb *fDb = globFileDbsPtr->accessFileDb(
226
		    globSet.dbsLocation, userName, oldStoreToDisk);
227 228 229
		if (fDb != NULL) {
			QString fDbFileName(fDb->fileName());
			/* Reopen database. */
230 231 232 233
			globFileDbsPtr->deleteDb(fDb);
			globFileDbsPtr->accessFileDb(globSet.dbsLocation,
			    userName, storeToDisk);
			if (oldStoreToDisk) {
234 235 236
				/* Delete databases from storage. */
				QFile::remove(fDbFileName);
			}
237 238
		}

239 240
		/* Inform the model that message counters have changed. */
		globAccountsModelPtr->updateCounters(userName, 0, 0, 0, 0);
241
	}
242

243
	acntData.setStoreToDisk(storeToDisk);
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
	QUrl url(certPath, QUrl::TolerantMode);
	url.toLocalFile();
	acntData.setCertPath(url.toLocalFile());

	/* Model data have changed. */
	emit AccountListModel::globAccounts.accountDataChanged(userName);

	/* Delete isds session context */
	emit removeIsdsCtx(userName);

	/* update account data in settings */
	saveAllSettings();
}


/* ========================================================================= */
/*
 * Slot: Create account.
 */
263
bool Accounts::createAccount(const QString &loginMetod,
264 265 266 267 268 269 270 271
    const QString &acntName, const QString &userName,
    const QString &pwd, bool isTestAccount,  bool rememberPwd,
    bool storeToDisk, const QString &certPath)
/* ========================================================================= */
{
	qDebug("%s()", __func__);

	if (userName.isEmpty() || acntName.isEmpty()) {
272
		Dialogues::errorMessage(Dialogues::CRITICAL,
273
		    tr("Problem while creating account"),
274
		    tr("User name or account name has not been specified!"),
275
		    tr("These fields must be filled in."));
276
		return false;
277 278 279 280 281 282 283 284 285
	}

	AcntData acntData;
	acntData.setAccountName(acntName.trimmed());
	acntData.setUserName(userName.trimmed());
	acntData.setPassword(pwd.trimmed());
	acntData.setLoginMethod(loginMetod);
	acntData.setTestAccount(isTestAccount);
	acntData.setRememberPwd(rememberPwd);
286
	acntData.setStoreToDisk(storeToDisk);
287 288 289 290 291
	QUrl url(certPath, QUrl::TolerantMode);
	url.toLocalFile();
	acntData.setCertPath(url.toLocalFile());

	if (globAccountsModelPtr->addAccount(acntData) == -2) {
292
		Dialogues::errorMessage(Dialogues::CRITICAL,
293
		    tr("Creating account: %1").arg(userName),
294
		    tr("Account '%1' could not be created.").arg(acntName),
295
		    tr("Account with user name '%1' already exists.").arg(userName));
296
		return false;
297
	}
298 299

	return true;
300 301
}

302

303 304 305 306 307 308 309
/* ========================================================================= */
/*
 * Slot: Load account info from databse and fill QML page.
 */
void Accounts::saveAccountToSettings(void)
/* ========================================================================= */
{
310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
	saveAllSettings();
}


/* ========================================================================= */
/*
 * Slot: Load account info from databse and fill QML page.
 */
void Accounts::fillAccountInfo(const QString &userName)
/* ========================================================================= */
{
	 qDebug("%s()", __func__);

	QString html = globAccountDbPtr->getAccountDetail(userName);
	if (!html.isEmpty()) {
		emit accountDetailChanged(html);
	}
}


/* ========================================================================= */
/*
 * Slot: Load model counters.
 */
Karel Slaný's avatar
Karel Slaný committed
334
void Accounts::loadModelCounters(void)
335 336 337 338 339 340 341 342 343 344 345 346 347
/* ========================================================================= */
{
	 qDebug("%s()", __func__);

	for (int row = 0; row < globAccountsModelPtr->rowCount(); ++row) {
		const QString userName(globAccountsModelPtr->userName(
		    globAccountsModelPtr->index(row, 0)));
		if (userName.isEmpty()) {
			Q_ASSERT(0);
			continue;
		}

		MessageDb *msgDb = NULL;
348 349
		msgDb = globMessageDbsPtr->accessMessageDb(globSet.dbsLocation,
		    userName, AccountListModel::globAccounts[userName].storeToDisk());
350 351 352 353 354 355 356
		if (msgDb == NULL) {
			qWarning("Cannot open message database for '%s'.",
			    userName.toUtf8().constData());
			continue;
		}

		globAccountsModelPtr->updateCounters(userName,
357 358 359 360
		    msgDb->getCntOfNewMsgs(MessageDb::TYPE_RECEIVED),
		    msgDb->getMessageCount(MessageDb::TYPE_RECEIVED),
		    msgDb->getCntOfNewMsgs(MessageDb::TYPE_SENT),
		    msgDb->getMessageCount(MessageDb::TYPE_SENT));
361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
	}
}


/* ========================================================================= */
/*
 * Func: Return string of account storage.
 */
const QString Accounts::getStorageText(bool toDisk)
/* ========================================================================= */
{

	if (toDisk) return tr("local storage");
	return tr("data in memory");
}


/* ========================================================================= */
/*
 * Func: Return string of account type.
 */
const QString Accounts::getAccountTypeText(bool isTest)
/* ========================================================================= */
{

	if (isTest) return tr("Test account");
	return tr("Standard account");
}
389 390 391 392 393 394 395 396 397 398 399 400


/* ========================================================================= */
/*
 * Slot: Received save account request from QML.
 *	TODO - Must be replaced via better solution in the future.
 */
void Accounts::saveAccountRequest(void)
/* ========================================================================= */
{
	emit saveAccountResponse();
}