accountmodel.h 8.94 KB
Newer Older
1
/*
2
 * Copyright (C) 2014-2018 CZ.NIC
3 4 5 6 7 8 9 10
 *
 * 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
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 13 14 15 16 17 18 19 20 21 22 23
 * 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.
 */

24
#pragma once
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

#include <QAbstractListModel>
#include <QSettings>

class AcntData {
public:
	AcntData(void);
	AcntData(const AcntData &ad);

	bool isValid(void) const;
	QString accountName(void) const;
	void setAccountName(const QString &name);
	QString userName(void) const;
	void setUserName(const QString &userName);
	QString loginMethod(void) const;
	void setLoginMethod(const QString &method);
	QString password(void) const;
	void setPassword(const QString &pwd);
43
	QString pwdAlg(void) const;
44
	void setPwdAlg(const QString &pwdAlg);
45
	QByteArray pwdSalt(void) const;
46
	void setPwdSalt(const QByteArray &pwdSalt);
47
	QByteArray pwdIv(void) const;
48 49 50
	void setPwdIv(const QByteArray &pwdIv);
	QByteArray pwdCode(void) const;
	void setPwdCode(const QByteArray &pwdCode);
51 52 53 54 55
	bool isTestAccount(void) const;
	void setTestAccount(bool isTesting);
	bool rememberPwd(void) const;
	void setRememberPwd(bool remember);
	bool storeToDisk(void) const;
56
	void setStoreToDisk(bool storeToDisk);
57 58 59 60 61
	QString certPath(void) const;
	void setCertPath(const QString &certPath);
	QString _passPhrase(void) const;
	void _setPassPhrase(const QString &passphrase);

62 63 64 65 66 67 68 69 70 71
	/*!
	 * @brief Used to change the password encryption key.
	 *
	 * @note This function must be called whenever PIN data are changed.
	 *
	 * @param[in] oldPin PIN value used to decrypt old passwords.
	 * @param[in] newPin New PIN value.
	 */
	void recomputePwd(const QString &oldPin, const QString &newPin);

72 73 74 75 76
private:
	QString m_acntName; /*!< Account name. */
	QString m_userName; /*!< User name. */
	QString m_loginMethod; /*!< Login method. */
	QString m_password; /*!< Password. */
77 78 79
	QString m_pwdAlg; /*!< Password encryption algorithm. */
	QByteArray m_pwdSalt; /*!< Password salt used to compute key from PIN. */
	QByteArray m_pwdIv; /*!< Password cryptographic algorithm initialisation vector. */
80
	QByteArray m_pwdCode; /*!< Encrypted password. */
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
	bool m_isTestAccount; /*!< Whether this is a testing account. */
	bool m_rememberPwd; /*!< Whether to remember password. */
	bool m_storeToDisk; /*!< Whether to store messages in local storage. */
	QString m_certPath; /*!< Certificate location. */

	QString _m_passPhrase; /*!< Certificate pass-phrase, is not saved. */

protected:
	/*
	 * Values below here are displayed, but have nothing to do with
	 * actual account.
	 *
	 * TODO -- Move it somewhere into the model.
	 */
	int _receivedNew;
	int _receivedTotal;
97
	int _sentNew;
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
	int _sentTotal;

	friend class AccountListModel;
};

/*!
 * @brief Associative array mapping user name to settings.
 */
class AccountsMap : public QObject, public QMap<QString, AcntData> {
    Q_OBJECT

public:
	/*!
	 * @brief Load data from supplied settings.
	 */
	void loadAccountsFromSettings(const QSettings &settings);

115 116 117 118 119 120 121
	/*!
	 * @brief Decrypts all encrypted passwords.
	 *
	 * @param[in] pinVal Pin value.
	 */
	void decryptAllPwds(const QString &pinVal);

122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
signals:
	/*!
	 * @brief Notifies that account data have changed.
	 *
	 * @note Currently the signal must be triggered manually.
	 *
	 * @param[in] userName User name.
	 */
	void accountDataChanged(const QString &userName);
};

/*!
 * @brief Account hierarchy.
 */
class AccountListModel : public QAbstractListModel {
    Q_OBJECT

public:
	/*!
	 * @brief Roles which this model supports.
	 */
	enum Roles {
		ROLE_ACCOUNT_NAME = Qt::UserRole,
		ROLE_USER_NAME,
		ROLE_TEST_ACCOUNT,
147
		ROLE_STORE_INTO_DB,
148 149
		ROLE_RECEIVED_UNREAD,
		ROLE_RECEIVED_TOTAL,
150
		ROLE_SENT_UNREAD,
151 152
		ROLE_SENT_TOTAL
	};
153 154
	Q_ENUM(Roles)

155 156 157 158 159 160 161 162 163
	/*!
	 * @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. */
	};

164 165 166
	/* Don't forget to declare various properties to the QML system. */
	static
	void declareQML(void);
167 168 169 170 171 172

	/*!
	 * @brief Constructor.
	 *
	 * @param[in] parent Pointer to parent object.
	 */
173 174 175 176 177 178 179 180 181 182 183 184
	explicit AccountListModel(QObject *parent = Q_NULLPTR);

	/*!
	 * @brief Copy constructor.
	 *
	 * @note Needed for QVariant conversion.
	 *
	 * @param[in] model Model to be copied.
	 * @param[in] parent Pointer to parent object.
	 */
	explicit AccountListModel(const AccountListModel &model,
	    QObject *parent = Q_NULLPTR);
185

186 187 188 189 190 191 192
	/*!
	 * @brief Set account map to be the source of data for the model.
	 *
	 * @param[in] accounts Pointer to account map.
	 */
	void setAccounts(AccountsMap *accounts);

193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
	/*!
	 * @brief Return number of rows under the given parent.
	 *
	 * @param[in] parent Parent node index.
	 * @return Number of rows.
	 */
	virtual
	int rowCount(const QModelIndex &parent = QModelIndex()) const
	    Q_DECL_OVERRIDE;

	/*!
	 * @brief Returns the model's role names.
	 *
	 * @return Model's role names.
	 */
	virtual
	QHash<int, QByteArray> roleNames(void) const Q_DECL_OVERRIDE;

	/*!
	 * @brief Return data stored in given location under given role.
	 *
	 * @param[in] index Index specifying the item.
	 * @param[in] role  Data role.
	 * @return Data from model.
	 */
	virtual
	QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE;

	/*!
	 * @brief Returns item flags for given index.
	 *
	 * @brief[in] index Index specifying the item.
	 * @return Item flags.
	 */
	virtual
	Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE;

	/*!
	 * @brief Load data from supplied settings.
	 *
	 * @param[in] settings Settings structure to be read.
	 */
	void loadAccountsFromSettings(const QSettings &settings);

	/*!
	 * @brief Store data to settings structure.
	 *
240
	 * @param[in]  pinVal PIN value to encrypt passwords with.
241 242 243
	 * @param[out] settings Setting structure to store the model content
	 *     into.
	 */
244 245
	void saveAccountsToSettings(const QString &pinVal,
	    QSettings &settings) const;
246 247 248 249 250

	/*!
	 * @brief Add account.
	 *
	 * @patam[in]  acntSettings Settings data to be added into the model.
251 252
	 * @param[out] idx Index of newly added account if specified.
	 * @return Error state.
253
	 */
254 255
	enum AddAcntResult addAccount(const AcntData &acntData,
	    QModelIndex *idx = Q_NULLPTR);
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288

	/*!
	 * @brief Delete account.
	 *
	 * @param[in] userName User name.
	 */
	void deleteAccount(const QString &userName);

	/*!
	 * @brief Returns user name for given node.
	 *
	 * @param[in] index Data index.
	 * @return User name of the account which the node belongs to
	 *     or null string on error.
	 */
	QString userName(const QModelIndex &index) const;

	/*!
	 * @brief Returns node related to user name.
	 *
	 * @param[in] userName Sought user name.
	 * @return Top node index or invalid index if no such name found.
	 */
	QModelIndex acntIndex(const QString &userName) const;

	/*!
	 * @brief Updates counters that are displayed by the model.
	 *
	 * @note Negative values are ignored.
	 *
	 * @param[in] userName User name.
	 * @param[in] recNew   Received new.
	 * @param[in] recTot   Received total.
289
	 * @param[in] sntNew   Sent new.
290 291 292
	 * @param[in] sntTot   Sent total.
	 */
	void updateCounters(const QString &userName, int recNew, int recTot,
293
	    int sntNew, int sntTot);
294

295 296 297 298 299 300 301 302 303 304 305 306 307 308
	/*!
	 * @brief Converts QVariant obtained from QML into model pointer.
	 *
	 * @note Some weird stuff happens in QML when passing attachment model
	 *     directly as constant reference. Wrong constructors are called
	 *     and no data are passed. That's because we are using a QVariant.
	 *     This function does not allocate a new model.
	 *
	 * @param[in] modelVariant QVariant holding the model.
	 * @return Pointer to model if it could be acquired, Q_NULLPTR else.
	 */
	static
	AccountListModel *fromVariant(const QVariant &modelVariant);

309 310 311 312 313 314 315 316 317 318
private slots:
	/*!
	 * @brief This slot handles changes of account data.
	 *
	 * @param[in] userName User name defining the changed account.
	 */
	void handleAccountDataChange(const QString &userName);

private:
	QList<QString> m_userNames; /*!<
319 320 321
	                             * List of user names,
	                             * defines the ordering of the model.
	                             */
322
	AccountsMap *m_accountsPtr; /*!< Pointer to account data container. */
323 324
};

325 326 327
/* QML passes its arguments via QVariant. */
Q_DECLARE_METATYPE(AccountListModel)
Q_DECLARE_METATYPE(AccountListModel::Roles)