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