File indexing completed on 2024-04-28 15:20:12

0001 /*
0002     SPDX-FileCopyrightText: 2014 Alex Richardson <arichardson.kde@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 #include <QDebug>
0007 #include <QTest>
0008 
0009 #include "kcoreaddons_debug.h"
0010 #include "kuser.h"
0011 
0012 namespace QTest
0013 {
0014 template<>
0015 char *toString(const KUserId &id)
0016 {
0017     return qstrdup(id.toString().toLocal8Bit().data());
0018 }
0019 template<>
0020 char *toString(const KGroupId &id)
0021 {
0022     return qstrdup(id.toString().toLocal8Bit().data());
0023 }
0024 }
0025 
0026 class KUserTest : public QObject
0027 {
0028     Q_OBJECT
0029 private Q_SLOTS:
0030     void testKUser();
0031     void testKUserGroup();
0032     void testKUserId();
0033     void testKGroupId();
0034 };
0035 
0036 static inline void printUserInfo(KUser user)
0037 {
0038     qCDebug(KCOREADDONS_DEBUG) << "Login name:" << user.loginName();
0039     qCDebug(KCOREADDONS_DEBUG) << "Full name:" << user.property(KUser::FullName);
0040     qCDebug(KCOREADDONS_DEBUG) << "User ID:" << user.userId().toString();
0041     qCDebug(KCOREADDONS_DEBUG) << "Group ID:" << user.groupId().toString();
0042     qCDebug(KCOREADDONS_DEBUG) << "Home dir:" << user.homeDir();
0043     qCDebug(KCOREADDONS_DEBUG) << "Superuser:" << user.isSuperUser();
0044     qCDebug(KCOREADDONS_DEBUG) << "Shell: " << user.shell();
0045     qCDebug(KCOREADDONS_DEBUG) << "Face icon path:" << user.faceIconPath();
0046     qCDebug(KCOREADDONS_DEBUG) << "Groups:" << user.groupNames();
0047     qCDebug(KCOREADDONS_DEBUG);
0048 }
0049 
0050 void KUserTest::testKUser()
0051 {
0052     KUser user(KUser::UseRealUserID);
0053     KUser effectiveUser(KUser::UseRealUserID);
0054     QVERIFY(user.isValid());
0055     QVERIFY(effectiveUser.isValid());
0056     QCOMPARE(user, effectiveUser); // should be the same, no suid
0057     QVERIFY(user.groupId().isValid());
0058     QCOMPARE(user.groupId(), KGroupId::currentGroupId());
0059     QVERIFY(!user.groups().isEmpty()); // user must be in at least one group
0060     QVERIFY(!user.groupNames().isEmpty()); // user must be in at least one group
0061     QCOMPARE(user.groups().size(), user.groupNames().size());
0062 
0063     QStringList allUserNames = KUser::allUserNames();
0064     QList<KUser> allUsers = KUser::allUsers();
0065     QVERIFY(!allUserNames.isEmpty());
0066     QVERIFY(!allUsers.isEmpty());
0067     QCOMPARE(allUsers.size(), allUserNames.size());
0068     // check that the limiting works
0069     QCOMPARE(user.groups(1).size(), 1);
0070     QCOMPARE(user.groupNames(1).size(), 1);
0071     qCDebug(KCOREADDONS_DEBUG) << "All users: " << allUserNames;
0072     // check that the limiting works
0073     QCOMPARE(KUser::allUserNames(1).size(), 1);
0074     QCOMPARE(KUser::allUsers(1).size(), 1);
0075     // We can't test the KUser properties, since they differ on each system
0076     // instead just print them all out, this can be verified by the person running the test
0077     printUserInfo(user);
0078 #if 0 // enable this if you think that KUser might not be working correctly
0079     Q_FOREACH (const KUser &u, allUsers) {
0080         printUserInfo(u);
0081     }
0082 #endif
0083 
0084     // test operator==
0085     KUser invalidKUser = KUser(KUserId());
0086     QVERIFY(invalidKUser != invalidKUser); // invalid never equal
0087     QVERIFY(invalidKUser != user);
0088     QVERIFY(user != invalidKUser); // now test the other way around
0089     QCOMPARE(user, user);
0090 
0091     // make sure we don't crash when accessing properties of an invalid instance
0092     QCOMPARE(invalidKUser.faceIconPath(), QString());
0093 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 0)
0094     QCOMPARE(invalidKUser.fullName(), QString());
0095 #endif
0096     QCOMPARE(invalidKUser.groupId(), KGroupId());
0097     invalidKUser.groupNames(); // could be empty, or "nogroup", so no checks here
0098     invalidKUser.groups(); // same as above
0099     QCOMPARE(invalidKUser.homeDir(), QString());
0100     QCOMPARE(invalidKUser.isSuperUser(), false);
0101     QCOMPARE(invalidKUser.loginName(), QString());
0102     QCOMPARE(invalidKUser.shell(), QString());
0103     QCOMPARE(invalidKUser.userId(), KUserId());
0104     QCOMPARE(invalidKUser.userId(), KUserId());
0105     QCOMPARE(invalidKUser.property(KUser::RoomNumber), QVariant());
0106 }
0107 
0108 void KUserTest::testKUserGroup()
0109 {
0110     KUserGroup group(KUser::UseRealUserID);
0111     KUserGroup effectiveUser(KUser::UseEffectiveUID);
0112     QVERIFY(group.isValid());
0113     QVERIFY(effectiveUser.isValid());
0114     QCOMPARE(group, effectiveUser); // should be the same, no suid
0115 #ifdef Q_OS_WIN
0116     // on Windows the special group "None" has no members (often the only group that exists)
0117     if (group.name() != QLatin1String("None")) {
0118 #else
0119     {
0120 #endif
0121         QStringList groupUserNames = group.userNames();
0122         QList<KUser> groupUsers = group.users();
0123         QVERIFY(!groupUsers.isEmpty()); // group must have at least one user (the current user)
0124         QVERIFY(!groupUserNames.isEmpty()); // group must have at least one user (the current user)
0125         QCOMPARE(groupUsers.size(), groupUserNames.size());
0126         // check that the limiting works
0127         QCOMPARE(group.users(1).size(), 1);
0128         QCOMPARE(group.userNames(1).size(), 1);
0129     }
0130 
0131     QStringList allGroupNames = KUserGroup::allGroupNames();
0132     QList<KUserGroup> allGroups = KUserGroup::allGroups();
0133     QVERIFY(!allGroupNames.isEmpty());
0134     QVERIFY(!allGroups.isEmpty());
0135     QCOMPARE(allGroups.size(), allGroupNames.size());
0136     qCDebug(KCOREADDONS_DEBUG) << "All groups: " << allGroupNames;
0137     // check that the limiting works
0138     QCOMPARE(KUserGroup::allGroupNames(1).size(), 1);
0139     QCOMPARE(KUserGroup::allGroups(1).size(), 1);
0140     // We can't test the KUser properties, since they differ on each system
0141     // instead just print them all out, this can be verified by the person running the test
0142     qCDebug(KCOREADDONS_DEBUG).nospace() << "Current group: " << group.name() << ", group ID =" << group.groupId().toString()
0143                                          << ", members = " << group.userNames();
0144 #if 0 // enable this if you think that KUser might not be working correctly
0145     for (int i = 0; i < allGroups.size(); ++i) {
0146         qDebug().nospace() << "Group " << i << ": name = " << allGroups[i].name()
0147                            << ", group ID =" << allGroups[i].groupId().toString();
0148         qDebug() << allGroups[i].name() << "members:" << allGroups[i].userNames();
0149     }
0150 #endif
0151     // test operator==
0152     KUserGroup invalidKUserGroup = KUserGroup(KGroupId());
0153     QVERIFY(invalidKUserGroup != invalidKUserGroup); // invalid never equal
0154     QVERIFY(invalidKUserGroup != group);
0155     QVERIFY(group != invalidKUserGroup); // now test the other way around
0156     QCOMPARE(group, group);
0157 
0158     // make sure we don't crash when accessing an invalid KUserGroup
0159     QCOMPARE(invalidKUserGroup.groupId(), KGroupId());
0160     invalidKUserGroup.name(); // could be empty, or "nogroup", so no checks here
0161     QCOMPARE(invalidKUserGroup.userNames(), QStringList());
0162     QCOMPARE(invalidKUserGroup.users(), QList<KUser>());
0163 }
0164 
0165 void KUserTest::testKUserId()
0166 {
0167     // make sure KUser::currentUserId() and KUser::curretEffectiveUserId() work
0168     KUserId currentUser = KUserId::currentUserId();
0169     QVERIFY(currentUser.isValid());
0170     KUserId currentEffectiveUser = KUserId::currentEffectiveUserId();
0171     QVERIFY(currentEffectiveUser.isValid());
0172     // these should be the same since this is not a setuid program
0173     QCOMPARE(currentUser, currentEffectiveUser);
0174 
0175     KUser kuser(currentUser);
0176     // now get the same user from his name
0177     QString userName = kuser.loginName();
0178     qDebug("Current user: %s, id: %s", qPrintable(userName), qPrintable(currentUser.toString()));
0179     QVERIFY(!userName.isEmpty());
0180     KUserId currentUserFromStr = KUserId::fromName(userName);
0181     QVERIFY(currentUserFromStr.isValid());
0182     KUserId currentUserCopyFromKUser = kuser.userId();
0183     QVERIFY(currentUserCopyFromKUser.isValid());
0184     KUserId invalid;
0185     QVERIFY(!invalid.isValid());
0186 #ifdef Q_OS_WIN
0187     KUserId invalid2(nullptr);
0188 #else
0189     KUserId invalid2(-1);
0190 #endif
0191     QVERIFY(!invalid2.isValid());
0192     // I guess it is safe to assume no user with this name exists
0193     KUserId invalid3 = KUserId::fromName(QStringLiteral("This_user_does_not_exist"));
0194     QVERIFY(!invalid3.isValid());
0195 
0196     // check comparison
0197     QCOMPARE(invalid, KUserId());
0198     QCOMPARE(invalid, invalid2);
0199     QCOMPARE(invalid, invalid3);
0200     QCOMPARE(currentUser, currentUserFromStr);
0201     QCOMPARE(currentUser, currentEffectiveUser);
0202     QCOMPARE(currentUser, currentUserCopyFromKUser);
0203     QVERIFY(currentUser != invalid);
0204     QVERIFY(currentUser != invalid2);
0205     QVERIFY(currentUser != invalid3);
0206     QVERIFY(invalid != currentUser);
0207     // Copy constructor and assignment
0208     KUserId currentUserCopy = currentUser;
0209     QCOMPARE(currentUser, currentUserCopy);
0210     QCOMPARE(currentUser, KUserId(currentUser));
0211     QCOMPARE(currentEffectiveUser, KUserId(currentUser));
0212 }
0213 
0214 void KUserTest::testKGroupId()
0215 {
0216     // make sure KGroup::currentGroupId() and KGroup::curretEffectiveGroupId() work
0217     KGroupId currentGroup = KGroupId::currentGroupId();
0218     QVERIFY(currentGroup.isValid());
0219     KGroupId currentEffectiveGroup = KGroupId::currentEffectiveGroupId();
0220     QVERIFY(currentEffectiveGroup.isValid());
0221     // these should be the same since this is not a setuid program
0222     QCOMPARE(currentGroup, currentEffectiveGroup);
0223 
0224     // now get the same Group from his name
0225     KUserGroup kuserGroup(currentGroup);
0226     QString groupName = kuserGroup.name();
0227     qDebug("Current group: %s, id: %s", qPrintable(groupName), qPrintable(currentGroup.toString()));
0228     QVERIFY(!groupName.isEmpty());
0229     KGroupId currentGroupFromStr = KGroupId::fromName(groupName);
0230     QVERIFY(currentGroupFromStr.isValid());
0231     KGroupId currentGroupCopyFromKUserGroup = kuserGroup.groupId();
0232     QVERIFY(currentGroupCopyFromKUserGroup.isValid());
0233     KGroupId invalid;
0234     QVERIFY(!invalid.isValid());
0235 #ifdef Q_OS_WIN
0236     KGroupId invalid2(nullptr);
0237 #else
0238     KGroupId invalid2(-1);
0239 #endif
0240     QVERIFY(!invalid2.isValid());
0241     // I guess it is safe to assume no Group with this name exists
0242     KGroupId invalid3 = KGroupId::fromName(QStringLiteral("This_Group_does_not_exist"));
0243     QVERIFY(!invalid3.isValid());
0244 
0245     // check comparison
0246     QCOMPARE(invalid, KGroupId());
0247     QCOMPARE(invalid, invalid2);
0248     QCOMPARE(invalid, invalid3);
0249     QCOMPARE(currentGroup, currentGroupFromStr);
0250     QCOMPARE(currentGroup, currentEffectiveGroup);
0251     QCOMPARE(currentGroup, currentGroupCopyFromKUserGroup);
0252     QVERIFY(invalid != currentGroup);
0253     QVERIFY(currentGroup != invalid);
0254     QVERIFY(currentGroup != invalid2);
0255     QVERIFY(currentGroup != invalid3);
0256     // Copy constructor and assignment
0257     KGroupId currentGroupCopy = currentGroup;
0258     QCOMPARE(currentGroup, currentGroupCopy);
0259     QCOMPARE(currentGroup, KGroupId(currentGroup));
0260     QCOMPARE(currentEffectiveGroup, KGroupId(currentGroup));
0261 }
0262 
0263 QTEST_MAIN(KUserTest)
0264 
0265 #include "kusertest.moc"