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 std::string startWithDisallowedCharacter = "[test"; 568 EXPECT_THROW( 569 throwForUserNameConstraints(startWithNumber, {"ipmi"}), 570 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 571 EXPECT_THROW( 572 throwForUserNameConstraints(startWithDisallowedCharacter, {"ipmi"}), 573 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 574 } 575 576 TEST_F(UserMgrInTest, UserAddNotRootFailedWithInternalFailure) 577 { 578 EXPECT_THROW( 579 UserMgr::executeUserAdd("user0", "ipmi,ssh", true, true), 580 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 581 } 582 583 TEST_F(UserMgrInTest, UserDeleteNotRootFailedWithInternalFailure) 584 { 585 EXPECT_THROW( 586 UserMgr::executeUserDelete("user0"), 587 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 588 } 589 590 TEST_F(UserMgrInTest, 591 ThrowForMaxGrpUserCountThrowsNoResourceWhenIpmiUserExceedLimit) 592 { 593 EXPECT_CALL(*this, getIpmiUsersCount()).WillOnce(Return(ipmiMaxUsers)); 594 EXPECT_THROW( 595 throwForMaxGrpUserCount({"ipmi"}), 596 sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource); 597 } 598 599 TEST_F(UserMgrInTest, CreateUserThrowsInternalFailureWhenExecuteUserAddFails) 600 { 601 EXPECT_CALL(*this, executeUserAdd) 602 .WillOnce(testing::Throw( 603 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 604 EXPECT_THROW( 605 createUser("whatever", {"redfish"}, "", true), 606 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 607 } 608 609 TEST_F(UserMgrInTest, DeleteUserThrowsInternalFailureWhenExecuteUserDeleteFails) 610 { 611 std::string username = "user"; 612 EXPECT_NO_THROW( 613 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 614 EXPECT_CALL(*this, executeUserDelete(testing::StrEq(username))) 615 .WillOnce(testing::Throw( 616 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())) 617 .WillOnce(testing::DoDefault()); 618 619 EXPECT_THROW( 620 deleteUser(username), 621 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 622 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 623 } 624 625 TEST_F(UserMgrInTest, 626 DeleteUserThrowsInternalFailureWhenExecuteUserClearFailRecords) 627 { 628 const char* username = "user"; 629 EXPECT_NO_THROW( 630 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 631 EXPECT_CALL(*this, executeUserClearFailRecords(testing::StrEq(username))) 632 .WillOnce(testing::Throw( 633 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())) 634 .WillOnce(testing::DoDefault()); 635 636 EXPECT_THROW( 637 deleteUser(username), 638 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 639 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 640 } 641 642 TEST_F(UserMgrInTest, ThrowForInvalidPrivilegeThrowsWhenPrivilegeIsInvalid) 643 { 644 EXPECT_THROW( 645 throwForInvalidPrivilege("whatever"), 646 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 647 } 648 649 TEST_F(UserMgrInTest, ThrowForInvalidPrivilegeNoThrowWhenPrivilegeIsValid) 650 { 651 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-admin")); 652 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-operator")); 653 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-user")); 654 } 655 656 TEST_F(UserMgrInTest, ThrowForInvalidGroupsThrowsWhenGroupIsInvalid) 657 { 658 EXPECT_THROW( 659 throwForInvalidGroups({"whatever"}), 660 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 661 EXPECT_THROW( 662 throwForInvalidGroups({"web"}), 663 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 664 } 665 666 TEST_F(UserMgrInTest, ThrowForInvalidGroupsNoThrowWhenGroupIsValid) 667 { 668 EXPECT_NO_THROW(throwForInvalidGroups({"ipmi"})); 669 EXPECT_NO_THROW(throwForInvalidGroups({"ssh"})); 670 EXPECT_NO_THROW(throwForInvalidGroups({"redfish"})); 671 EXPECT_NO_THROW(throwForInvalidGroups({"hostconsole"})); 672 } 673 674 TEST_F(UserMgrInTest, RenameUserOnSuccess) 675 { 676 std::string username = "user001"; 677 EXPECT_NO_THROW( 678 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 679 std::string newUsername = "user002"; 680 681 EXPECT_NO_THROW(UserMgr::renameUser(username, newUsername)); 682 683 // old username doesn't exist 684 EXPECT_THROW(getUserInfo(username), 685 sdbusplus::xyz::openbmc_project::User::Common::Error:: 686 UserNameDoesNotExist); 687 688 UserInfoMap userInfo = getUserInfo(newUsername); 689 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-user"); 690 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]), 691 testing::UnorderedElementsAre("redfish", "ssh")); 692 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 693 694 EXPECT_NO_THROW(UserMgr::deleteUser(newUsername)); 695 } 696 697 TEST_F(UserMgrInTest, RenameUserThrowsInternalFailureIfExecuteUserModifyFails) 698 { 699 std::string username = "user001"; 700 EXPECT_NO_THROW( 701 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 702 std::string newUsername = "user002"; 703 704 EXPECT_CALL(*this, executeUserRename(testing::StrEq(username), 705 testing::StrEq(newUsername))) 706 .WillOnce(testing::Throw( 707 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 708 EXPECT_THROW( 709 UserMgr::renameUser(username, newUsername), 710 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 711 712 // The original user is unchanged 713 UserInfoMap userInfo = getUserInfo(username); 714 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-user"); 715 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]), 716 testing::UnorderedElementsAre("redfish", "ssh")); 717 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 718 719 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 720 } 721 722 TEST_F(UserMgrInTest, DefaultUserModifyFailedWithInternalFailure) 723 { 724 EXPECT_THROW( 725 UserMgr::executeUserRename("user0", "user1"), 726 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 727 EXPECT_THROW( 728 UserMgr::executeUserModify("user0", "ssh", true), 729 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 730 } 731 732 TEST_F(UserMgrInTest, UpdateGroupsAndPrivOnSuccess) 733 { 734 std::string username = "user001"; 735 EXPECT_NO_THROW( 736 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 737 EXPECT_NO_THROW( 738 updateGroupsAndPriv(username, {"ipmi", "ssh"}, "priv-admin")); 739 UserInfoMap userInfo = getUserInfo(username); 740 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-admin"); 741 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]), 742 testing::UnorderedElementsAre("ipmi", "ssh")); 743 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 744 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 745 } 746 747 TEST_F(UserMgrInTest, 748 UpdateGroupsAndPrivThrowsInternalFailureIfExecuteUserModifyFail) 749 { 750 std::string username = "user001"; 751 EXPECT_NO_THROW( 752 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 753 EXPECT_CALL(*this, executeUserModify(testing::StrEq(username), testing::_, 754 testing::_)) 755 .WillOnce(testing::Throw( 756 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 757 EXPECT_THROW( 758 updateGroupsAndPriv(username, {"ipmi", "ssh"}, "priv-admin"), 759 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 760 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 761 } 762 763 TEST_F(UserMgrInTest, MinPasswordLengthReturnsIfValueIsTheSame) 764 { 765 initializeAccountPolicy(); 766 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 767 UserMgr::minPasswordLength(8); 768 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 769 } 770 771 TEST_F(UserMgrInTest, 772 MinPasswordLengthRejectsTooShortPasswordWithInvalidArgument) 773 { 774 initializeAccountPolicy(); 775 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 776 EXPECT_THROW( 777 UserMgr::minPasswordLength(minPasswdLength - 1), 778 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 779 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 780 } 781 782 TEST_F(UserMgrInTest, MinPasswordLengthOnSuccess) 783 { 784 initializeAccountPolicy(); 785 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 786 UserMgr::minPasswordLength(16); 787 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 16); 788 } 789 790 TEST_F(UserMgrInTest, MinPasswordLengthOnFailure) 791 { 792 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWQualityConfigFile)); 793 initializeAccountPolicy(); 794 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 795 EXPECT_THROW( 796 UserMgr::minPasswordLength(16), 797 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 798 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 799 } 800 801 TEST_F(UserMgrInTest, RememberOldPasswordTimesReturnsIfValueIsTheSame) 802 { 803 initializeAccountPolicy(); 804 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 805 UserMgr::rememberOldPasswordTimes(8); 806 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 8); 807 UserMgr::rememberOldPasswordTimes(8); 808 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 8); 809 } 810 811 TEST_F(UserMgrInTest, RememberOldPasswordTimesOnSuccess) 812 { 813 initializeAccountPolicy(); 814 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 815 UserMgr::rememberOldPasswordTimes(16); 816 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 16); 817 } 818 819 TEST_F(UserMgrInTest, RememberOldPasswordTimesOnFailure) 820 { 821 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWHistoryConfigFile)); 822 initializeAccountPolicy(); 823 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 824 EXPECT_THROW( 825 UserMgr::rememberOldPasswordTimes(16), 826 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 827 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 828 } 829 830 TEST_F(UserMgrInTest, MaxLoginAttemptBeforeLockoutReturnsIfValueIsTheSame) 831 { 832 initializeAccountPolicy(); 833 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 834 UserMgr::maxLoginAttemptBeforeLockout(2); 835 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 836 } 837 838 TEST_F(UserMgrInTest, MaxLoginAttemptBeforeLockoutOnSuccess) 839 { 840 initializeAccountPolicy(); 841 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 842 UserMgr::maxLoginAttemptBeforeLockout(16); 843 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 16); 844 } 845 846 TEST_F(UserMgrInTest, MaxLoginAttemptBeforeLockoutOnFailure) 847 { 848 initializeAccountPolicy(); 849 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 850 EXPECT_THROW( 851 UserMgr::maxLoginAttemptBeforeLockout(16), 852 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 853 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 854 } 855 856 TEST_F(UserMgrInTest, AccountUnlockTimeoutReturnsIfValueIsTheSame) 857 { 858 initializeAccountPolicy(); 859 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 860 UserMgr::accountUnlockTimeout(3); 861 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 862 } 863 864 TEST_F(UserMgrInTest, AccountUnlockTimeoutOnSuccess) 865 { 866 initializeAccountPolicy(); 867 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 868 UserMgr::accountUnlockTimeout(16); 869 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 16); 870 } 871 872 TEST_F(UserMgrInTest, AccountUnlockTimeoutOnFailure) 873 { 874 initializeAccountPolicy(); 875 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 876 EXPECT_THROW( 877 UserMgr::accountUnlockTimeout(16), 878 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 879 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 880 } 881 882 TEST_F(UserMgrInTest, UserEnableOnSuccess) 883 { 884 std::string username = "user001"; 885 EXPECT_NO_THROW( 886 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 887 UserInfoMap userInfo = getUserInfo(username); 888 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 889 890 EXPECT_NO_THROW(userEnable(username, false)); 891 892 userInfo = getUserInfo(username); 893 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), false); 894 895 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 896 } 897 898 TEST_F(UserMgrInTest, CreateDeleteUserSuccessForHostConsole) 899 { 900 std::string username = "user001"; 901 EXPECT_NO_THROW( 902 UserMgr::createUser(username, {"hostconsole"}, "priv-user", true)); 903 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 904 EXPECT_NO_THROW( 905 UserMgr::createUser(username, {"hostconsole"}, "priv-admin", true)); 906 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 907 EXPECT_NO_THROW( 908 UserMgr::createUser(username, {"hostconsole"}, "priv-operator", true)); 909 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 910 } 911 912 TEST_F(UserMgrInTest, UserEnableThrowsInternalFailureIfExecuteUserModifyFail) 913 { 914 std::string username = "user001"; 915 EXPECT_NO_THROW( 916 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 917 UserInfoMap userInfo = getUserInfo(username); 918 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 919 920 EXPECT_CALL(*this, executeUserModifyUserEnable(testing::StrEq(username), 921 testing::Eq(false))) 922 .WillOnce(testing::Throw( 923 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 924 EXPECT_THROW( 925 userEnable(username, false), 926 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 927 928 userInfo = getUserInfo(username); 929 // Stay unchanged 930 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 931 932 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 933 } 934 935 TEST_F( 936 UserMgrInTest, 937 UserLockedForFailedAttemptReturnsFalseIfMaxLoginAttemptBeforeLockoutIsZero) 938 { 939 EXPECT_FALSE(userLockedForFailedAttempt("whatever")); 940 } 941 942 TEST_F(UserMgrInTest, UserLockedForFailedAttemptZeroFailuresReturnsFalse) 943 { 944 std::string username = "user001"; 945 initializeAccountPolicy(); 946 // Example output from BMC 947 // root:~# faillock --user root 948 // root: 949 // When Type Source Valid 950 std::vector<std::string> output = {"whatever", 951 "When Type Source Valid"}; 952 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 953 .WillOnce(testing::Return(output)); 954 955 EXPECT_FALSE(userLockedForFailedAttempt(username)); 956 } 957 958 TEST_F(UserMgrInTest, UserLockedForFailedAttemptFailIfGetFailedAttemptFail) 959 { 960 std::string username = "user001"; 961 initializeAccountPolicy(); 962 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 963 .WillOnce(testing::Throw( 964 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 965 966 EXPECT_THROW( 967 userLockedForFailedAttempt(username), 968 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 969 } 970 971 TEST_F(UserMgrInTest, 972 UserLockedForFailedAttemptThrowsInternalFailureIfWrongDateFormat) 973 { 974 std::string username = "user001"; 975 initializeAccountPolicy(); 976 977 // Choose a date in the past. 978 std::vector<std::string> output = {"whatever", 979 "10/24/2002 00:00:00 type source V"}; 980 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 981 .WillOnce(testing::Return(output)); 982 983 EXPECT_THROW( 984 userLockedForFailedAttempt(username), 985 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 986 } 987 988 TEST_F(UserMgrInTest, 989 UserLockedForFailedAttemptReturnsFalseIfLastFailTimeHasTimedOut) 990 { 991 std::string username = "user001"; 992 initializeAccountPolicy(); 993 994 // Choose a date in the past. 995 std::vector<std::string> output = {"whatever", 996 "2002-10-24 00:00:00 type source V"}; 997 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 998 .WillOnce(testing::Return(output)); 999 1000 EXPECT_EQ(userLockedForFailedAttempt(username), false); 1001 } 1002 1003 TEST_F(UserMgrInTest, CheckAndThrowForDisallowedGroupCreationOnSuccess) 1004 { 1005 // Base Redfish Roles 1006 EXPECT_NO_THROW( 1007 checkAndThrowForDisallowedGroupCreation("openbmc_rfr_Administrator")); 1008 EXPECT_NO_THROW( 1009 checkAndThrowForDisallowedGroupCreation("openbmc_rfr_Operator")); 1010 EXPECT_NO_THROW( 1011 checkAndThrowForDisallowedGroupCreation("openbmc_rfr_ReadOnly")); 1012 // Base Redfish Privileges 1013 EXPECT_NO_THROW( 1014 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_Login")); 1015 EXPECT_NO_THROW(checkAndThrowForDisallowedGroupCreation( 1016 "openbmc_rfp_ConfigureManager")); 1017 EXPECT_NO_THROW( 1018 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_ConfigureUsers")); 1019 EXPECT_NO_THROW( 1020 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_ConfigureSelf")); 1021 EXPECT_NO_THROW(checkAndThrowForDisallowedGroupCreation( 1022 "openbmc_rfp_ConfigureComponents")); 1023 // OEM Redfish Roles 1024 EXPECT_NO_THROW( 1025 checkAndThrowForDisallowedGroupCreation("openbmc_orfr_PowerService")); 1026 // OEM Redfish Privileges 1027 EXPECT_NO_THROW( 1028 checkAndThrowForDisallowedGroupCreation("openbmc_orfp_PowerService")); 1029 } 1030 1031 TEST_F(UserMgrInTest, 1032 CheckAndThrowForDisallowedGroupCreationThrowsIfGroupNameTooLong) 1033 { 1034 std::string groupName(maxSystemGroupNameLength + 1, 'A'); 1035 EXPECT_THROW( 1036 checkAndThrowForDisallowedGroupCreation(groupName), 1037 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1038 } 1039 1040 TEST_F( 1041 UserMgrInTest, 1042 CheckAndThrowForDisallowedGroupCreationThrowsIfGroupNameHasDisallowedCharacters) 1043 { 1044 EXPECT_THROW( 1045 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_?owerService"), 1046 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1047 EXPECT_THROW( 1048 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_-owerService"), 1049 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1050 } 1051 1052 TEST_F( 1053 UserMgrInTest, 1054 CheckAndThrowForDisallowedGroupCreationThrowsIfGroupNameHasDisallowedPrefix) 1055 { 1056 EXPECT_THROW( 1057 checkAndThrowForDisallowedGroupCreation("google_rfp_"), 1058 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1059 EXPECT_THROW( 1060 checkAndThrowForDisallowedGroupCreation("com_rfp_"), 1061 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1062 } 1063 1064 TEST_F(UserMgrInTest, CheckAndThrowForMaxGroupCountOnSuccess) 1065 { 1066 constexpr size_t predefGroupCount = 4; 1067 1068 EXPECT_THAT(allGroups().size(), predefGroupCount); 1069 for (size_t i = 0; i < maxSystemGroupCount - predefGroupCount; ++i) 1070 { 1071 std::string groupName = "openbmc_rfr_role"; 1072 groupName += std::to_string(i); 1073 EXPECT_NO_THROW(createGroup(groupName)); 1074 } 1075 EXPECT_THROW( 1076 createGroup("openbmc_rfr_AnotherRole"), 1077 sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource); 1078 for (size_t i = 0; i < maxSystemGroupCount - predefGroupCount; ++i) 1079 { 1080 std::string groupName = "openbmc_rfr_role"; 1081 groupName += std::to_string(i); 1082 EXPECT_NO_THROW(deleteGroup(groupName)); 1083 } 1084 } 1085 1086 TEST_F(UserMgrInTest, CheckAndThrowForGroupExist) 1087 { 1088 std::string groupName = "openbmc_rfr_role"; 1089 EXPECT_NO_THROW(createGroup(groupName)); 1090 EXPECT_THROW( 1091 createGroup(groupName), 1092 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1093 EXPECT_NO_THROW(deleteGroup(groupName)); 1094 } 1095 1096 TEST_F(UserMgrInTest, ByDefaultAllGroupsArePredefinedGroups) 1097 { 1098 EXPECT_THAT(allGroups(), testing::UnorderedElementsAre( 1099 "redfish", "ipmi", "ssh", "hostconsole")); 1100 } 1101 1102 TEST_F(UserMgrInTest, AddGroupThrowsIfPreDefinedGroupAdd) 1103 { 1104 EXPECT_THROW( 1105 createGroup("ipmi"), 1106 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1107 EXPECT_THROW( 1108 createGroup("redfish"), 1109 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1110 EXPECT_THROW( 1111 createGroup("ssh"), 1112 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1113 EXPECT_THROW( 1114 createGroup("hostconsole"), 1115 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1116 } 1117 1118 TEST_F(UserMgrInTest, DeleteGroupThrowsIfGroupIsNotAllowedToChange) 1119 { 1120 EXPECT_THROW( 1121 deleteGroup("ipmi"), 1122 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1123 EXPECT_THROW( 1124 deleteGroup("redfish"), 1125 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1126 EXPECT_THROW( 1127 deleteGroup("ssh"), 1128 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1129 EXPECT_THROW( 1130 deleteGroup("hostconsole"), 1131 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1132 } 1133 1134 TEST_F(UserMgrInTest, 1135 CreateGroupThrowsInternalFailureWhenExecuteGroupCreateFails) 1136 { 1137 EXPECT_CALL(*this, executeGroupCreation) 1138 .WillOnce(testing::Throw( 1139 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 1140 EXPECT_THROW( 1141 createGroup("openbmc_rfr_role1"), 1142 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 1143 } 1144 1145 TEST_F(UserMgrInTest, 1146 DeleteGroupThrowsInternalFailureWhenExecuteGroupDeleteFails) 1147 { 1148 std::string groupName = "openbmc_rfr_role1"; 1149 EXPECT_NO_THROW(UserMgr::createGroup(groupName)); 1150 EXPECT_CALL(*this, executeGroupDeletion(testing::StrEq(groupName))) 1151 .WillOnce(testing::Throw( 1152 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())) 1153 .WillOnce(testing::DoDefault()); 1154 1155 EXPECT_THROW( 1156 deleteGroup(groupName), 1157 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 1158 EXPECT_NO_THROW(UserMgr::deleteGroup(groupName)); 1159 } 1160 1161 TEST_F(UserMgrInTest, CheckAndThrowForGroupNotExist) 1162 { 1163 EXPECT_THROW(deleteGroup("whatever"), 1164 sdbusplus::xyz::openbmc_project::User::Common::Error:: 1165 GroupNameDoesNotExist); 1166 } 1167 1168 TEST(ReadAllGroupsOnSystemTest, OnlyReturnsPredefinedGroups) 1169 { 1170 EXPECT_THAT( 1171 UserMgr::readAllGroupsOnSystem(), 1172 testing::UnorderedElementsAre("redfish", "ipmi", "ssh", "hostconsole")); 1173 } 1174 1175 } // namespace user 1176 } // namespace phosphor 1177