File indexing completed on 2024-12-08 10:25:56

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());
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     return d;
0122 }
0123 
0124 // FIXME Add autotest for it!
0125 void User::parseUserRestApi(const QJsonObject &object, const QVector<RoleInfo> &roleInfo)
0126 {
0127     setUserId(object.value(QLatin1String("_id")).toString());
0128     setName(object.value(QLatin1String("name")).toString());
0129     setStatus(Utils::presenceStatusFromString(object.value(QLatin1String("status")).toString()));
0130     setUserName(object.value(QLatin1String("username")).toString());
0131     setStatusText(object.value(QLatin1String("statusText")).toString());
0132     setUtcOffset(object.value(QLatin1String("utcOffset")).toDouble());
0133     setActive(object.value(QLatin1String("active")).toBool(true)); // By default it's active
0134     setBio(object.value(QLatin1String("bio")).toString());
0135     const QJsonArray rolesArray = object.value(QStringLiteral("roles")).toArray();
0136     QStringList roles;
0137     const int total = rolesArray.size();
0138     roles.reserve(total);
0139     for (int i = 0; i < total; ++i) {
0140         roles.append(rolesArray.at(i).toString());
0141     }
0142     setRoles(roles, roleInfo);
0143     if (object.contains(QLatin1String("createdAt"))) {
0144         setCreatedAt(QDateTime::fromMSecsSinceEpoch(Utils::parseIsoDate(QStringLiteral("createdAt"), object)));
0145     }
0146     if (object.contains(QLatin1String("lastLogin"))) {
0147         setLastLogin(QDateTime::fromMSecsSinceEpoch(Utils::parseIsoDate(QStringLiteral("lastLogin"), object)));
0148     }
0149     if (object.contains(QLatin1String("emails"))) {
0150         const QJsonArray emails = object.value(QStringLiteral("emails")).toArray();
0151         if (emails.count() > 1) {
0152             qCWarning(RUQOLA_LOG) << " Users info has more that 1 emails. Bug or missing feature" << emails;
0153         } else {
0154             const QJsonObject emailObj = emails.at(0).toObject();
0155             UserEmailsInfo info;
0156             info.email = emailObj.value(QLatin1String("address")).toString();
0157             info.verified = emailObj.value(QLatin1String("verified")).toBool();
0158             setUserEmailsInfo(info);
0159         }
0160     }
0161     setRequirePasswordChange(object.value(QLatin1String("requirePasswordChange")).toBool(false));
0162 
0163     // TODO emails
0164     // qDebug() << " object "  << object;
0165 }
0166 
0167 void User::parseUser(const QVariantList &list)
0168 {
0169     if (list.count() != 4) {
0170         qCDebug(RUQOLA_SPECIALWARNING_LOG) << " List argument different of 4! It's a bug: " << list;
0171     }
0172     setUserId(list.at(0).toString());
0173     setUserName(list.at(1).toString());
0174     const int valueStatus = list.at(2).toInt();
0175     if (valueStatus == 0) {
0176         setStatus(PresenceStatus::PresenceOffline);
0177     } else if (valueStatus == 1) {
0178         setStatus(PresenceStatus::PresenceOnline);
0179     } else if (valueStatus == 2) {
0180         setStatus(PresenceStatus::PresenceAway);
0181     } else if (valueStatus == 3) {
0182         setStatus(PresenceStatus::PresenceBusy);
0183     } else {
0184         qCWarning(RUQOLA_LOG) << " Invalid status value" << valueStatus;
0185         return;
0186     }
0187     const QVariant customText = list.at(3);
0188     if (customText.isValid()) {
0189         setStatusText(customText.toString());
0190     }
0191 }
0192 
0193 QStringList User::roles() const
0194 {
0195     return mRoles;
0196 }
0197 
0198 QString User::roleI18n(const QString &roleStr, const QVector<RoleInfo> &roleInfo)
0199 {
0200     QString ri18n;
0201     if (roleStr == QLatin1String("user")) {
0202         ri18n = i18n("User");
0203     } else if (roleStr == QLatin1String("admin")) {
0204         ri18n = i18n("Administrator");
0205     } else if (roleStr == QLatin1String("bot")) {
0206         ri18n = i18n("Bot");
0207     } else {
0208         for (const RoleInfo &info : roleInfo) {
0209             if (roleStr == info.identifier()) {
0210                 ri18n = info.name();
0211                 break;
0212             }
0213         }
0214         if (ri18n.isEmpty()) {
0215             ri18n = roleStr;
0216         }
0217     }
0218     return ri18n;
0219 }
0220 
0221 QString User::bio() const
0222 {
0223     return mBio;
0224 }
0225 
0226 void User::setBio(const QString &newBio)
0227 {
0228     mBio = newBio;
0229 }
0230 
0231 QJsonObject User::serialize(const User &user)
0232 {
0233     QJsonObject o;
0234     o[QLatin1String("identifier")] = user.userId();
0235     o[QLatin1String("name")] = user.name();
0236     o[QLatin1String("username")] = user.userName();
0237     o[QLatin1String("statusText")] = user.statusText();
0238     o[QLatin1String("bio")] = user.bio();
0239 
0240     // Add status/utcoffset/active
0241 
0242     // TODO
0243     return o;
0244 }
0245 
0246 User User::deserialize(const QJsonObject &o)
0247 {
0248     User user;
0249     user.setUserId(o.value(QLatin1String("identifier")).toString());
0250     user.setName(o.value(QLatin1String("name")).toString());
0251     user.setStatus(Utils::presenceStatusFromString(o.value(QLatin1String("status")).toString()));
0252     user.setUserName(o.value(QLatin1String("username")).toString());
0253     user.setStatusText(o.value(QLatin1String("statusText")).toString());
0254     user.setUtcOffset(o.value(QLatin1String("utcOffset")).toDouble());
0255     user.setActive(o.value(QLatin1String("active")).toBool(true)); // By default it's active
0256     user.setBio(o.value(QLatin1String("bio")).toString());
0257     // TODO
0258     return {};
0259 }
0260 
0261 void User::setRoles(const QStringList &roles, const QVector<RoleInfo> &roleInfo)
0262 {
0263     QStringList rolesI18n;
0264     rolesI18n.reserve(roles.count());
0265     for (const QString &role : roles) {
0266         rolesI18n.append(User::roleI18n(role, roleInfo));
0267     }
0268     mI18nRoles = rolesI18n;
0269     mRoles = roles;
0270 }
0271 
0272 QDateTime User::createdAt() const
0273 {
0274     return mCreatedAt;
0275 }
0276 
0277 void User::setCreatedAt(const QDateTime &createdAt)
0278 {
0279     mCreatedAt = createdAt;
0280 }
0281 
0282 QDateTime User::lastLogin() const
0283 {
0284     return mLastLogin;
0285 }
0286 
0287 void User::setLastLogin(const QDateTime &lastLogin)
0288 {
0289     mLastLogin = lastLogin;
0290 }
0291 
0292 User::UserEmailsInfo User::userEmailsInfo() const
0293 {
0294     return mUserEmailsInfo;
0295 }
0296 
0297 void User::setUserEmailsInfo(const UserEmailsInfo &userEmailsInfo)
0298 {
0299     mUserEmailsInfo = userEmailsInfo;
0300 }
0301 
0302 // TODO remove it ????
0303 QStringList User::i18nRoles() const
0304 {
0305     return mI18nRoles;
0306 }
0307 
0308 bool User::active() const
0309 {
0310     return mActive;
0311 }
0312 
0313 void User::setActive(bool newActive)
0314 {
0315     mActive = newActive;
0316 }
0317 
0318 void User::parseUser(const QJsonObject &object)
0319 {
0320     const QJsonObject fields = object.value(QLatin1String("fields")).toObject();
0321     setUserId(object.value(QLatin1String("id")).toString());
0322     setName(fields.value(QLatin1String("name")).toString());
0323     setStatus(Utils::presenceStatusFromString(fields.value(QLatin1String("status")).toString()));
0324     setUserName(fields.value(QLatin1String("username")).toString());
0325     setStatusText(fields.value(QLatin1String("statusText")).toString());
0326     setUtcOffset(fields.value(QLatin1String("utcOffset")).toDouble());
0327     // TODO active ?
0328 }
0329 
0330 QString User::generateStatusStr() const
0331 {
0332     return Utils::displaytextFromPresenceStatus(mStatus);
0333 }
0334 
0335 bool User::requirePasswordChange() const
0336 {
0337     return mRequirePasswordChange;
0338 }
0339 
0340 void User::setRequirePasswordChange(bool newRequirePasswordChange)
0341 {
0342     mRequirePasswordChange = newRequirePasswordChange;
0343 }
0344 
0345 QString User::iconFromStatus() const
0346 {
0347     return Utils::iconFromPresenceStatus(mStatus);
0348 }
0349 
0350 QVector<User> User::parseUsersList(const QJsonObject &object, const QVector<RoleInfo> &roleInfo)
0351 {
0352     const QJsonArray fieldsArray = object.value(QLatin1String("items")).toArray();
0353     QVector<User> users;
0354     for (const QJsonValue &current : fieldsArray) {
0355         if (current.type() == QJsonValue::Object) {
0356             const QJsonObject userObject = current.toObject();
0357             User user;
0358             user.parseUserRestApi(userObject, roleInfo);
0359             users.append(std::move(user));
0360         } else {
0361             qCWarning(RUQOLA_LOG) << "Problem when parsing users" << current;
0362         }
0363     }
0364     return users;
0365 }
0366 
0367 #include "moc_user.cpp"