diff --git a/autotests/rocketchataccountsettingstest.cpp b/autotests/rocketchataccountsettingstest.cpp index a45e03ed..3c959858 100644 --- a/autotests/rocketchataccountsettingstest.cpp +++ b/autotests/rocketchataccountsettingstest.cpp @@ -1,215 +1,217 @@ /* Copyright (c) 2017-2019 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "rocketchataccountsettingstest.h" #include "rocketchataccountsettings.h" #include #include #include QTEST_GUILESS_MAIN(RocketChatAccountSettingsTest) RocketChatAccountSettingsTest::RocketChatAccountSettingsTest(QObject *parent) : QObject(parent) { QStandardPaths::setTestModeEnabled(true); } void RocketChatAccountSettingsTest::shouldNotEmitSignalWhenNewServerUrlIsSameAsOld() { RocketChatAccountSettings SampleChatAccount; const QString url = QStringLiteral("some.url.com"); SampleChatAccount.setServerUrl(url); QSignalSpy SpyURL(&SampleChatAccount, &RocketChatAccountSettings::serverURLChanged); SampleChatAccount.setServerUrl(url); QCOMPARE(SpyURL.count(), 0); } void RocketChatAccountSettingsTest::shouldEmitSignalWhenSetServerURLChanged() { RocketChatAccountSettings SampleChatAccount; QSignalSpy SpyURL(&SampleChatAccount, &RocketChatAccountSettings::serverURLChanged); const QString serverUrlDefault = QStringLiteral("bla bla"); SampleChatAccount.setServerUrl(serverUrlDefault); QCOMPARE(SpyURL.count(), 1); //Test same url SampleChatAccount.setServerUrl(serverUrlDefault); QCOMPARE(SpyURL.count(), 1); //Test Empty url - QString emptyString; + const QString emptyString; SampleChatAccount.setServerUrl(emptyString); QCOMPARE(SpyURL.count(), 2); SampleChatAccount.setServerUrl(emptyString); QCOMPARE(SpyURL.count(), 2); } void RocketChatAccountSettingsTest::shouldNotEmitSignalWhenNewUsernameIsSameAsOld() { RocketChatAccountSettings SampleChat; const QString username = QStringLiteral("dummyUsername"); SampleChat.setUserName(username); QSignalSpy SpyName(&SampleChat, &RocketChatAccountSettings::userNameChanged); SampleChat.setUserName(username); QCOMPARE(SpyName.count(), 0); } void RocketChatAccountSettingsTest::shouldEmitSignalWhenUserNameChanged() { RocketChatAccountSettings SampleChat; QSignalSpy SpyName(&SampleChat, &RocketChatAccountSettings::userNameChanged); const QString userNameDefault = QStringLiteral("Donald Knuth"); SampleChat.setUserName(userNameDefault); QCOMPARE(SpyName.count(), 1); //Test same name SampleChat.setUserName(userNameDefault); QCOMPARE(SpyName.count(), 1); //Test empty string - QString emptyString; + const QString emptyString; SampleChat.setUserName(emptyString); QCOMPARE(SpyName.count(), 2); SampleChat.setUserName(emptyString); QCOMPARE(SpyName.count(), 2); } void RocketChatAccountSettingsTest::shouldEmitSignalWhenUserIDChanged() { RocketChatAccountSettings SampleChat1; QSignalSpy SpyID(&SampleChat1, &RocketChatAccountSettings::userIDChanged); const QString userId = QStringLiteral("RA15"); QVERIFY(userId != SampleChat1.userId()); SampleChat1.setUserId(QStringLiteral("RA15")); QCOMPARE(SpyID.count(), 1); } void RocketChatAccountSettingsTest::shouldEmitSignalWhenLoginStatusChanged() { //TODO } void RocketChatAccountSettingsTest::shouldLogout() { RocketChatAccountSettings SampleChat; SampleChat.setAuthToken(QStringLiteral("Token305")); SampleChat.setUserId(QStringLiteral("ECE305")); SampleChat.setPassword(QStringLiteral("masterPassword")); //Make sure that values are not null QVERIFY(!SampleChat.authToken().isEmpty()); QVERIFY(!SampleChat.userId().isEmpty()); QVERIFY(!SampleChat.password().isEmpty()); SampleChat.logout(); QVERIFY(SampleChat.authToken().isEmpty()); QVERIFY(SampleChat.userId().isEmpty()); QVERIFY(SampleChat.password().isEmpty()); } void RocketChatAccountSettingsTest::shouldSetAccountName() { RocketChatAccountSettings sampleChat; QSignalSpy spy(&sampleChat, &RocketChatAccountSettings::accountNameChanged); - QString val = QStringLiteral("myAccount#$^56"); + const QString val = QStringLiteral("myAccount#$^56"); sampleChat.setAccountName(val); QCOMPARE(val, sampleChat.accountName()); QCOMPARE(spy.count(), 1); } void RocketChatAccountSettingsTest::shouldsetAuthToken() { RocketChatAccountSettings sampleChat; - QString val = QStringLiteral("myAuthToken#$^56"); + const QString val = QStringLiteral("myAuthToken#$^56"); sampleChat.setAuthToken(val); QCOMPARE(val, sampleChat.authToken()); } void RocketChatAccountSettingsTest::shouldSetPassword() { RocketChatAccountSettings sampleChat; - QString val = QStringLiteral("myPass#$^56"); + const QString val = QStringLiteral("myPass#$^56"); sampleChat.setPassword(val); QCOMPARE(val, sampleChat.password()); } void RocketChatAccountSettingsTest::shouldSetServerUrl() { RocketChatAccountSettings sampleChat; - QString val = QStringLiteral("my.fancy.url"); + const QString val = QStringLiteral("my.fancy.url"); sampleChat.setServerUrl(val); QCOMPARE(val, sampleChat.serverUrl()); } void RocketChatAccountSettingsTest::shouldSetUserID() { RocketChatAccountSettings sampleChat; - QString val = QStringLiteral("ECE305"); + const QString val = QStringLiteral("ECE305"); sampleChat.setUserId(val); QCOMPARE(val, sampleChat.userId()); } void RocketChatAccountSettingsTest::shouldSetUserName() { RocketChatAccountSettings sampleChat; - QString val = QStringLiteral("Eric Roberts"); + const QString val = QStringLiteral("Eric Roberts"); sampleChat.setUserName(val); QCOMPARE(val, sampleChat.userName()); } void RocketChatAccountSettingsTest::shouldHaveDefaultValues() { RocketChatAccountSettings chat; QVERIFY(chat.accountName().isEmpty()); QVERIFY(chat.authToken().isEmpty()); QVERIFY(!chat.cacheBasePath().isEmpty()); QVERIFY(chat.userId().isEmpty()); QVERIFY(chat.userName().isEmpty()); QVERIFY(chat.password().isEmpty()); QVERIFY(!chat.serverUrl().isEmpty()); QVERIFY(chat.userId().isEmpty()); QVERIFY(chat.userName().isEmpty()); QVERIFY(chat.authToken().isEmpty()); QCOMPARE(chat.serverUrl(), QStringLiteral("open.rocket.chat")); QVERIFY(!chat.showUnreadOnTop()); + QVERIFY(chat.twoFactorAuthenticationCode().isEmpty()); + QVERIFY(chat.enabled()); } diff --git a/src/ruqolacore/rocketchataccountsettings.cpp b/src/ruqolacore/rocketchataccountsettings.cpp index 1b4a6952..5eaca3eb 100644 --- a/src/ruqolacore/rocketchataccountsettings.cpp +++ b/src/ruqolacore/rocketchataccountsettings.cpp @@ -1,275 +1,285 @@ /* Copyright (c) 2017-2019 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "rocketchataccountsettings.h" #include "managerdatapaths.h" #include "ruqola_debug.h" #include #include #include #include #include #if HAVE_QT5KEYCHAIN #include using namespace QKeychain; #endif RocketChatAccountSettings::RocketChatAccountSettings(const QString &accountFileName, QObject *parent) : QObject(parent) { initializeSettings(accountFileName); } RocketChatAccountSettings::~RocketChatAccountSettings() { mSetting->sync(); delete mSetting; } void RocketChatAccountSettings::initializeSettings(const QString &accountFileName) { delete mSetting; mSetting = new QSettings(accountFileName, QSettings::IniFormat); qCDebug(RUQOLA_LOG) << "accountFileName "<value(QStringLiteral("serverURL"), QStringLiteral("open.rocket.chat")).toString(); mUserName = mSetting->value(QStringLiteral("username")).toString(); mUserId = mSetting->value(QStringLiteral("userID")).toString(); mAuthToken = mSetting->value(QStringLiteral("authToken")).toString(); mExpireToken = mSetting->value(QStringLiteral("expireToken")).toLongLong(); mAccountName = mSetting->value(QStringLiteral("accountName")).toString(); mShowUnreadOnTop = mSetting->value(QStringLiteral("showunreadontop")).toBool(); #if HAVE_QT5KEYCHAIN auto readJob = new ReadPasswordJob(QStringLiteral("Ruqola"), this); connect(readJob, &Job::finished, this, &RocketChatAccountSettings::slotPasswordRead); readJob->setKey(mAccountName); readJob->start(); #endif } void RocketChatAccountSettings::slotPasswordRead(QKeychain::Job *baseJob) { #if HAVE_QT5KEYCHAIN ReadPasswordJob *job = qobject_cast(baseJob); Q_ASSERT(job); if (!job->error()) { mPassword = job->textData(); qCDebug(RUQOLA_LOG) << "OK, we have the password now"; Q_EMIT passwordChanged(); } #else Q_UNUSED(baseJob); #endif } void RocketChatAccountSettings::slotPasswordWritten(QKeychain::Job *baseJob) { #if HAVE_QT5KEYCHAIN if (baseJob->error()) { qCWarning(RUQOLA_LOG) << "Error writing password using QKeychain:" << baseJob->errorString(); } #endif } +bool RocketChatAccountSettings::enabled() const +{ + return mEnabled; +} + +void RocketChatAccountSettings::setEnabled(bool enabled) +{ + mEnabled = enabled; +} + qint64 RocketChatAccountSettings::expireToken() const { return mExpireToken; } void RocketChatAccountSettings::setExpireToken(const qint64 &expireToken) { if (mExpireToken != expireToken) { mExpireToken = expireToken; mSetting->setValue(QStringLiteral("expireToken"), mExpireToken); mSetting->sync(); } } bool RocketChatAccountSettings::tokenExpired() const { return mExpireToken < QDateTime::currentDateTime().toMSecsSinceEpoch(); } bool RocketChatAccountSettings::showUnreadOnTop() const { return mShowUnreadOnTop; } bool RocketChatAccountSettings::setShowUnreadOnTop(bool showUnreadOnTop) { if (mShowUnreadOnTop != showUnreadOnTop) { mShowUnreadOnTop = showUnreadOnTop; mSetting->setValue(QStringLiteral("showunreadontop"), mShowUnreadOnTop); mSetting->sync(); return true; } return false; } QString RocketChatAccountSettings::userId() const { return mUserId; } void RocketChatAccountSettings::setUserId(const QString &userId) { //Don't use if( m_userID != userID) as we need to Q_EMIT userIDChanged mUserId = userId; mSetting->setValue(QStringLiteral("userID"), userId); mSetting->sync(); Q_EMIT userIDChanged(); } QString RocketChatAccountSettings::authToken() const { return mAuthToken; } void RocketChatAccountSettings::setAuthToken(const QString &authToken) { if (mAuthToken != authToken) { qCDebug(RUQOLA_LOG) << "Setting token to" << authToken; mAuthToken = authToken; mSetting->setValue(QStringLiteral("authToken"), authToken); } } void RocketChatAccountSettings::logout() { mSetting->setValue(QStringLiteral("authToken"), QString()); mSetting->setValue(QStringLiteral("expireToken"), -1); mSetting->sync(); mAuthToken.clear(); mUserId.clear(); mPassword.clear(); mExpireToken = -1; } QString RocketChatAccountSettings::password() const { return mPassword; } void RocketChatAccountSettings::setPassword(const QString &password) { mPassword = password; #if HAVE_QT5KEYCHAIN auto writeJob = new WritePasswordJob(QStringLiteral("Ruqola"), this); connect(writeJob, &Job::finished, this, &RocketChatAccountSettings::slotPasswordWritten); writeJob->setKey(mAccountName); writeJob->setTextData(mPassword); writeJob->start(); #endif Q_EMIT passwordChanged(); } QString RocketChatAccountSettings::twoFactorAuthenticationCode() const { return mTwoFactorAuthenticationCode; } void RocketChatAccountSettings::setTwoFactorAuthenticationCode(const QString &twoFactorAuthenticationCode) { if (mTwoFactorAuthenticationCode != twoFactorAuthenticationCode) { mTwoFactorAuthenticationCode = twoFactorAuthenticationCode; Q_EMIT twoFactorAuthenticationCodeChanged(); } } QString RocketChatAccountSettings::userName() const { return mUserName; } void RocketChatAccountSettings::setUserName(const QString &userName) { if (mUserName != userName) { mUserName = userName; mSetting->setValue(QStringLiteral("username"), mUserName); mSetting->sync(); Q_EMIT userNameChanged(); } } QString RocketChatAccountSettings::accountName() const { return mAccountName; } void RocketChatAccountSettings::setAccountName(const QString &accountName) { if (mAccountName == accountName) { return; } initializeSettings(ManagerDataPaths::self()->accountConfigFileName(accountName)); mSetting->setValue(QStringLiteral("accountName"), accountName); mSetting->sync(); mAccountName = accountName; Q_EMIT accountNameChanged(); } QString RocketChatAccountSettings::serverUrl() const { return mServerUrl; } void RocketChatAccountSettings::setServerUrl(const QString &serverUrl) { if (mServerUrl == serverUrl) { return; } mSetting->setValue(QStringLiteral("serverURL"), serverUrl); mSetting->sync(); mServerUrl = serverUrl; Q_EMIT serverURLChanged(); } QString RocketChatAccountSettings::cacheBasePath() { if (mServerUrl.isEmpty()) { return QString(); } if (mCachePath.isEmpty()) { mCachePath = ManagerDataPaths::self()->path(ManagerDataPaths::Cache, mAccountName); } return mCachePath; } void RocketChatAccountSettings::removeSettings() { //Delete password #if HAVE_QT5KEYCHAIN auto deleteJob = new DeletePasswordJob(QStringLiteral("Ruqola")); deleteJob->setKey(mAccountName); deleteJob->setAutoDelete(true); deleteJob->start(); #endif QFile f(mSetting->fileName()); if (!f.remove()) { qCWarning(RUQOLA_LOG) << "Impossible to delete config file: " << mSetting->fileName(); } } diff --git a/src/ruqolacore/rocketchataccountsettings.h b/src/ruqolacore/rocketchataccountsettings.h index f5be3eec..8b98d0c5 100644 --- a/src/ruqolacore/rocketchataccountsettings.h +++ b/src/ruqolacore/rocketchataccountsettings.h @@ -1,100 +1,104 @@ /* Copyright (c) 2017-2019 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ROCKETCHATACCOUNTSETTINGS_H #define ROCKETCHATACCOUNTSETTINGS_H #include #include #include "libruqola_private_export.h" namespace QKeychain { class Job; } class QSettings; class LIBRUQOLACORE_EXPORT RocketChatAccountSettings : public QObject { Q_OBJECT public: explicit RocketChatAccountSettings(const QString &accountFileName = QString(), QObject *parent = nullptr); ~RocketChatAccountSettings(); Q_REQUIRED_RESULT QString userId() const; void setUserId(const QString &userId); Q_REQUIRED_RESULT QString authToken() const; void setAuthToken(const QString &authToken); Q_REQUIRED_RESULT QString serverUrl() const; void setServerUrl(const QString &serverUrl); Q_REQUIRED_RESULT QString accountName() const; void setAccountName(const QString &accountName); void logout(); Q_REQUIRED_RESULT QString cacheBasePath(); Q_REQUIRED_RESULT QString userName() const; void setUserName(const QString &userName); Q_REQUIRED_RESULT QString password() const; void setPassword(const QString &password); Q_REQUIRED_RESULT QString twoFactorAuthenticationCode() const; void setTwoFactorAuthenticationCode(const QString &twoFactorAuthenticationCode); void removeSettings(); Q_REQUIRED_RESULT bool showUnreadOnTop() const; bool setShowUnreadOnTop(bool showUnreadOnTop); Q_REQUIRED_RESULT qint64 expireToken() const; void setExpireToken(const qint64 &expireToken); Q_REQUIRED_RESULT bool tokenExpired() const; + Q_REQUIRED_RESULT bool enabled() const; + void setEnabled(bool enabled); + Q_SIGNALS: void serverURLChanged(); void userNameChanged(); void userIDChanged(); void accountNameChanged(); void passwordChanged(); void twoFactorAuthenticationCodeChanged(); private: Q_DISABLE_COPY(RocketChatAccountSettings) void initializeSettings(const QString &accountFileName); void slotPasswordRead(QKeychain::Job *job); void slotPasswordWritten(QKeychain::Job *job); QString mUserId; QString mAuthToken; QString mServerUrl; QString mAccountName; QString mCachePath; QString mUserName; QString mPassword; QString mTwoFactorAuthenticationCode; qint64 mExpireToken = -1; QSettings *mSetting = nullptr; bool mShowUnreadOnTop = false; + bool mEnabled = true; }; #endif // ROCKETCHATACCOUNTSETTINGS_H