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