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