File indexing completed on 2024-04-14 03:51:33

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     QCOMPARE(invalidKUser.groupId(), KGroupId());
0094     invalidKUser.groupNames(); // could be empty, or "nogroup", so no checks here
0095     invalidKUser.groups(); // same as above
0096     QCOMPARE(invalidKUser.homeDir(), QString());
0097     QCOMPARE(invalidKUser.isSuperUser(), false);
0098     QCOMPARE(invalidKUser.loginName(), QString());
0099     QCOMPARE(invalidKUser.shell(), QString());
0100     QCOMPARE(invalidKUser.userId(), KUserId());
0101     QCOMPARE(invalidKUser.userId(), KUserId());
0102     QCOMPARE(invalidKUser.property(KUser::RoomNumber), QVariant());
0103 }
0104 
0105 void KUserTest::testKUserGroup()
0106 {
0107     KUserGroup group(KUser::UseRealUserID);
0108     KUserGroup effectiveUser(KUser::UseEffectiveUID);
0109     QVERIFY(group.isValid());
0110     QVERIFY(effectiveUser.isValid());
0111     QCOMPARE(group, effectiveUser); // should be the same, no suid
0112 #ifdef Q_OS_WIN
0113     // on Windows the special group "None" has no members (often the only group that exists)
0114     if (group.name() != QLatin1String("None")) {
0115 #else
0116     {
0117 #endif
0118         QStringList groupUserNames = group.userNames();
0119         QList<KUser> groupUsers = group.users();
0120         QVERIFY(!groupUsers.isEmpty()); // group must have at least one user (the current user)
0121         QVERIFY(!groupUserNames.isEmpty()); // group must have at least one user (the current user)
0122         QCOMPARE(groupUsers.size(), groupUserNames.size());
0123         // check that the limiting works
0124         QCOMPARE(group.users(1).size(), 1);
0125         QCOMPARE(group.userNames(1).size(), 1);
0126     }
0127 
0128     QStringList allGroupNames = KUserGroup::allGroupNames();
0129     QList<KUserGroup> allGroups = KUserGroup::allGroups();
0130     QVERIFY(!allGroupNames.isEmpty());
0131     QVERIFY(!allGroups.isEmpty());
0132     QCOMPARE(allGroups.size(), allGroupNames.size());
0133     qCDebug(KCOREADDONS_DEBUG) << "All groups: " << allGroupNames;
0134     // check that the limiting works
0135     QCOMPARE(KUserGroup::allGroupNames(1).size(), 1);
0136     QCOMPARE(KUserGroup::allGroups(1).size(), 1);
0137     // We can't test the KUser properties, since they differ on each system
0138     // instead just print them all out, this can be verified by the person running the test
0139     qCDebug(KCOREADDONS_DEBUG).nospace() << "Current group: " << group.name() << ", group ID =" << group.groupId().toString()
0140                                          << ", members = " << group.userNames();
0141 #if 0 // enable this if you think that KUser might not be working correctly
0142     for (int i = 0; i < allGroups.size(); ++i) {
0143         qDebug().nospace() << "Group " << i << ": name = " << allGroups[i].name()
0144                            << ", group ID =" << allGroups[i].groupId().toString();
0145         qDebug() << allGroups[i].name() << "members:" << allGroups[i].userNames();
0146     }
0147 #endif
0148     // test operator==
0149     KUserGroup invalidKUserGroup = KUserGroup(KGroupId());
0150     QVERIFY(invalidKUserGroup != invalidKUserGroup); // invalid never equal
0151     QVERIFY(invalidKUserGroup != group);
0152     QVERIFY(group != invalidKUserGroup); // now test the other way around
0153     QCOMPARE(group, group);
0154 
0155     // make sure we don't crash when accessing an invalid KUserGroup
0156     QCOMPARE(invalidKUserGroup.groupId(), KGroupId());
0157     invalidKUserGroup.name(); // could be empty, or "nogroup", so no checks here
0158     QCOMPARE(invalidKUserGroup.userNames(), QStringList());
0159     QCOMPARE(invalidKUserGroup.users(), QList<KUser>());
0160 }
0161 
0162 void KUserTest::testKUserId()
0163 {
0164     // make sure KUser::currentUserId() and KUser::curretEffectiveUserId() work
0165     KUserId currentUser = KUserId::currentUserId();
0166     QVERIFY(currentUser.isValid());
0167     KUserId currentEffectiveUser = KUserId::currentEffectiveUserId();
0168     QVERIFY(currentEffectiveUser.isValid());
0169     // these should be the same since this is not a setuid program
0170     QCOMPARE(currentUser, currentEffectiveUser);
0171 
0172     KUser kuser(currentUser);
0173     // now get the same user from his name
0174     QString userName = kuser.loginName();
0175     qDebug("Current user: %s, id: %s", qPrintable(userName), qPrintable(currentUser.toString()));
0176     QVERIFY(!userName.isEmpty());
0177     KUserId currentUserFromStr = KUserId::fromName(userName);
0178     QVERIFY(currentUserFromStr.isValid());
0179     KUserId currentUserCopyFromKUser = kuser.userId();
0180     QVERIFY(currentUserCopyFromKUser.isValid());
0181     KUserId invalid;
0182     QVERIFY(!invalid.isValid());
0183 #ifdef Q_OS_WIN
0184     KUserId invalid2(nullptr);
0185 #else
0186     KUserId invalid2(-1);
0187 #endif
0188     QVERIFY(!invalid2.isValid());
0189     // I guess it is safe to assume no user with this name exists
0190     KUserId invalid3 = KUserId::fromName(QStringLiteral("This_user_does_not_exist"));
0191     QVERIFY(!invalid3.isValid());
0192 
0193     // check comparison
0194     QCOMPARE(invalid, KUserId());
0195     QCOMPARE(invalid, invalid2);
0196     QCOMPARE(invalid, invalid3);
0197     QCOMPARE(currentUser, currentUserFromStr);
0198     QCOMPARE(currentUser, currentEffectiveUser);
0199     QCOMPARE(currentUser, currentUserCopyFromKUser);
0200     QVERIFY(currentUser != invalid);
0201     QVERIFY(currentUser != invalid2);
0202     QVERIFY(currentUser != invalid3);
0203     QVERIFY(invalid != currentUser);
0204     // Copy constructor and assignment
0205     KUserId currentUserCopy = currentUser;
0206     QCOMPARE(currentUser, currentUserCopy);
0207     QCOMPARE(currentUser, KUserId(currentUser));
0208     QCOMPARE(currentEffectiveUser, KUserId(currentUser));
0209 }
0210 
0211 void KUserTest::testKGroupId()
0212 {
0213     // make sure KGroup::currentGroupId() and KGroup::curretEffectiveGroupId() work
0214     KGroupId currentGroup = KGroupId::currentGroupId();
0215     QVERIFY(currentGroup.isValid());
0216     KGroupId currentEffectiveGroup = KGroupId::currentEffectiveGroupId();
0217     QVERIFY(currentEffectiveGroup.isValid());
0218     // these should be the same since this is not a setuid program
0219     QCOMPARE(currentGroup, currentEffectiveGroup);
0220 
0221     // now get the same Group from his name
0222     KUserGroup kuserGroup(currentGroup);
0223     QString groupName = kuserGroup.name();
0224     qDebug("Current group: %s, id: %s", qPrintable(groupName), qPrintable(currentGroup.toString()));
0225     QVERIFY(!groupName.isEmpty());
0226     KGroupId currentGroupFromStr = KGroupId::fromName(groupName);
0227     QVERIFY(currentGroupFromStr.isValid());
0228     KGroupId currentGroupCopyFromKUserGroup = kuserGroup.groupId();
0229     QVERIFY(currentGroupCopyFromKUserGroup.isValid());
0230     KGroupId invalid;
0231     QVERIFY(!invalid.isValid());
0232 #ifdef Q_OS_WIN
0233     KGroupId invalid2(nullptr);
0234 #else
0235     KGroupId invalid2(-1);
0236 #endif
0237     QVERIFY(!invalid2.isValid());
0238     // I guess it is safe to assume no Group with this name exists
0239     KGroupId invalid3 = KGroupId::fromName(QStringLiteral("This_Group_does_not_exist"));
0240     QVERIFY(!invalid3.isValid());
0241 
0242     // check comparison
0243     QCOMPARE(invalid, KGroupId());
0244     QCOMPARE(invalid, invalid2);
0245     QCOMPARE(invalid, invalid3);
0246     QCOMPARE(currentGroup, currentGroupFromStr);
0247     QCOMPARE(currentGroup, currentEffectiveGroup);
0248     QCOMPARE(currentGroup, currentGroupCopyFromKUserGroup);
0249     QVERIFY(invalid != currentGroup);
0250     QVERIFY(currentGroup != invalid);
0251     QVERIFY(currentGroup != invalid2);
0252     QVERIFY(currentGroup != invalid3);
0253     // Copy constructor and assignment
0254     KGroupId currentGroupCopy = currentGroup;
0255     QCOMPARE(currentGroup, currentGroupCopy);
0256     QCOMPARE(currentGroup, KGroupId(currentGroup));
0257     QCOMPARE(currentEffectiveGroup, KGroupId(currentGroup));
0258 }
0259 
0260 QTEST_MAIN(KUserTest)
0261 
0262 #include "kusertest.moc"