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