1 #include "mock_user_mgr.hpp" 2 #include "user_mgr.hpp" 3 4 #include <sdbusplus/test/sdbus_mock.hpp> 5 #include <xyz/openbmc_project/Common/error.hpp> 6 #include <xyz/openbmc_project/User/Common/error.hpp> 7 8 #include <exception> 9 #include <filesystem> 10 #include <fstream> 11 #include <vector> 12 13 #include <gmock/gmock.h> 14 #include <gtest/gtest.h> 15 16 namespace phosphor 17 { 18 namespace user 19 { 20 21 using ::testing::Return; 22 using ::testing::Throw; 23 24 using InternalFailure = 25 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 26 using UserNameDoesNotExist = 27 sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameDoesNotExist; 28 29 class TestUserMgr : public testing::Test 30 { 31 public: 32 sdbusplus::SdBusMock sdBusMock; 33 sdbusplus::bus_t bus; 34 MockManager mockManager; 35 36 TestUserMgr() : 37 bus(sdbusplus::get_mocked_new(&sdBusMock)), mockManager(bus, objpath) 38 {} 39 40 void createLocalUser(const std::string& userName, 41 std::vector<std::string> groupNames, 42 const std::string& priv, bool enabled) 43 { 44 sdbusplus::message::object_path tempObjPath(usersObjPath); 45 tempObjPath /= userName; 46 std::string userObj(tempObjPath); 47 mockManager.usersList.emplace( 48 userName, std::make_unique<phosphor::user::Users>( 49 mockManager.bus, userObj.c_str(), groupNames, priv, 50 enabled, mockManager)); 51 } 52 53 DbusUserObj createPrivilegeMapperDbusObject(void) 54 { 55 DbusUserObj object; 56 DbusUserObjValue objValue; 57 58 DbusUserObjPath objPath("/xyz/openbmc_project/user/ldap/openldap"); 59 DbusUserPropVariant enabled(true); 60 DbusUserObjProperties property = {std::make_pair("Enabled", enabled)}; 61 std::string intf = "xyz.openbmc_project.Object.Enable"; 62 objValue.emplace(intf, property); 63 object.emplace(objPath, objValue); 64 65 DbusUserObjPath objectPath( 66 "/xyz/openbmc_project/user/ldap/openldap/role_map/1"); 67 std::string group = "ldapGroup"; 68 std::string priv = "priv-admin"; 69 DbusUserObjProperties properties = {std::make_pair("GroupName", group), 70 std::make_pair("Privilege", priv)}; 71 std::string interface = "xyz.openbmc_project.User.PrivilegeMapperEntry"; 72 73 objValue.emplace(interface, properties); 74 object.emplace(objectPath, objValue); 75 76 return object; 77 } 78 79 DbusUserObj createLdapConfigObjectWithoutPrivilegeMapper(void) 80 { 81 DbusUserObj object; 82 DbusUserObjValue objValue; 83 84 DbusUserObjPath objPath("/xyz/openbmc_project/user/ldap/openldap"); 85 DbusUserPropVariant enabled(true); 86 DbusUserObjProperties property = {std::make_pair("Enabled", enabled)}; 87 std::string intf = "xyz.openbmc_project.Object.Enable"; 88 objValue.emplace(intf, property); 89 object.emplace(objPath, objValue); 90 return object; 91 } 92 }; 93 94 TEST_F(TestUserMgr, ldapEntryDoesNotExist) 95 { 96 std::string userName = "user"; 97 UserInfoMap userInfo; 98 99 EXPECT_CALL(mockManager, getPrimaryGroup(userName)) 100 .WillRepeatedly(Throw(UserNameDoesNotExist())); 101 EXPECT_THROW(userInfo = mockManager.getUserInfo(userName), 102 UserNameDoesNotExist); 103 } 104 105 TEST_F(TestUserMgr, localUser) 106 { 107 UserInfoMap userInfo; 108 std::string userName = "testUser"; 109 std::string privilege = "priv-admin"; 110 std::vector<std::string> groups{"testGroup"}; 111 // Create local user 112 createLocalUser(userName, groups, privilege, true); 113 EXPECT_CALL(mockManager, userLockedForFailedAttempt(userName)).Times(1); 114 userInfo = mockManager.getUserInfo(userName); 115 116 EXPECT_EQ(privilege, std::get<std::string>(userInfo["UserPrivilege"])); 117 EXPECT_EQ(groups, 118 std::get<std::vector<std::string>>(userInfo["UserGroups"])); 119 EXPECT_EQ(true, std::get<bool>(userInfo["UserEnabled"])); 120 EXPECT_EQ(false, std::get<bool>(userInfo["UserLockedForFailedAttempt"])); 121 EXPECT_EQ(false, std::get<bool>(userInfo["UserPasswordExpired"])); 122 EXPECT_EQ(false, std::get<bool>(userInfo["RemoteUser"])); 123 } 124 125 TEST_F(TestUserMgr, ldapUserWithPrivMapper) 126 { 127 UserInfoMap userInfo; 128 std::string userName = "ldapUser"; 129 std::string ldapGroup = "ldapGroup"; 130 gid_t primaryGid = 1000; 131 132 EXPECT_CALL(mockManager, getPrimaryGroup(userName)) 133 .WillRepeatedly(Return(primaryGid)); 134 // Create privilege mapper dbus object 135 DbusUserObj object = createPrivilegeMapperDbusObject(); 136 EXPECT_CALL(mockManager, getPrivilegeMapperObject()) 137 .WillRepeatedly(Return(object)); 138 EXPECT_CALL(mockManager, isGroupMember(userName, primaryGid, ldapGroup)) 139 .WillRepeatedly(Return(true)); 140 userInfo = mockManager.getUserInfo(userName); 141 EXPECT_EQ(true, std::get<bool>(userInfo["RemoteUser"])); 142 EXPECT_EQ("priv-admin", std::get<std::string>(userInfo["UserPrivilege"])); 143 } 144 145 TEST_F(TestUserMgr, ldapUserWithoutPrivMapper) 146 { 147 using ::testing::_; 148 149 UserInfoMap userInfo; 150 std::string userName = "ldapUser"; 151 std::string ldapGroup = "ldapGroup"; 152 gid_t primaryGid = 1000; 153 154 EXPECT_CALL(mockManager, getPrimaryGroup(userName)) 155 .WillRepeatedly(Return(primaryGid)); 156 // Create LDAP config object without privilege mapper 157 DbusUserObj object = createLdapConfigObjectWithoutPrivilegeMapper(); 158 EXPECT_CALL(mockManager, getPrivilegeMapperObject()) 159 .WillRepeatedly(Return(object)); 160 EXPECT_CALL(mockManager, isGroupMember(_, _, _)).Times(0); 161 userInfo = mockManager.getUserInfo(userName); 162 EXPECT_EQ(true, std::get<bool>(userInfo["RemoteUser"])); 163 EXPECT_EQ("priv-user", std::get<std::string>(userInfo["UserPrivilege"])); 164 } 165 166 TEST(GetCSVFromVector, EmptyVectorReturnsEmptyString) 167 { 168 EXPECT_EQ(getCSVFromVector({}), ""); 169 } 170 171 TEST(GetCSVFromVector, ElementsAreJoinedByComma) 172 { 173 EXPECT_EQ(getCSVFromVector(std::vector<std::string>{"123"}), "123"); 174 EXPECT_EQ(getCSVFromVector(std::vector<std::string>{"123", "456"}), 175 "123,456"); 176 } 177 178 TEST(RemoveStringFromCSV, WithoutDeleteStringReturnsFalse) 179 { 180 std::string expected = "whatever,https"; 181 std::string str = expected; 182 EXPECT_FALSE(removeStringFromCSV(str, "ssh")); 183 EXPECT_EQ(str, expected); 184 185 std::string empty; 186 EXPECT_FALSE(removeStringFromCSV(empty, "ssh")); 187 } 188 189 TEST(RemoveStringFromCSV, WithDeleteStringReturnsTrue) 190 { 191 std::string expected = "whatever"; 192 std::string str = "whatever,https"; 193 EXPECT_TRUE(removeStringFromCSV(str, "https")); 194 EXPECT_EQ(str, expected); 195 196 str = "https"; 197 EXPECT_TRUE(removeStringFromCSV(str, "https")); 198 EXPECT_EQ(str, ""); 199 } 200 201 namespace 202 { 203 inline constexpr const char* objectRootInTest = "/xyz/openbmc_project/user"; 204 205 // Fake configs; referenced configs on real BMC 206 inline constexpr const char* rawConfig = R"( 207 # 208 # /etc/pam.d/common-password - password-related modules common to all services 209 # 210 # This file is included from other service-specific PAM config files, 211 # and should contain a list of modules that define the services to be 212 # used to change user passwords. The default is pam_unix. 213 214 # Explanation of pam_unix options: 215 # 216 # The "sha512" option enables salted SHA512 passwords. Without this option, 217 # the default is Unix crypt. Prior releases used the option "md5". 218 # 219 # The "obscure" option replaces the old `OBSCURE_CHECKS_ENAB' option in 220 # login.defs. 221 # 222 # See the pam_unix manpage for other options. 223 224 # here are the per-package modules (the "Primary" block) 225 password [success=ok default=die] pam_faillock.so authsucc 226 password [success=ok default=die] pam_pwquality.so debug 227 password [success=ok default=die] pam_ipmicheck.so spec_grp_name=ipmi use_authtok 228 password [success=ok ignore=ignore default=die] pam_pwhistory.so debug enforce_for_root remember=0 use_authtok 229 password [success=ok default=die] pam_unix.so sha512 use_authtok 230 password [success=1 default=die] pam_ipmisave.so spec_grp_name=ipmi spec_pass_file=/etc/ipmi_pass key_file=/etc/key_file 231 # here's the fallback if no module succeeds 232 password requisite pam_deny.so 233 # prime the stack with a positive return value if there isn't one already; 234 # this avoids us returning an error just because nothing sets a success code 235 # since the modules above will each just jump around 236 password required pam_permit.so 237 # and here are more per-package modules (the "Additional" block) 238 )"; 239 inline constexpr const char* rawFailLockConfig = R"( 240 deny=2 241 unlock_time=3 242 )"; 243 inline constexpr const char* rawPWQualityConfig = R"( 244 enforce_for_root 245 minlen=8 246 difok=0 247 lcredit=0 248 ocredit=0 249 dcredit=0 250 ucredit=0 251 )"; 252 } // namespace 253 254 void dumpStringToFile(const std::string& str, const std::string& filePath) 255 { 256 std::ofstream outputFileStream; 257 258 outputFileStream.exceptions(std::ofstream::failbit | std::ofstream::badbit | 259 std::ofstream::eofbit); 260 261 outputFileStream.open(filePath, std::ios::out); 262 outputFileStream << str << "\n" << std::flush; 263 outputFileStream.close(); 264 } 265 266 void removeFile(const std::string& filePath) 267 { 268 std::filesystem::remove(filePath); 269 } 270 271 class UserMgrInTest : public testing::Test, public UserMgr 272 { 273 public: 274 UserMgrInTest() : UserMgr(busInTest, objectRootInTest) 275 { 276 tempPamConfigFile = "/tmp/test-data-XXXXXX"; 277 mktemp(tempPamConfigFile.data()); 278 EXPECT_NO_THROW(dumpStringToFile(rawConfig, tempPamConfigFile)); 279 tempFaillockConfigFile = "/tmp/test-data-XXXXXX"; 280 mktemp(tempFaillockConfigFile.data()); 281 EXPECT_NO_THROW( 282 dumpStringToFile(rawFailLockConfig, tempFaillockConfigFile)); 283 tempPWQualityConfigFile = "/tmp/test-data-XXXXXX"; 284 mktemp(tempPWQualityConfigFile.data()); 285 EXPECT_NO_THROW( 286 dumpStringToFile(rawPWQualityConfig, tempPWQualityConfigFile)); 287 // Set config files to test files 288 pamPasswdConfigFile = tempPamConfigFile; 289 faillockConfigFile = tempFaillockConfigFile; 290 pwQualityConfigFile = tempPWQualityConfigFile; 291 292 ON_CALL(*this, executeUserAdd).WillByDefault(testing::Return()); 293 294 ON_CALL(*this, executeUserDelete).WillByDefault(testing::Return()); 295 296 ON_CALL(*this, getIpmiUsersCount).WillByDefault(testing::Return(0)); 297 298 ON_CALL(*this, executeUserRename).WillByDefault(testing::Return()); 299 300 ON_CALL(*this, executeUserModify(testing::_, testing::_, testing::_)) 301 .WillByDefault(testing::Return()); 302 303 ON_CALL(*this, executeUserModifyUserEnable) 304 .WillByDefault(testing::Return()); 305 306 ON_CALL(*this, executeGroupCreation(testing::_)) 307 .WillByDefault(testing::Return()); 308 309 ON_CALL(*this, executeGroupDeletion(testing::_)) 310 .WillByDefault(testing::Return()); 311 312 ON_CALL(*this, executeGroupCreation).WillByDefault(testing::Return()); 313 314 ON_CALL(*this, executeGroupDeletion).WillByDefault(testing::Return()); 315 } 316 317 ~UserMgrInTest() override 318 { 319 EXPECT_NO_THROW(removeFile(tempPamConfigFile)); 320 EXPECT_NO_THROW(removeFile(tempFaillockConfigFile)); 321 EXPECT_NO_THROW(removeFile(tempPWQualityConfigFile)); 322 } 323 324 MOCK_METHOD(void, executeUserAdd, (const char*, const char*, bool, bool), 325 (override)); 326 327 MOCK_METHOD(void, executeUserDelete, (const char*), (override)); 328 329 MOCK_METHOD(size_t, getIpmiUsersCount, (), (override)); 330 331 MOCK_METHOD(void, executeUserRename, (const char*, const char*), 332 (override)); 333 334 MOCK_METHOD(void, executeUserModify, (const char*, const char*, bool), 335 (override)); 336 337 MOCK_METHOD(void, executeUserModifyUserEnable, (const char*, bool), 338 (override)); 339 340 MOCK_METHOD(std::vector<std::string>, getFailedAttempt, (const char*), 341 (override)); 342 343 MOCK_METHOD(void, executeGroupCreation, (const char*), (override)); 344 345 MOCK_METHOD(void, executeGroupDeletion, (const char*), (override)); 346 347 protected: 348 static sdbusplus::bus_t busInTest; 349 std::string tempPamConfigFile; 350 std::string tempFaillockConfigFile; 351 std::string tempPWQualityConfigFile; 352 }; 353 354 sdbusplus::bus_t UserMgrInTest::busInTest = sdbusplus::bus::new_default(); 355 356 TEST_F(UserMgrInTest, GetPamModuleArgValueOnSuccess) 357 { 358 std::string remember; 359 EXPECT_EQ(getPamModuleArgValue("pam_pwhistory.so", "remember", remember), 360 0); 361 EXPECT_EQ(remember, "0"); 362 } 363 364 TEST_F(UserMgrInTest, GetPamModuleConfValueOnSuccess) 365 { 366 std::string minlen; 367 EXPECT_EQ(getPamModuleConfValue(tempPWQualityConfigFile, "minlen", minlen), 368 0); 369 EXPECT_EQ(minlen, "8"); 370 std::string deny; 371 EXPECT_EQ(getPamModuleConfValue(tempFaillockConfigFile, "deny", deny), 0); 372 EXPECT_EQ(deny, "2"); 373 } 374 375 TEST_F(UserMgrInTest, SetPamModuleArgValueOnSuccess) 376 { 377 EXPECT_EQ(setPamModuleArgValue("pam_pwhistory.so", "remember", "1"), 0); 378 std::string remember; 379 EXPECT_EQ(getPamModuleArgValue("pam_pwhistory.so", "remember", remember), 380 0); 381 EXPECT_EQ(remember, "1"); 382 } 383 384 TEST_F(UserMgrInTest, SetPamModuleConfValueOnSuccess) 385 { 386 EXPECT_EQ(setPamModuleConfValue(tempPWQualityConfigFile, "minlen", "16"), 387 0); 388 std::string minlen; 389 EXPECT_EQ(getPamModuleConfValue(tempPWQualityConfigFile, "minlen", minlen), 390 0); 391 EXPECT_EQ(minlen, "16"); 392 393 EXPECT_EQ(setPamModuleConfValue(tempFaillockConfigFile, "deny", "3"), 0); 394 std::string deny; 395 EXPECT_EQ(getPamModuleConfValue(tempFaillockConfigFile, "deny", deny), 0); 396 EXPECT_EQ(deny, "3"); 397 } 398 399 TEST_F(UserMgrInTest, GetPamModuleArgValueOnFailure) 400 { 401 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPamConfigFile)); 402 std::string remember; 403 EXPECT_EQ(getPamModuleArgValue("pam_pwhistory.so", "remember", remember), 404 -1); 405 406 EXPECT_NO_THROW(removeFile(tempPamConfigFile)); 407 EXPECT_EQ(getPamModuleArgValue("pam_pwhistory.so", "remember", remember), 408 -1); 409 } 410 411 TEST_F(UserMgrInTest, GetPamModuleConfValueOnFailure) 412 { 413 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWQualityConfigFile)); 414 std::string minlen; 415 EXPECT_EQ(getPamModuleConfValue(tempPWQualityConfigFile, "minlen", minlen), 416 -1); 417 418 EXPECT_NO_THROW(removeFile(tempPWQualityConfigFile)); 419 EXPECT_EQ(getPamModuleConfValue(tempPWQualityConfigFile, "minlen", minlen), 420 -1); 421 422 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 423 std::string deny; 424 EXPECT_EQ(getPamModuleConfValue(tempFaillockConfigFile, "deny", deny), -1); 425 426 EXPECT_NO_THROW(removeFile(tempFaillockConfigFile)); 427 EXPECT_EQ(getPamModuleConfValue(tempFaillockConfigFile, "deny", deny), -1); 428 } 429 430 TEST_F(UserMgrInTest, SetPamModuleArgValueOnFailure) 431 { 432 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPamConfigFile)); 433 EXPECT_EQ(setPamModuleArgValue("pam_pwhistory.so", "remember", "1"), -1); 434 435 EXPECT_NO_THROW(removeFile(tempPamConfigFile)); 436 EXPECT_EQ(setPamModuleArgValue("pam_pwhistory.so", "remember", "1"), -1); 437 } 438 439 TEST_F(UserMgrInTest, SetPamModuleConfValueOnFailure) 440 { 441 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWQualityConfigFile)); 442 EXPECT_EQ(setPamModuleConfValue(tempPWQualityConfigFile, "minlen", "16"), 443 -1); 444 445 EXPECT_NO_THROW(removeFile(tempPWQualityConfigFile)); 446 EXPECT_EQ(setPamModuleConfValue(tempPWQualityConfigFile, "minlen", "16"), 447 -1); 448 449 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 450 EXPECT_EQ(setPamModuleConfValue(tempFaillockConfigFile, "deny", "3"), -1); 451 452 EXPECT_NO_THROW(removeFile(tempFaillockConfigFile)); 453 EXPECT_EQ(setPamModuleConfValue(tempFaillockConfigFile, "deny", "3"), -1); 454 } 455 456 TEST_F(UserMgrInTest, IsUserExistEmptyInputThrowsError) 457 { 458 EXPECT_THROW( 459 isUserExist(""), 460 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 461 } 462 463 TEST_F(UserMgrInTest, ThrowForUserDoesNotExistThrowsError) 464 { 465 EXPECT_THROW(throwForUserDoesNotExist("whatever"), 466 sdbusplus::xyz::openbmc_project::User::Common::Error:: 467 UserNameDoesNotExist); 468 } 469 470 TEST_F(UserMgrInTest, ThrowForUserExistsThrowsError) 471 { 472 EXPECT_THROW( 473 throwForUserExists("root"), 474 sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameExists); 475 } 476 477 TEST_F( 478 UserMgrInTest, 479 ThrowForUserNameConstraintsExceedIpmiMaxUserNameLenThrowsUserNameGroupFail) 480 { 481 std::string strWith17Chars(17, 'A'); 482 EXPECT_THROW(throwForUserNameConstraints(strWith17Chars, {"ipmi"}), 483 sdbusplus::xyz::openbmc_project::User::Common::Error:: 484 UserNameGroupFail); 485 } 486 487 TEST_F( 488 UserMgrInTest, 489 ThrowForUserNameConstraintsExceedSystemMaxUserNameLenThrowsInvalidArgument) 490 { 491 std::string strWith31Chars(31, 'A'); 492 EXPECT_THROW( 493 throwForUserNameConstraints(strWith31Chars, {}), 494 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 495 } 496 497 TEST_F(UserMgrInTest, 498 ThrowForUserNameConstraintsRegexMismatchThrowsInvalidArgument) 499 { 500 std::string startWithNumber = "0ABC"; 501 EXPECT_THROW( 502 throwForUserNameConstraints(startWithNumber, {"ipmi"}), 503 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 504 } 505 506 TEST_F(UserMgrInTest, UserAddNotRootFailedWithInternalFailure) 507 { 508 EXPECT_THROW( 509 UserMgr::executeUserAdd("user0", "ipmi,ssh", true, true), 510 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 511 } 512 513 TEST_F(UserMgrInTest, UserDeleteNotRootFailedWithInternalFailure) 514 { 515 EXPECT_THROW( 516 UserMgr::executeUserDelete("user0"), 517 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 518 } 519 520 TEST_F(UserMgrInTest, 521 ThrowForMaxGrpUserCountThrowsNoResourceWhenIpmiUserExceedLimit) 522 { 523 EXPECT_CALL(*this, getIpmiUsersCount()).WillOnce(Return(ipmiMaxUsers)); 524 EXPECT_THROW( 525 throwForMaxGrpUserCount({"ipmi"}), 526 sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource); 527 } 528 529 TEST_F(UserMgrInTest, CreateUserThrowsInternalFailureWhenExecuteUserAddFails) 530 { 531 EXPECT_CALL(*this, executeUserAdd) 532 .WillOnce(testing::Throw( 533 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 534 EXPECT_THROW( 535 createUser("whatever", {"redfish"}, "", true), 536 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 537 } 538 539 TEST_F(UserMgrInTest, DeleteUserThrowsInternalFailureWhenExecuteUserDeleteFails) 540 { 541 std::string username = "user"; 542 EXPECT_NO_THROW( 543 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 544 EXPECT_CALL(*this, executeUserDelete(testing::StrEq(username))) 545 .WillOnce(testing::Throw( 546 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())) 547 .WillOnce(testing::DoDefault()); 548 549 EXPECT_THROW( 550 deleteUser(username), 551 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 552 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 553 } 554 555 TEST_F(UserMgrInTest, ThrowForInvalidPrivilegeThrowsWhenPrivilegeIsInvalid) 556 { 557 EXPECT_THROW( 558 throwForInvalidPrivilege("whatever"), 559 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 560 } 561 562 TEST_F(UserMgrInTest, ThrowForInvalidPrivilegeNoThrowWhenPrivilegeIsValid) 563 { 564 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-admin")); 565 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-operator")); 566 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-user")); 567 } 568 569 TEST_F(UserMgrInTest, ThrowForInvalidGroupsThrowsWhenGroupIsInvalid) 570 { 571 EXPECT_THROW( 572 throwForInvalidGroups({"whatever"}), 573 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 574 } 575 576 TEST_F(UserMgrInTest, ThrowForInvalidGroupsNoThrowWhenGroupIsValid) 577 { 578 EXPECT_NO_THROW(throwForInvalidGroups({"ipmi"})); 579 EXPECT_NO_THROW(throwForInvalidGroups({"ssh"})); 580 EXPECT_NO_THROW(throwForInvalidGroups({"redfish"})); 581 EXPECT_NO_THROW(throwForInvalidGroups({"web"})); 582 EXPECT_NO_THROW(throwForInvalidGroups({"hostconsole"})); 583 } 584 585 TEST_F(UserMgrInTest, RenameUserOnSuccess) 586 { 587 std::string username = "user001"; 588 EXPECT_NO_THROW( 589 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 590 std::string newUsername = "user002"; 591 592 EXPECT_NO_THROW(UserMgr::renameUser(username, newUsername)); 593 594 // old username doesn't exist 595 EXPECT_THROW(getUserInfo(username), 596 sdbusplus::xyz::openbmc_project::User::Common::Error:: 597 UserNameDoesNotExist); 598 599 UserInfoMap userInfo = getUserInfo(newUsername); 600 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-user"); 601 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]), 602 testing::UnorderedElementsAre("redfish", "ssh")); 603 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 604 605 EXPECT_NO_THROW(UserMgr::deleteUser(newUsername)); 606 } 607 608 TEST_F(UserMgrInTest, RenameUserThrowsInternalFailureIfExecuteUserModifyFails) 609 { 610 std::string username = "user001"; 611 EXPECT_NO_THROW( 612 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 613 std::string newUsername = "user002"; 614 615 EXPECT_CALL(*this, executeUserRename(testing::StrEq(username), 616 testing::StrEq(newUsername))) 617 .WillOnce(testing::Throw( 618 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 619 EXPECT_THROW( 620 UserMgr::renameUser(username, newUsername), 621 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 622 623 // The original user is unchanged 624 UserInfoMap userInfo = getUserInfo(username); 625 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-user"); 626 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]), 627 testing::UnorderedElementsAre("redfish", "ssh")); 628 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 629 630 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 631 } 632 633 TEST_F(UserMgrInTest, DefaultUserModifyFailedWithInternalFailure) 634 { 635 EXPECT_THROW( 636 UserMgr::executeUserRename("user0", "user1"), 637 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 638 EXPECT_THROW( 639 UserMgr::executeUserModify("user0", "ssh", true), 640 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 641 } 642 643 TEST_F(UserMgrInTest, UpdateGroupsAndPrivOnSuccess) 644 { 645 std::string username = "user001"; 646 EXPECT_NO_THROW( 647 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 648 EXPECT_NO_THROW( 649 updateGroupsAndPriv(username, {"ipmi", "ssh"}, "priv-admin")); 650 UserInfoMap userInfo = getUserInfo(username); 651 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-admin"); 652 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]), 653 testing::UnorderedElementsAre("ipmi", "ssh")); 654 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 655 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 656 } 657 658 TEST_F(UserMgrInTest, 659 UpdateGroupsAndPrivThrowsInternalFailureIfExecuteUserModifyFail) 660 { 661 std::string username = "user001"; 662 EXPECT_NO_THROW( 663 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 664 EXPECT_CALL(*this, executeUserModify(testing::StrEq(username), testing::_, 665 testing::_)) 666 .WillOnce(testing::Throw( 667 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 668 EXPECT_THROW( 669 updateGroupsAndPriv(username, {"ipmi", "ssh"}, "priv-admin"), 670 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 671 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 672 } 673 674 TEST_F(UserMgrInTest, MinPasswordLengthReturnsIfValueIsTheSame) 675 { 676 initializeAccountPolicy(); 677 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 678 UserMgr::minPasswordLength(8); 679 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 680 } 681 682 TEST_F(UserMgrInTest, 683 MinPasswordLengthRejectsTooShortPasswordWithInvalidArgument) 684 { 685 initializeAccountPolicy(); 686 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 687 EXPECT_THROW( 688 UserMgr::minPasswordLength(minPasswdLength - 1), 689 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 690 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 691 } 692 693 TEST_F(UserMgrInTest, MinPasswordLengthOnSuccess) 694 { 695 initializeAccountPolicy(); 696 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 697 UserMgr::minPasswordLength(16); 698 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 16); 699 } 700 701 TEST_F(UserMgrInTest, MinPasswordLengthOnFailure) 702 { 703 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWQualityConfigFile)); 704 initializeAccountPolicy(); 705 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 706 EXPECT_THROW( 707 UserMgr::minPasswordLength(16), 708 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 709 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 710 } 711 712 TEST_F(UserMgrInTest, RememberOldPasswordTimesReturnsIfValueIsTheSame) 713 { 714 initializeAccountPolicy(); 715 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 716 UserMgr::rememberOldPasswordTimes(8); 717 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 8); 718 UserMgr::rememberOldPasswordTimes(8); 719 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 8); 720 } 721 722 TEST_F(UserMgrInTest, RememberOldPasswordTimesOnSuccess) 723 { 724 initializeAccountPolicy(); 725 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 726 UserMgr::rememberOldPasswordTimes(16); 727 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 16); 728 } 729 730 TEST_F(UserMgrInTest, RememberOldPasswordTimesOnFailure) 731 { 732 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPamConfigFile)); 733 initializeAccountPolicy(); 734 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 735 EXPECT_THROW( 736 UserMgr::rememberOldPasswordTimes(16), 737 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 738 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 739 } 740 741 TEST_F(UserMgrInTest, MaxLoginAttemptBeforeLockoutReturnsIfValueIsTheSame) 742 { 743 initializeAccountPolicy(); 744 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 745 UserMgr::maxLoginAttemptBeforeLockout(2); 746 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 747 } 748 749 TEST_F(UserMgrInTest, MaxLoginAttemptBeforeLockoutOnSuccess) 750 { 751 initializeAccountPolicy(); 752 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 753 UserMgr::maxLoginAttemptBeforeLockout(16); 754 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 16); 755 } 756 757 TEST_F(UserMgrInTest, MaxLoginAttemptBeforeLockoutOnFailure) 758 { 759 initializeAccountPolicy(); 760 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 761 EXPECT_THROW( 762 UserMgr::maxLoginAttemptBeforeLockout(16), 763 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 764 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 765 } 766 767 TEST_F(UserMgrInTest, AccountUnlockTimeoutReturnsIfValueIsTheSame) 768 { 769 initializeAccountPolicy(); 770 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 771 UserMgr::accountUnlockTimeout(3); 772 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 773 } 774 775 TEST_F(UserMgrInTest, AccountUnlockTimeoutOnSuccess) 776 { 777 initializeAccountPolicy(); 778 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 779 UserMgr::accountUnlockTimeout(16); 780 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 16); 781 } 782 783 TEST_F(UserMgrInTest, AccountUnlockTimeoutOnFailure) 784 { 785 initializeAccountPolicy(); 786 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 787 EXPECT_THROW( 788 UserMgr::accountUnlockTimeout(16), 789 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 790 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 791 } 792 793 TEST_F(UserMgrInTest, UserEnableOnSuccess) 794 { 795 std::string username = "user001"; 796 EXPECT_NO_THROW( 797 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 798 UserInfoMap userInfo = getUserInfo(username); 799 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 800 801 EXPECT_NO_THROW(userEnable(username, false)); 802 803 userInfo = getUserInfo(username); 804 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), false); 805 806 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 807 } 808 809 TEST_F(UserMgrInTest, CreateDeleteUserSuccessForHostConsole) 810 { 811 std::string username = "user001"; 812 EXPECT_NO_THROW( 813 UserMgr::createUser(username, {"hostconsole"}, "priv-user", true)); 814 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 815 EXPECT_NO_THROW( 816 UserMgr::createUser(username, {"hostconsole"}, "priv-admin", true)); 817 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 818 EXPECT_NO_THROW( 819 UserMgr::createUser(username, {"hostconsole"}, "priv-operator", true)); 820 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 821 } 822 823 TEST_F(UserMgrInTest, UserEnableThrowsInternalFailureIfExecuteUserModifyFail) 824 { 825 std::string username = "user001"; 826 EXPECT_NO_THROW( 827 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 828 UserInfoMap userInfo = getUserInfo(username); 829 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 830 831 EXPECT_CALL(*this, executeUserModifyUserEnable(testing::StrEq(username), 832 testing::Eq(false))) 833 .WillOnce(testing::Throw( 834 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 835 EXPECT_THROW( 836 userEnable(username, false), 837 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 838 839 userInfo = getUserInfo(username); 840 // Stay unchanged 841 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 842 843 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 844 } 845 846 TEST_F( 847 UserMgrInTest, 848 UserLockedForFailedAttemptReturnsFalseIfMaxLoginAttemptBeforeLockoutIsZero) 849 { 850 EXPECT_FALSE(userLockedForFailedAttempt("whatever")); 851 } 852 853 TEST_F(UserMgrInTest, UserLockedForFailedAttemptZeroFailuresReturnsFalse) 854 { 855 std::string username = "user001"; 856 initializeAccountPolicy(); 857 // Example output from BMC 858 // root:~# faillock --user root 859 // root: 860 // When Type Source Valid 861 std::vector<std::string> output = {"whatever", 862 "When Type Source Valid"}; 863 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 864 .WillOnce(testing::Return(output)); 865 866 EXPECT_FALSE(userLockedForFailedAttempt(username)); 867 } 868 869 TEST_F(UserMgrInTest, UserLockedForFailedAttemptFailIfGetFailedAttemptFail) 870 { 871 std::string username = "user001"; 872 initializeAccountPolicy(); 873 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 874 .WillOnce(testing::Throw( 875 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 876 877 EXPECT_THROW( 878 userLockedForFailedAttempt(username), 879 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 880 } 881 882 TEST_F(UserMgrInTest, 883 UserLockedForFailedAttemptThrowsInternalFailureIfWrongDateFormat) 884 { 885 std::string username = "user001"; 886 initializeAccountPolicy(); 887 888 // Choose a date in the past. 889 std::vector<std::string> output = {"whatever", 890 "10/24/2002 00:00:00 type source V"}; 891 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 892 .WillOnce(testing::Return(output)); 893 894 EXPECT_THROW( 895 userLockedForFailedAttempt(username), 896 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 897 } 898 899 TEST_F(UserMgrInTest, 900 UserLockedForFailedAttemptReturnsFalseIfLastFailTimeHasTimedOut) 901 { 902 std::string username = "user001"; 903 initializeAccountPolicy(); 904 905 // Choose a date in the past. 906 std::vector<std::string> output = {"whatever", 907 "2002-10-24 00:00:00 type source V"}; 908 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 909 .WillOnce(testing::Return(output)); 910 911 EXPECT_EQ(userLockedForFailedAttempt(username), false); 912 } 913 914 TEST_F(UserMgrInTest, CheckAndThrowForDisallowedGroupCreationOnSuccess) 915 { 916 // Base Redfish Roles 917 EXPECT_NO_THROW( 918 checkAndThrowForDisallowedGroupCreation("openbmc_rfr_Administrator")); 919 EXPECT_NO_THROW( 920 checkAndThrowForDisallowedGroupCreation("openbmc_rfr_Operator")); 921 EXPECT_NO_THROW( 922 checkAndThrowForDisallowedGroupCreation("openbmc_rfr_ReadOnly")); 923 // Base Redfish Privileges 924 EXPECT_NO_THROW( 925 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_Login")); 926 EXPECT_NO_THROW(checkAndThrowForDisallowedGroupCreation( 927 "openbmc_rfp_ConfigureManager")); 928 EXPECT_NO_THROW( 929 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_ConfigureUsers")); 930 EXPECT_NO_THROW( 931 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_ConfigureSelf")); 932 EXPECT_NO_THROW(checkAndThrowForDisallowedGroupCreation( 933 "openbmc_rfp_ConfigureComponents")); 934 // OEM Redfish Roles 935 EXPECT_NO_THROW( 936 checkAndThrowForDisallowedGroupCreation("openbmc_orfr_PowerService")); 937 // OEM Redfish Privileges 938 EXPECT_NO_THROW( 939 checkAndThrowForDisallowedGroupCreation("openbmc_orfp_PowerService")); 940 } 941 942 TEST_F(UserMgrInTest, 943 CheckAndThrowForDisallowedGroupCreationThrowsIfGroupNameTooLong) 944 { 945 std::string groupName(maxSystemGroupNameLength + 1, 'A'); 946 EXPECT_THROW( 947 checkAndThrowForDisallowedGroupCreation(groupName), 948 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 949 } 950 951 TEST_F( 952 UserMgrInTest, 953 CheckAndThrowForDisallowedGroupCreationThrowsIfGroupNameHasDisallowedCharacters) 954 { 955 EXPECT_THROW( 956 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_?owerService"), 957 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 958 EXPECT_THROW( 959 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_-owerService"), 960 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 961 } 962 963 TEST_F( 964 UserMgrInTest, 965 CheckAndThrowForDisallowedGroupCreationThrowsIfGroupNameHasDisallowedPrefix) 966 { 967 EXPECT_THROW( 968 checkAndThrowForDisallowedGroupCreation("google_rfp_"), 969 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 970 EXPECT_THROW( 971 checkAndThrowForDisallowedGroupCreation("com_rfp_"), 972 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 973 } 974 975 TEST_F(UserMgrInTest, CheckAndThrowForMaxGroupCountOnSuccess) 976 { 977 constexpr size_t predefGroupCount = 5; 978 979 EXPECT_THAT(allGroups().size(), predefGroupCount); 980 for (size_t i = 0; i < maxSystemGroupCount - predefGroupCount; ++i) 981 { 982 std::string groupName = "openbmc_rfr_role"; 983 groupName += std::to_string(i); 984 EXPECT_NO_THROW(createGroup(groupName)); 985 } 986 EXPECT_THROW( 987 createGroup("openbmc_rfr_AnotherRole"), 988 sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource); 989 for (size_t i = 0; i < maxSystemGroupCount - predefGroupCount; ++i) 990 { 991 std::string groupName = "openbmc_rfr_role"; 992 groupName += std::to_string(i); 993 EXPECT_NO_THROW(deleteGroup(groupName)); 994 } 995 } 996 997 TEST_F(UserMgrInTest, CheckAndThrowForGroupExist) 998 { 999 std::string groupName = "openbmc_rfr_role"; 1000 EXPECT_NO_THROW(createGroup(groupName)); 1001 EXPECT_THROW( 1002 createGroup(groupName), 1003 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1004 EXPECT_NO_THROW(deleteGroup(groupName)); 1005 } 1006 1007 TEST_F(UserMgrInTest, ByDefaultAllGroupsArePredefinedGroups) 1008 { 1009 EXPECT_THAT(allGroups(), 1010 testing::UnorderedElementsAre("web", "redfish", "ipmi", "ssh", 1011 "hostconsole")); 1012 } 1013 1014 TEST_F(UserMgrInTest, AddGroupThrowsIfPreDefinedGroupAdd) 1015 { 1016 EXPECT_THROW( 1017 createGroup("ipmi"), 1018 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1019 EXPECT_THROW( 1020 createGroup("web"), 1021 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1022 EXPECT_THROW( 1023 createGroup("redfish"), 1024 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1025 EXPECT_THROW( 1026 createGroup("ssh"), 1027 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1028 EXPECT_THROW( 1029 createGroup("hostconsole"), 1030 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1031 } 1032 1033 TEST_F(UserMgrInTest, DeleteGroupThrowsIfGroupIsNotAllowedToChange) 1034 { 1035 EXPECT_THROW( 1036 deleteGroup("ipmi"), 1037 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1038 EXPECT_THROW( 1039 deleteGroup("web"), 1040 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1041 EXPECT_THROW( 1042 deleteGroup("redfish"), 1043 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1044 EXPECT_THROW( 1045 deleteGroup("ssh"), 1046 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1047 EXPECT_THROW( 1048 deleteGroup("hostconsole"), 1049 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1050 } 1051 1052 TEST_F(UserMgrInTest, 1053 CreateGroupThrowsInternalFailureWhenExecuteGroupCreateFails) 1054 { 1055 EXPECT_CALL(*this, executeGroupCreation) 1056 .WillOnce(testing::Throw( 1057 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 1058 EXPECT_THROW( 1059 createGroup("openbmc_rfr_role1"), 1060 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 1061 } 1062 1063 TEST_F(UserMgrInTest, 1064 DeleteGroupThrowsInternalFailureWhenExecuteGroupDeleteFails) 1065 { 1066 std::string groupName = "openbmc_rfr_role1"; 1067 EXPECT_NO_THROW(UserMgr::createGroup(groupName)); 1068 EXPECT_CALL(*this, executeGroupDeletion(testing::StrEq(groupName))) 1069 .WillOnce(testing::Throw( 1070 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())) 1071 .WillOnce(testing::DoDefault()); 1072 1073 EXPECT_THROW( 1074 deleteGroup(groupName), 1075 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 1076 EXPECT_NO_THROW(UserMgr::deleteGroup(groupName)); 1077 } 1078 1079 TEST_F(UserMgrInTest, CheckAndThrowForGroupNotExist) 1080 { 1081 EXPECT_THROW(deleteGroup("whatever"), 1082 sdbusplus::xyz::openbmc_project::User::Common::Error:: 1083 GroupNameDoesNotExist); 1084 } 1085 1086 TEST(ReadAllGroupsOnSystemTest, OnlyReturnsPredefinedGroups) 1087 { 1088 EXPECT_THAT(UserMgr::readAllGroupsOnSystem(), 1089 testing::UnorderedElementsAre("web", "redfish", "ipmi", "ssh", 1090 "hostconsole")); 1091 } 1092 1093 } // namespace user 1094 } // namespace phosphor 1095