File indexing completed on 2024-05-05 05:02:22

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 "user.h"
0008 #include "ruqola_debug.h"
0009 #include "ruqola_specialwarning_debug.h"
0010 #include "utils.h"
0011 
0012 #include <KLocalizedString>
0013 
0014 #include <QJsonArray>
0015 #include <QJsonObject>
0016 
0017 User::User() = default;
0018 
0019 User::~User() = default;
0020 
0021 QString User::name() const
0022 {
0023     return mName;
0024 }
0025 
0026 void User::setName(const QString &name)
0027 {
0028     mName = name;
0029 }
0030 
0031 QString User::userId() const
0032 {
0033     return mUserId;
0034 }
0035 
0036 void User::setUserId(const QString &userId)
0037 {
0038     mUserId = userId;
0039 }
0040 
0041 User::PresenceStatus User::status() const
0042 {
0043     return mStatus;
0044 }
0045 
0046 void User::setStatus(PresenceStatus s)
0047 {
0048     mStatus = s;
0049 }
0050 
0051 bool User::operator==(const User &other) const
0052 {
0053     return (mName == other.name()) && (mUserId == other.userId()) && (mStatus == other.status()) && (mUserName == other.userName())
0054         && (mUtcOffset == other.utcOffset()) && (mStatusText == other.statusText()) && (mRoles == other.roles()) && (mCreatedAt == other.createdAt())
0055         && (mLastLogin == other.lastLogin()) && (mActive == other.active()) && (mRequirePasswordChange == other.requirePasswordChange())
0056         && (mBio == other.bio()) && (mNickName == other.nickName());
0057 }
0058 
0059 bool User::operator!=(const User &other) const
0060 {
0061     return !operator==(other);
0062 }
0063 
0064 QString User::userName() const
0065 {
0066     return mUserName;
0067 }
0068 
0069 void User::setUserName(const QString &userName)
0070 {
0071     mUserName = userName;
0072 }
0073 
0074 bool User::isValid() const
0075 {
0076     return !mUserName.isEmpty() || !mName.isEmpty();
0077 }
0078 
0079 double User::utcOffset() const
0080 {
0081     return mUtcOffset;
0082 }
0083 
0084 void User::setUtcOffset(double utcOffset)
0085 {
0086     mUtcOffset = utcOffset;
0087 }
0088 
0089 QString User::statusText() const
0090 {
0091     return mStatusText;
0092 }
0093 
0094 void User::setStatusText(const QString &statusText)
0095 {
0096     mStatusText = statusText;
0097 }
0098 
0099 QDebug operator<<(QDebug d, const User::UserEmailsInfo &t)
0100 {
0101     d << "email " << t.email;
0102     d << "verified " << t.verified;
0103     return d;
0104 }
0105 
0106 QDebug operator<<(QDebug d, const User &t)
0107 {
0108     d << " Name " << t.name();
0109     d << " UserId " << t.userId();
0110     d << " Status " << t.status();
0111     d << " UserName " << t.userName();
0112     d << " UtcOffset " << t.utcOffset();
0113     d << " StatusText " << t.statusText();
0114     d << " roles " << t.roles();
0115     d << " CreatedAt " << t.createdAt();
0116     d << " Last Login " << t.lastLogin();
0117     d << " userEmailsInfo " << t.userEmailsInfo();
0118     d << " active " << t.active();
0119     d << " mRequirePasswordChange " << t.requirePasswordChange();
0120     d << " mBio " << t.bio();
0121     d << " mNickName " << t.nickName();
0122     return d;
0123 }
0124 
0125 // FIXME Add autotest for it!
0126 void User::parseUserRestApi(const QJsonObject &object, const QVector<RoleInfo> &roleInfo)
0127 {
0128     setUserId(object.value(QLatin1String("_id")).toString());
0129     setName(object.value(QLatin1String("name")).toString());
0130     setStatus(Utils::presenceStatusFromString(object.value(QLatin1String("status")).toString()));
0131     setUserName(object.value(QLatin1String("username")).toString());
0132     setStatusText(object.value(QLatin1String("statusText")).toString());
0133     setUtcOffset(object.value(QLatin1String("utcOffset")).toDouble());
0134     setActive(object.value(QLatin1String("active")).toBool(true)); // By default it's active
0135     setBio(object.value(QLatin1String("bio")).toString());
0136     setNickName(object.value(QLatin1String("nickname")).toString());
0137     const QJsonArray rolesArray = object.value(QStringLiteral("roles")).toArray();
0138     QStringList roles;
0139     const int total = rolesArray.size();
0140     roles.reserve(total);
0141     for (int i = 0; i < total; ++i) {
0142         roles.append(rolesArray.at(i).toString());
0143     }
0144     setRoles(roles, roleInfo);
0145     if (object.contains(QLatin1String("createdAt"))) {
0146         setCreatedAt(QDateTime::fromMSecsSinceEpoch(Utils::parseIsoDate(QStringLiteral("createdAt"), object)));
0147     }
0148     if (object.contains(QLatin1String("lastLogin"))) {
0149         setLastLogin(QDateTime::fromMSecsSinceEpoch(Utils::parseIsoDate(QStringLiteral("lastLogin"), object)));
0150     }
0151     if (object.contains(QLatin1String("emails"))) {
0152         const QJsonArray emails = object.value(QStringLiteral("emails")).toArray();
0153         if (emails.count() > 1) {
0154             qCWarning(RUQOLA_LOG) << " Users info has more that 1 emails. Bug or missing feature" << emails;
0155         } else {
0156             const QJsonObject emailObj = emails.at(0).toObject();
0157             UserEmailsInfo info;
0158             info.email = emailObj.value(QLatin1String("address")).toString();
0159             info.verified = emailObj.value(QLatin1String("verified")).toBool();
0160             setUserEmailsInfo(info);
0161         }
0162     }
0163     setRequirePasswordChange(object.value(QLatin1String("requirePasswordChange")).toBool(false));
0164 
0165     // TODO emails
0166     // qDebug() << " object "  << object;
0167 }
0168 
0169 void User::parseUser(const QVariantList &list)
0170 {
0171     if (list.count() != 4) {
0172         qCDebug(RUQOLA_SPECIALWARNING_LOG) << " List argument different of 4! It's a bug: " << list;
0173     }
0174     setUserId(list.at(0).toString());
0175     setUserName(list.at(1).toString());
0176     const int valueStatus = list.at(2).toInt();
0177     if (valueStatus == 0) {
0178         setStatus(PresenceStatus::PresenceOffline);
0179     } else if (valueStatus == 1) {
0180         setStatus(PresenceStatus::PresenceOnline);
0181     } else if (valueStatus == 2) {
0182         setStatus(PresenceStatus::PresenceAway);
0183     } else if (valueStatus == 3) {
0184         setStatus(PresenceStatus::PresenceBusy);
0185     } else {
0186         qCWarning(RUQOLA_LOG) << " Invalid status value" << valueStatus;
0187         return;
0188     }
0189     const QVariant customText = list.at(3);
0190     if (customText.isValid()) {
0191         setStatusText(customText.toString());
0192     }
0193 }
0194 
0195 QStringList User::roles() const
0196 {
0197     return mRoles;
0198 }
0199 
0200 QString User::roleI18n(const QString &roleStr, const QVector<RoleInfo> &roleInfo)
0201 {
0202     QString ri18n;
0203     if (roleStr == QLatin1String("user")) {
0204         ri18n = i18n("User");
0205     } else if (roleStr == QLatin1String("admin")) {
0206         ri18n = i18n("Administrator");
0207     } else if (roleStr == QLatin1String("bot")) {
0208         ri18n = i18n("Bot");
0209     } else {
0210         for (const RoleInfo &info : roleInfo) {
0211             if (roleStr == info.identifier()) {
0212                 ri18n = info.name();
0213                 break;
0214             }
0215         }
0216         if (ri18n.isEmpty()) {
0217             ri18n = roleStr;
0218         }
0219     }
0220     return ri18n;
0221 }
0222 
0223 QString User::bio() const
0224 {
0225     return mBio;
0226 }
0227 
0228 void User::setBio(const QString &newBio)
0229 {
0230     mBio = newBio;
0231 }
0232 
0233 QJsonObject User::serialize(const User &user)
0234 {
0235     QJsonObject o;
0236     o[QLatin1String("identifier")] = user.userId();
0237     o[QLatin1String("name")] = user.name();
0238     o[QLatin1String("username")] = user.userName();
0239     o[QLatin1String("statusText")] = user.statusText();
0240     o[QLatin1String("bio")] = user.bio();
0241     o[QLatin1String("nickname")] = user.nickName();
0242 
0243     // Add status/utcoffset/active
0244 
0245     // TODO
0246     return o;
0247 }
0248 
0249 User User::deserialize(const QJsonObject &o)
0250 {
0251     User user;
0252     user.setUserId(o.value(QLatin1String("identifier")).toString());
0253     user.setName(o.value(QLatin1String("name")).toString());
0254     user.setStatus(Utils::presenceStatusFromString(o.value(QLatin1String("status")).toString()));
0255     user.setUserName(o.value(QLatin1String("username")).toString());
0256     user.setStatusText(o.value(QLatin1String("statusText")).toString());
0257     user.setUtcOffset(o.value(QLatin1String("utcOffset")).toDouble());
0258     user.setActive(o.value(QLatin1String("active")).toBool(true)); // By default it's active
0259     user.setBio(o.value(QLatin1String("bio")).toString());
0260     user.setNickName(o.value(QLatin1String("nickname")).toString());
0261     // TODO
0262     return {};
0263 }
0264 
0265 QString User::nickName() const
0266 {
0267     return mNickName;
0268 }
0269 
0270 void User::setNickName(const QString &newNickName)
0271 {
0272     mNickName = newNickName;
0273 }
0274 
0275 void User::setRoles(const QStringList &roles, const QVector<RoleInfo> &roleInfo)
0276 {
0277     QStringList rolesI18n;
0278     rolesI18n.reserve(roles.count());
0279     for (const QString &role : roles) {
0280         rolesI18n.append(User::roleI18n(role, roleInfo));
0281     }
0282     mI18nRoles = rolesI18n;
0283     mRoles = roles;
0284 }
0285 
0286 QDateTime User::createdAt() const
0287 {
0288     return mCreatedAt;
0289 }
0290 
0291 void User::setCreatedAt(const QDateTime &createdAt)
0292 {
0293     mCreatedAt = createdAt;
0294 }
0295 
0296 QDateTime User::lastLogin() const
0297 {
0298     return mLastLogin;
0299 }
0300 
0301 void User::setLastLogin(const QDateTime &lastLogin)
0302 {
0303     mLastLogin = lastLogin;
0304 }
0305 
0306 User::UserEmailsInfo User::userEmailsInfo() const
0307 {
0308     return mUserEmailsInfo;
0309 }
0310 
0311 void User::setUserEmailsInfo(const UserEmailsInfo &userEmailsInfo)
0312 {
0313     mUserEmailsInfo = userEmailsInfo;
0314 }
0315 
0316 // TODO remove it ????
0317 QStringList User::i18nRoles() const
0318 {
0319     return mI18nRoles;
0320 }
0321 
0322 bool User::active() const
0323 {
0324     return mActive;
0325 }
0326 
0327 void User::setActive(bool newActive)
0328 {
0329     mActive = newActive;
0330 }
0331 
0332 void User::parseUser(const QJsonObject &object)
0333 {
0334     const QJsonObject fields = object.value(QLatin1String("fields")).toObject();
0335     setUserId(object.value(QLatin1String("id")).toString());
0336     setName(fields.value(QLatin1String("name")).toString());
0337     setNickName(fields.value(QLatin1String("nickname")).toString());
0338     setStatus(Utils::presenceStatusFromString(fields.value(QLatin1String("status")).toString()));
0339     setUserName(fields.value(QLatin1String("username")).toString());
0340     setStatusText(fields.value(QLatin1String("statusText")).toString());
0341     setUtcOffset(fields.value(QLatin1String("utcOffset")).toDouble());
0342     // TODO active ?
0343 }
0344 
0345 QString User::generateStatusStr() const
0346 {
0347     return Utils::displaytextFromPresenceStatus(mStatus);
0348 }
0349 
0350 bool User::requirePasswordChange() const
0351 {
0352     return mRequirePasswordChange;
0353 }
0354 
0355 void User::setRequirePasswordChange(bool newRequirePasswordChange)
0356 {
0357     mRequirePasswordChange = newRequirePasswordChange;
0358 }
0359 
0360 QString User::iconFromStatus() const
0361 {
0362     return Utils::iconFromPresenceStatus(mStatus);
0363 }
0364 
0365 QVector<User> User::parseUsersList(const QJsonObject &object, const QVector<RoleInfo> &roleInfo)
0366 {
0367     const QJsonArray fieldsArray = object.value(QLatin1String("items")).toArray();
0368     QVector<User> users;
0369     for (const QJsonValue &current : fieldsArray) {
0370         if (current.type() == QJsonValue::Object) {
0371             const QJsonObject userObject = current.toObject();
0372             User user;
0373             user.parseUserRestApi(userObject, roleInfo);
0374             users.append(std::move(user));
0375         } else {
0376             qCWarning(RUQOLA_LOG) << "Problem when parsing users" << current;
0377         }
0378     }
0379     return users;
0380 }
0381 
0382 #include "moc_user.cpp"