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