File indexing completed on 2024-12-08 10:25:53
0001 /* 0002 SPDX-FileCopyrightText: 2017-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "rocketchataccountsettings.h" 0008 #include "config-ruqola.h" 0009 #include "localdatabase/localdatabaseutils.h" 0010 #include "managerdatapaths.h" 0011 #include "ruqola_debug.h" 0012 #include "ruqola_password_core_debug.h" 0013 0014 #include <QDateTime> 0015 #include <QDir> 0016 #include <QFile> 0017 #include <QSettings> 0018 #include <QStandardPaths> 0019 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 0020 #include <qt5keychain/keychain.h> 0021 #else 0022 #include <qt6keychain/keychain.h> 0023 #endif 0024 using namespace QKeychain; 0025 0026 RocketChatAccountSettings::RocketChatAccountSettings(const QString &accountFileName, QObject *parent) 0027 : QObject(parent) 0028 { 0029 initializeSettings(accountFileName); 0030 } 0031 0032 RocketChatAccountSettings::~RocketChatAccountSettings() 0033 { 0034 mSetting->sync(); 0035 delete mSetting; 0036 } 0037 0038 bool RocketChatAccountSettings::isValid() const 0039 { 0040 return !mServerUrl.isEmpty() && !mUserName.isEmpty(); 0041 } 0042 0043 void RocketChatAccountSettings::initializeSettings(const QString &accountFileName) 0044 { 0045 delete mSetting; 0046 mSetting = new QSettings(accountFileName, QSettings::IniFormat); 0047 qCDebug(RUQOLA_LOG) << "accountFileName " << accountFileName; 0048 0049 mServerUrl = mSetting->value(QStringLiteral("serverURL"), QStringLiteral("open.rocket.chat")).toString(); 0050 mUserName = mSetting->value(QStringLiteral("username")).toString(); 0051 mUserId = mSetting->value(QStringLiteral("userID")).toString(); 0052 mAuthToken = mSetting->value(QStringLiteral("authToken")).toString(); 0053 mExpireToken = mSetting->value(QStringLiteral("expireToken")).toLongLong(); 0054 mAccountName = mSetting->value(QStringLiteral("accountName")).toString(); 0055 mUseLdap = mSetting->value(QStringLiteral("useLdap")).toBool(); 0056 mAccountEnabled = mSetting->value(QStringLiteral("enabled"), true).toBool(); 0057 mDisplayName = mSetting->value(QStringLiteral("displayName")).toString(); 0058 mLastCheckedPreviewUrlCacheDate = mSetting->value(QStringLiteral("lastCheckedPreviewUrlDate")).toDate(); 0059 0060 if (mAccountEnabled && !mAccountName.isEmpty()) { 0061 qCDebug(RUQOLA_PASSWORD_CORE_LOG) << "Load password from QKeychain: accountname " << mAccountName; 0062 auto readJob = new ReadPasswordJob(QStringLiteral("Ruqola"), this); 0063 connect(readJob, &Job::finished, this, &RocketChatAccountSettings::slotPasswordRead); 0064 readJob->setKey(mAccountName); 0065 readJob->start(); 0066 } 0067 } 0068 0069 void RocketChatAccountSettings::slotPasswordRead(QKeychain::Job *baseJob) 0070 { 0071 auto job = qobject_cast<ReadPasswordJob *>(baseJob); 0072 Q_ASSERT(job); 0073 if (!job->error()) { 0074 mPassword = job->textData(); 0075 qCDebug(RUQOLA_PASSWORD_CORE_LOG) << "OK, we have the password now"; 0076 Q_EMIT passwordChanged(); 0077 } else { 0078 qCWarning(RUQOLA_PASSWORD_CORE_LOG) << "We have an error during reading password " << job->errorString() << " Account name " << mAccountName; 0079 } 0080 } 0081 0082 void RocketChatAccountSettings::slotPasswordWritten(QKeychain::Job *baseJob) 0083 { 0084 if (baseJob->error()) { 0085 qCWarning(RUQOLA_PASSWORD_CORE_LOG) << "Error writing password using QKeychain:" << baseJob->errorString(); 0086 } 0087 } 0088 0089 QDate RocketChatAccountSettings::lastCheckedPreviewUrlCacheDate() const 0090 { 0091 return mLastCheckedPreviewUrlCacheDate; 0092 } 0093 0094 void RocketChatAccountSettings::setLastCheckedPreviewUrlCacheDate(const QDate &newLastCheckedPreviewUrlCacheDate) 0095 { 0096 if (mLastCheckedPreviewUrlCacheDate != newLastCheckedPreviewUrlCacheDate) { 0097 mLastCheckedPreviewUrlCacheDate = newLastCheckedPreviewUrlCacheDate; 0098 mSetting->setValue(QStringLiteral("lastCheckedPreviewUrlDate"), mLastCheckedPreviewUrlCacheDate); 0099 mSetting->sync(); 0100 } 0101 } 0102 0103 QString RocketChatAccountSettings::displayName() const 0104 { 0105 if (mDisplayName.isEmpty()) { 0106 return mAccountName; 0107 } 0108 return mDisplayName; 0109 } 0110 0111 void RocketChatAccountSettings::setDisplayName(const QString &displayName) 0112 { 0113 if (mDisplayName != displayName) { 0114 mDisplayName = displayName; 0115 mSetting->setValue(QStringLiteral("displayName"), mDisplayName); 0116 mSetting->sync(); 0117 Q_EMIT displayNameChanged(); 0118 } 0119 } 0120 0121 bool RocketChatAccountSettings::accountEnabled() const 0122 { 0123 return mAccountEnabled; 0124 } 0125 0126 void RocketChatAccountSettings::setAccountEnabled(bool enabled) 0127 { 0128 if (mAccountEnabled != enabled) { 0129 mAccountEnabled = enabled; 0130 mSetting->setValue(QStringLiteral("enabled"), mAccountEnabled); 0131 mSetting->sync(); 0132 Q_EMIT enableAccountChanged(); 0133 } 0134 } 0135 0136 QString RocketChatAccountSettings::lastSelectedRoom() const 0137 { 0138 return mSetting->value(QStringLiteral("SelectedRoom")).toString(); 0139 } 0140 0141 void RocketChatAccountSettings::setLastSelectedRoom(const QString &roomId) 0142 { 0143 if (!roomId.isEmpty()) { 0144 mSetting->setValue(QStringLiteral("SelectedRoom"), roomId); 0145 } 0146 } 0147 0148 qint64 RocketChatAccountSettings::expireToken() const 0149 { 0150 return mExpireToken; 0151 } 0152 0153 void RocketChatAccountSettings::setExpireToken(qint64 expireToken) 0154 { 0155 if (mExpireToken != expireToken) { 0156 mExpireToken = expireToken; 0157 mSetting->setValue(QStringLiteral("expireToken"), mExpireToken); 0158 mSetting->sync(); 0159 } 0160 } 0161 0162 bool RocketChatAccountSettings::tokenExpired() const 0163 { 0164 return mExpireToken < QDateTime::currentDateTime().toMSecsSinceEpoch(); 0165 } 0166 0167 QString RocketChatAccountSettings::userId() const 0168 { 0169 return mUserId; 0170 } 0171 0172 void RocketChatAccountSettings::setUserId(const QString &userId) 0173 { 0174 // Don't use if( m_userID != userID) as we need to Q_EMIT userIDChanged 0175 mUserId = userId; 0176 mSetting->setValue(QStringLiteral("userID"), userId); 0177 mSetting->sync(); 0178 Q_EMIT userIdChanged(); 0179 } 0180 0181 QString RocketChatAccountSettings::authToken() const 0182 { 0183 return mAuthToken; 0184 } 0185 0186 void RocketChatAccountSettings::setAuthToken(const QString &authToken) 0187 { 0188 if (mAuthToken != authToken) { 0189 qCDebug(RUQOLA_LOG) << "Setting token to" << authToken; 0190 mAuthToken = authToken; 0191 mSetting->setValue(QStringLiteral("authToken"), authToken); 0192 } 0193 } 0194 0195 void RocketChatAccountSettings::logout() 0196 { 0197 mSetting->setValue(QStringLiteral("authToken"), QString()); 0198 mSetting->setValue(QStringLiteral("expireToken"), -1); 0199 mSetting->sync(); 0200 mAuthToken.clear(); 0201 mUserId.clear(); 0202 mExpireToken = -1; 0203 } 0204 0205 QString RocketChatAccountSettings::password() const 0206 { 0207 return mPassword; 0208 } 0209 0210 void RocketChatAccountSettings::setPassword(const QString &password) 0211 { 0212 mPassword = password; 0213 0214 auto writeJob = new WritePasswordJob(QStringLiteral("Ruqola"), this); 0215 connect(writeJob, &Job::finished, this, &RocketChatAccountSettings::slotPasswordWritten); 0216 writeJob->setKey(mAccountName); 0217 writeJob->setTextData(mPassword); 0218 writeJob->start(); 0219 0220 Q_EMIT passwordChanged(); 0221 } 0222 0223 QString RocketChatAccountSettings::twoFactorAuthenticationCode() const 0224 { 0225 return mTwoFactorAuthenticationCode; 0226 } 0227 0228 void RocketChatAccountSettings::setTwoFactorAuthenticationCode(const QString &twoFactorAuthenticationCode) 0229 { 0230 if (mTwoFactorAuthenticationCode != twoFactorAuthenticationCode) { 0231 mTwoFactorAuthenticationCode = twoFactorAuthenticationCode; 0232 0233 Q_EMIT twoFactorAuthenticationCodeChanged(); 0234 } 0235 } 0236 0237 QString RocketChatAccountSettings::userName() const 0238 { 0239 return mUserName; 0240 } 0241 0242 void RocketChatAccountSettings::setUserName(const QString &userName) 0243 { 0244 if (mUserName != userName) { 0245 mUserName = userName; 0246 mSetting->setValue(QStringLiteral("username"), mUserName); 0247 mSetting->sync(); 0248 Q_EMIT userNameChanged(); 0249 } 0250 } 0251 0252 QString RocketChatAccountSettings::accountName() const 0253 { 0254 return mAccountName; 0255 } 0256 0257 void RocketChatAccountSettings::setAccountName(const QString &accountName) 0258 { 0259 if (mAccountName == accountName) { 0260 return; 0261 } 0262 0263 initializeSettings(ManagerDataPaths::self()->accountConfigFileName(accountName)); 0264 mSetting->setValue(QStringLiteral("accountName"), accountName); 0265 mSetting->sync(); 0266 mAccountName = accountName; 0267 Q_EMIT accountNameChanged(); 0268 } 0269 0270 QString RocketChatAccountSettings::serverUrl() const 0271 { 0272 return mServerUrl; 0273 } 0274 0275 void RocketChatAccountSettings::setServerUrl(const QString &serverUrl) 0276 { 0277 if (mServerUrl == serverUrl) { 0278 return; 0279 } 0280 0281 mSetting->setValue(QStringLiteral("serverURL"), serverUrl); 0282 mSetting->sync(); 0283 mServerUrl = serverUrl; 0284 Q_EMIT serverURLChanged(); 0285 } 0286 0287 QString RocketChatAccountSettings::cacheBasePath() 0288 { 0289 if (mServerUrl.isEmpty()) { 0290 return {}; 0291 } 0292 if (mCachePath.isEmpty()) { 0293 mCachePath = ManagerDataPaths::self()->path(ManagerDataPaths::Cache, mAccountName); 0294 QDir dir; 0295 if (!dir.mkpath(mCachePath)) { 0296 qCWarning(RUQOLA_LOG) << "Impossible to create cache directory" << mCachePath; 0297 } 0298 } 0299 return mCachePath; 0300 } 0301 0302 void RocketChatAccountSettings::removeSettings() 0303 { 0304 // Delete password 0305 auto deleteJob = new DeletePasswordJob(QStringLiteral("Ruqola")); 0306 deleteJob->setKey(mAccountName); 0307 deleteJob->start(); 0308 QFile f(mSetting->fileName()); 0309 if (!f.remove()) { 0310 qCWarning(RUQOLA_LOG) << "Impossible to delete config file: " << mSetting->fileName(); 0311 } 0312 0313 const QString storeCachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1Char('/') + mAccountName + QLatin1Char('/'); 0314 QDir dir(storeCachePath); 0315 if (!dir.removeRecursively()) { 0316 qCWarning(RUQOLA_LOG) << "Impossible to delete cache dir: " << storeCachePath; 0317 } 0318 } 0319 0320 #include "moc_rocketchataccountsettings.cpp"