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( 240 std::ofstream::failbit | std::ofstream::badbit | 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) 278 .WillByDefault(testing::Return(true)); 279 testing::Return(); 280 }); 281 282 ON_CALL(*this, executeUserAdd(testing::_, testing::_, testing::_, 283 testing::Eq(false))) 284 .WillByDefault([this]() { 285 ON_CALL(*this, isUserEnabled) 286 .WillByDefault(testing::Return(false)); 287 testing::Return(); 288 }); 289 290 ON_CALL(*this, executeUserDelete).WillByDefault(testing::Return()); 291 292 ON_CALL(*this, executeUserClearFailRecords) 293 .WillByDefault(testing::Return()); 294 295 ON_CALL(*this, getIpmiUsersCount).WillByDefault(testing::Return(0)); 296 297 ON_CALL(*this, executeUserRename).WillByDefault(testing::Return()); 298 299 ON_CALL(*this, executeUserModify(testing::_, testing::_, testing::_)) 300 .WillByDefault(testing::Return()); 301 302 ON_CALL(*this, 303 executeUserModifyUserEnable(testing::_, testing::Eq(true))) 304 .WillByDefault([this]() { 305 ON_CALL(*this, isUserEnabled) 306 .WillByDefault(testing::Return(true)); 307 testing::Return(); 308 }); 309 310 ON_CALL(*this, 311 executeUserModifyUserEnable(testing::_, testing::Eq(false))) 312 .WillByDefault([this]() { 313 ON_CALL(*this, isUserEnabled) 314 .WillByDefault(testing::Return(false)); 315 testing::Return(); 316 }); 317 318 ON_CALL(*this, executeGroupCreation(testing::_)) 319 .WillByDefault(testing::Return()); 320 321 ON_CALL(*this, executeGroupDeletion(testing::_)) 322 .WillByDefault(testing::Return()); 323 324 ON_CALL(*this, executeGroupCreation).WillByDefault(testing::Return()); 325 326 ON_CALL(*this, executeGroupDeletion).WillByDefault(testing::Return()); 327 } 328 329 ~UserMgrInTest() override 330 { 331 EXPECT_NO_THROW(removeFile(tempFaillockConfigFile)); 332 EXPECT_NO_THROW(removeFile(tempPWHistoryConfigFile)); 333 EXPECT_NO_THROW(removeFile(tempPWQualityConfigFile)); 334 } 335 336 MOCK_METHOD(void, executeUserAdd, (const char*, const char*, bool, bool), 337 (override)); 338 339 MOCK_METHOD(void, executeUserDelete, (const char*), (override)); 340 341 MOCK_METHOD(void, executeUserClearFailRecords, (const char*), (override)); 342 343 MOCK_METHOD(size_t, getIpmiUsersCount, (), (override)); 344 345 MOCK_METHOD(void, executeUserRename, (const char*, const char*), 346 (override)); 347 348 MOCK_METHOD(void, executeUserModify, (const char*, const char*, bool), 349 (override)); 350 351 MOCK_METHOD(void, executeUserModifyUserEnable, (const char*, bool), 352 (override)); 353 354 MOCK_METHOD(std::vector<std::string>, getFailedAttempt, (const char*), 355 (override)); 356 357 MOCK_METHOD(void, executeGroupCreation, (const char*), (override)); 358 359 MOCK_METHOD(void, executeGroupDeletion, (const char*), (override)); 360 361 MOCK_METHOD(bool, isUserEnabled, (const std::string& userName), (override)); 362 363 protected: 364 static sdbusplus::bus_t busInTest; 365 std::string tempFaillockConfigFile; 366 std::string tempPWHistoryConfigFile; 367 std::string tempPWQualityConfigFile; 368 }; 369 370 sdbusplus::bus_t UserMgrInTest::busInTest = sdbusplus::bus::new_default(); 371 372 TEST_F(UserMgrInTest, GetPamModuleConfValueOnSuccess) 373 { 374 std::string minlen; 375 EXPECT_EQ(getPamModuleConfValue(tempPWQualityConfigFile, "minlen", minlen), 376 0); 377 EXPECT_EQ(minlen, "8"); 378 std::string deny; 379 EXPECT_EQ(getPamModuleConfValue(tempFaillockConfigFile, "deny", deny), 0); 380 EXPECT_EQ(deny, "2"); 381 std::string remember; 382 EXPECT_EQ( 383 getPamModuleConfValue(tempPWHistoryConfigFile, "remember", remember), 384 0); 385 EXPECT_EQ(remember, "0"); 386 } 387 388 TEST_F(UserMgrInTest, SetPamModuleConfValueOnSuccess) 389 { 390 EXPECT_EQ(setPamModuleConfValue(tempPWQualityConfigFile, "minlen", "16"), 391 0); 392 std::string minlen; 393 EXPECT_EQ(getPamModuleConfValue(tempPWQualityConfigFile, "minlen", minlen), 394 0); 395 EXPECT_EQ(minlen, "16"); 396 397 EXPECT_EQ(setPamModuleConfValue(tempFaillockConfigFile, "deny", "3"), 0); 398 std::string deny; 399 EXPECT_EQ(getPamModuleConfValue(tempFaillockConfigFile, "deny", deny), 0); 400 EXPECT_EQ(deny, "3"); 401 402 EXPECT_EQ(setPamModuleConfValue(tempPWHistoryConfigFile, "remember", "1"), 403 0); 404 std::string remember; 405 EXPECT_EQ( 406 getPamModuleConfValue(tempPWHistoryConfigFile, "remember", remember), 407 0); 408 EXPECT_EQ(remember, "1"); 409 } 410 411 TEST_F(UserMgrInTest, SetPamModuleConfValueTempFileOnSuccess) 412 { 413 EXPECT_EQ(setPamModuleConfValue(tempPWQualityConfigFile, "minlen", "16"), 414 0); 415 416 std::string tmpFile = tempPWQualityConfigFile + "_tmp"; 417 EXPECT_FALSE(std::filesystem::exists(tmpFile)); 418 419 EXPECT_EQ(setPamModuleConfValue(tempFaillockConfigFile, "deny", "3"), 0); 420 421 tmpFile = tempFaillockConfigFile + "_tmp"; 422 EXPECT_FALSE(std::filesystem::exists(tmpFile)); 423 424 EXPECT_EQ(setPamModuleConfValue(tempPWHistoryConfigFile, "remember", "1"), 425 0); 426 427 tmpFile = tempPWHistoryConfigFile + "_tmp"; 428 EXPECT_FALSE(std::filesystem::exists(tmpFile)); 429 } 430 431 TEST_F(UserMgrInTest, GetPamModuleConfValueOnFailure) 432 { 433 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWQualityConfigFile)); 434 std::string minlen; 435 EXPECT_EQ(getPamModuleConfValue(tempPWQualityConfigFile, "minlen", minlen), 436 -1); 437 438 EXPECT_NO_THROW(removeFile(tempPWQualityConfigFile)); 439 EXPECT_EQ(getPamModuleConfValue(tempPWQualityConfigFile, "minlen", minlen), 440 -1); 441 442 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 443 std::string deny; 444 EXPECT_EQ(getPamModuleConfValue(tempFaillockConfigFile, "deny", deny), -1); 445 446 EXPECT_NO_THROW(removeFile(tempFaillockConfigFile)); 447 EXPECT_EQ(getPamModuleConfValue(tempFaillockConfigFile, "deny", deny), -1); 448 449 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWHistoryConfigFile)); 450 std::string remember; 451 EXPECT_EQ( 452 getPamModuleConfValue(tempPWHistoryConfigFile, "remember", remember), 453 -1); 454 455 EXPECT_NO_THROW(removeFile(tempPWHistoryConfigFile)); 456 EXPECT_EQ( 457 getPamModuleConfValue(tempPWHistoryConfigFile, "remember", remember), 458 -1); 459 } 460 461 TEST_F(UserMgrInTest, SetPamModuleConfValueOnFailure) 462 { 463 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWQualityConfigFile)); 464 EXPECT_EQ(setPamModuleConfValue(tempPWQualityConfigFile, "minlen", "16"), 465 -1); 466 467 EXPECT_NO_THROW(removeFile(tempPWQualityConfigFile)); 468 EXPECT_EQ(setPamModuleConfValue(tempPWQualityConfigFile, "minlen", "16"), 469 -1); 470 471 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 472 EXPECT_EQ(setPamModuleConfValue(tempFaillockConfigFile, "deny", "3"), -1); 473 474 EXPECT_NO_THROW(removeFile(tempFaillockConfigFile)); 475 EXPECT_EQ(setPamModuleConfValue(tempFaillockConfigFile, "deny", "3"), -1); 476 477 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWHistoryConfigFile)); 478 EXPECT_EQ(setPamModuleConfValue(tempPWHistoryConfigFile, "remember", "1"), 479 -1); 480 481 EXPECT_NO_THROW(removeFile(tempPWHistoryConfigFile)); 482 EXPECT_EQ(setPamModuleConfValue(tempPWHistoryConfigFile, "remember", "1"), 483 -1); 484 } 485 486 TEST_F(UserMgrInTest, SetPamModuleConfValueTempFileOnFailure) 487 { 488 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWQualityConfigFile)); 489 EXPECT_EQ(setPamModuleConfValue(tempPWQualityConfigFile, "minlen", "16"), 490 -1); 491 492 std::string tmpFile = tempPWQualityConfigFile + "_tmp"; 493 EXPECT_FALSE(std::filesystem::exists(tmpFile)); 494 495 EXPECT_NO_THROW(removeFile(tempPWQualityConfigFile)); 496 EXPECT_EQ(setPamModuleConfValue(tempPWQualityConfigFile, "minlen", "16"), 497 -1); 498 499 EXPECT_FALSE(std::filesystem::exists(tmpFile)); 500 501 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 502 EXPECT_EQ(setPamModuleConfValue(tempFaillockConfigFile, "deny", "3"), -1); 503 504 tmpFile = tempFaillockConfigFile + "_tmp"; 505 EXPECT_FALSE(std::filesystem::exists(tmpFile)); 506 507 EXPECT_NO_THROW(removeFile(tempFaillockConfigFile)); 508 EXPECT_EQ(setPamModuleConfValue(tempFaillockConfigFile, "deny", "3"), -1); 509 510 EXPECT_FALSE(std::filesystem::exists(tmpFile)); 511 512 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWHistoryConfigFile)); 513 EXPECT_EQ(setPamModuleConfValue(tempPWHistoryConfigFile, "remember", "1"), 514 -1); 515 516 tmpFile = tempPWHistoryConfigFile + "_tmp"; 517 EXPECT_FALSE(std::filesystem::exists(tmpFile)); 518 519 EXPECT_NO_THROW(removeFile(tempPWHistoryConfigFile)); 520 EXPECT_EQ(setPamModuleConfValue(tempPWHistoryConfigFile, "remember", "1"), 521 -1); 522 523 EXPECT_FALSE(std::filesystem::exists(tmpFile)); 524 } 525 526 TEST_F(UserMgrInTest, IsUserExistEmptyInputThrowsError) 527 { 528 EXPECT_THROW( 529 isUserExist(""), 530 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 531 } 532 533 TEST_F(UserMgrInTest, ThrowForUserDoesNotExistThrowsError) 534 { 535 EXPECT_THROW(throwForUserDoesNotExist("whatever"), 536 sdbusplus::xyz::openbmc_project::User::Common::Error:: 537 UserNameDoesNotExist); 538 } 539 540 TEST_F(UserMgrInTest, ThrowForUserExistsThrowsError) 541 { 542 EXPECT_THROW( 543 throwForUserExists("root"), 544 sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameExists); 545 } 546 547 TEST_F( 548 UserMgrInTest, 549 ThrowForUserNameConstraintsExceedIpmiMaxUserNameLenThrowsUserNameGroupFail) 550 { 551 std::string strWith17Chars(17, 'A'); 552 EXPECT_THROW(throwForUserNameConstraints(strWith17Chars, {"ipmi"}), 553 sdbusplus::xyz::openbmc_project::User::Common::Error:: 554 UserNameGroupFail); 555 } 556 557 TEST_F( 558 UserMgrInTest, 559 ThrowForUserNameConstraintsExceedSystemMaxUserNameLenThrowsInvalidArgument) 560 { 561 std::string strWith31Chars(31, 'A'); 562 EXPECT_THROW( 563 throwForUserNameConstraints(strWith31Chars, {}), 564 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 565 } 566 567 TEST_F(UserMgrInTest, 568 ThrowForUserNameConstraintsRegexMismatchThrowsInvalidArgument) 569 { 570 std::string startWithNumber = "0ABC"; 571 std::string startWithDisallowedCharacter = "[test"; 572 EXPECT_THROW( 573 throwForUserNameConstraints(startWithNumber, {"ipmi"}), 574 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 575 EXPECT_THROW( 576 throwForUserNameConstraints(startWithDisallowedCharacter, {"ipmi"}), 577 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 578 } 579 580 TEST_F(UserMgrInTest, UserAddNotRootFailedWithInternalFailure) 581 { 582 EXPECT_THROW( 583 UserMgr::executeUserAdd("user0", "ipmi,ssh", true, true), 584 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 585 } 586 587 TEST_F(UserMgrInTest, UserDeleteNotRootFailedWithInternalFailure) 588 { 589 EXPECT_THROW( 590 UserMgr::executeUserDelete("user0"), 591 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 592 } 593 594 TEST_F(UserMgrInTest, 595 ThrowForMaxGrpUserCountThrowsNoResourceWhenIpmiUserExceedLimit) 596 { 597 EXPECT_CALL(*this, getIpmiUsersCount()).WillOnce(Return(ipmiMaxUsers)); 598 EXPECT_THROW( 599 throwForMaxGrpUserCount({"ipmi"}), 600 sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource); 601 } 602 603 TEST_F(UserMgrInTest, CreateUserThrowsInternalFailureWhenExecuteUserAddFails) 604 { 605 EXPECT_CALL(*this, executeUserAdd) 606 .WillOnce(testing::Throw( 607 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 608 EXPECT_THROW( 609 createUser("whatever", {"redfish"}, "", true), 610 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 611 } 612 613 TEST_F(UserMgrInTest, DeleteUserThrowsInternalFailureWhenExecuteUserDeleteFails) 614 { 615 std::string username = "user"; 616 EXPECT_NO_THROW( 617 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 618 EXPECT_CALL(*this, executeUserDelete(testing::StrEq(username))) 619 .WillOnce(testing::Throw( 620 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())) 621 .WillOnce(testing::DoDefault()); 622 623 EXPECT_THROW( 624 deleteUser(username), 625 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 626 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 627 } 628 629 TEST_F(UserMgrInTest, 630 DeleteUserThrowsInternalFailureWhenExecuteUserClearFailRecords) 631 { 632 const char* username = "user"; 633 EXPECT_NO_THROW( 634 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 635 EXPECT_CALL(*this, executeUserClearFailRecords(testing::StrEq(username))) 636 .WillOnce(testing::Throw( 637 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())) 638 .WillOnce(testing::DoDefault()); 639 640 EXPECT_THROW( 641 deleteUser(username), 642 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 643 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 644 } 645 646 TEST_F(UserMgrInTest, ThrowForInvalidPrivilegeThrowsWhenPrivilegeIsInvalid) 647 { 648 EXPECT_THROW( 649 throwForInvalidPrivilege("whatever"), 650 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 651 } 652 653 TEST_F(UserMgrInTest, ThrowForInvalidPrivilegeNoThrowWhenPrivilegeIsValid) 654 { 655 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-admin")); 656 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-operator")); 657 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-user")); 658 } 659 660 TEST_F(UserMgrInTest, ThrowForInvalidGroupsThrowsWhenGroupIsInvalid) 661 { 662 EXPECT_THROW( 663 throwForInvalidGroups({"whatever"}), 664 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 665 EXPECT_THROW( 666 throwForInvalidGroups({"web"}), 667 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 668 } 669 670 TEST_F(UserMgrInTest, ThrowForInvalidGroupsNoThrowWhenGroupIsValid) 671 { 672 EXPECT_NO_THROW(throwForInvalidGroups({"ipmi"})); 673 EXPECT_NO_THROW(throwForInvalidGroups({"ssh"})); 674 EXPECT_NO_THROW(throwForInvalidGroups({"redfish"})); 675 EXPECT_NO_THROW(throwForInvalidGroups({"hostconsole"})); 676 } 677 678 TEST_F(UserMgrInTest, RenameUserOnSuccess) 679 { 680 std::string username = "user001"; 681 EXPECT_NO_THROW( 682 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 683 std::string newUsername = "user002"; 684 685 EXPECT_NO_THROW(UserMgr::renameUser(username, newUsername)); 686 687 // old username doesn't exist 688 EXPECT_THROW(getUserInfo(username), 689 sdbusplus::xyz::openbmc_project::User::Common::Error:: 690 UserNameDoesNotExist); 691 692 UserInfoMap userInfo = getUserInfo(newUsername); 693 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-user"); 694 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]), 695 testing::UnorderedElementsAre("redfish", "ssh")); 696 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 697 698 EXPECT_NO_THROW(UserMgr::deleteUser(newUsername)); 699 } 700 701 TEST_F(UserMgrInTest, RenameUserThrowsInternalFailureIfExecuteUserModifyFails) 702 { 703 std::string username = "user001"; 704 EXPECT_NO_THROW( 705 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 706 std::string newUsername = "user002"; 707 708 EXPECT_CALL(*this, executeUserRename(testing::StrEq(username), 709 testing::StrEq(newUsername))) 710 .WillOnce(testing::Throw( 711 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 712 EXPECT_THROW( 713 UserMgr::renameUser(username, newUsername), 714 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 715 716 // The original user is unchanged 717 UserInfoMap userInfo = getUserInfo(username); 718 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-user"); 719 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]), 720 testing::UnorderedElementsAre("redfish", "ssh")); 721 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 722 723 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 724 } 725 726 TEST_F(UserMgrInTest, DefaultUserModifyFailedWithInternalFailure) 727 { 728 EXPECT_THROW( 729 UserMgr::executeUserRename("user0", "user1"), 730 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 731 EXPECT_THROW( 732 UserMgr::executeUserModify("user0", "ssh", true), 733 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 734 } 735 736 TEST_F(UserMgrInTest, UpdateGroupsAndPrivOnSuccess) 737 { 738 std::string username = "user001"; 739 EXPECT_NO_THROW( 740 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 741 EXPECT_NO_THROW( 742 updateGroupsAndPriv(username, {"ipmi", "ssh"}, "priv-admin")); 743 UserInfoMap userInfo = getUserInfo(username); 744 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-admin"); 745 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]), 746 testing::UnorderedElementsAre("ipmi", "ssh")); 747 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 748 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 749 } 750 751 TEST_F(UserMgrInTest, 752 UpdateGroupsAndPrivThrowsInternalFailureIfExecuteUserModifyFail) 753 { 754 std::string username = "user001"; 755 EXPECT_NO_THROW( 756 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 757 EXPECT_CALL(*this, executeUserModify(testing::StrEq(username), testing::_, 758 testing::_)) 759 .WillOnce(testing::Throw( 760 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 761 EXPECT_THROW( 762 updateGroupsAndPriv(username, {"ipmi", "ssh"}, "priv-admin"), 763 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 764 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 765 } 766 767 TEST_F(UserMgrInTest, MinPasswordLengthReturnsIfValueIsTheSame) 768 { 769 initializeAccountPolicy(); 770 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 771 UserMgr::minPasswordLength(8); 772 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 773 } 774 775 TEST_F(UserMgrInTest, 776 MinPasswordLengthRejectsTooShortPasswordWithInvalidArgument) 777 { 778 initializeAccountPolicy(); 779 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 780 EXPECT_THROW( 781 UserMgr::minPasswordLength(minPasswdLength - 1), 782 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 783 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 784 } 785 786 TEST_F(UserMgrInTest, MinPasswordLengthOnSuccess) 787 { 788 initializeAccountPolicy(); 789 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 790 UserMgr::minPasswordLength(16); 791 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 16); 792 } 793 794 TEST_F(UserMgrInTest, MinPasswordLengthOnFailure) 795 { 796 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWQualityConfigFile)); 797 initializeAccountPolicy(); 798 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 799 EXPECT_THROW( 800 UserMgr::minPasswordLength(16), 801 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 802 EXPECT_EQ(AccountPolicyIface::minPasswordLength(), 8); 803 } 804 805 TEST_F(UserMgrInTest, RememberOldPasswordTimesReturnsIfValueIsTheSame) 806 { 807 initializeAccountPolicy(); 808 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 809 UserMgr::rememberOldPasswordTimes(8); 810 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 8); 811 UserMgr::rememberOldPasswordTimes(8); 812 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 8); 813 } 814 815 TEST_F(UserMgrInTest, RememberOldPasswordTimesOnSuccess) 816 { 817 initializeAccountPolicy(); 818 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 819 UserMgr::rememberOldPasswordTimes(16); 820 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 16); 821 } 822 823 TEST_F(UserMgrInTest, RememberOldPasswordTimesOnFailure) 824 { 825 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPWHistoryConfigFile)); 826 initializeAccountPolicy(); 827 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 828 EXPECT_THROW( 829 UserMgr::rememberOldPasswordTimes(16), 830 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 831 EXPECT_EQ(AccountPolicyIface::rememberOldPasswordTimes(), 0); 832 } 833 834 TEST_F(UserMgrInTest, MaxLoginAttemptBeforeLockoutReturnsIfValueIsTheSame) 835 { 836 initializeAccountPolicy(); 837 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 838 UserMgr::maxLoginAttemptBeforeLockout(2); 839 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 840 } 841 842 TEST_F(UserMgrInTest, MaxLoginAttemptBeforeLockoutOnSuccess) 843 { 844 initializeAccountPolicy(); 845 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 846 UserMgr::maxLoginAttemptBeforeLockout(16); 847 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 16); 848 } 849 850 TEST_F(UserMgrInTest, MaxLoginAttemptBeforeLockoutOnFailure) 851 { 852 initializeAccountPolicy(); 853 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 854 EXPECT_THROW( 855 UserMgr::maxLoginAttemptBeforeLockout(16), 856 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 857 EXPECT_EQ(AccountPolicyIface::maxLoginAttemptBeforeLockout(), 2); 858 } 859 860 TEST_F(UserMgrInTest, AccountUnlockTimeoutReturnsIfValueIsTheSame) 861 { 862 initializeAccountPolicy(); 863 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 864 UserMgr::accountUnlockTimeout(3); 865 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 866 } 867 868 TEST_F(UserMgrInTest, AccountUnlockTimeoutOnSuccess) 869 { 870 initializeAccountPolicy(); 871 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 872 UserMgr::accountUnlockTimeout(16); 873 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 16); 874 } 875 876 TEST_F(UserMgrInTest, AccountUnlockTimeoutOnFailure) 877 { 878 initializeAccountPolicy(); 879 EXPECT_NO_THROW(dumpStringToFile("whatever", tempFaillockConfigFile)); 880 EXPECT_THROW( 881 UserMgr::accountUnlockTimeout(16), 882 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 883 EXPECT_EQ(AccountPolicyIface::accountUnlockTimeout(), 3); 884 } 885 886 TEST_F(UserMgrInTest, UserEnableOnSuccess) 887 { 888 std::string username = "user001"; 889 EXPECT_NO_THROW( 890 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 891 UserInfoMap userInfo = getUserInfo(username); 892 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 893 894 EXPECT_NO_THROW(userEnable(username, false)); 895 896 userInfo = getUserInfo(username); 897 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), false); 898 899 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 900 } 901 902 TEST_F(UserMgrInTest, CreateDeleteUserSuccessForHostConsole) 903 { 904 std::string username = "user001"; 905 EXPECT_NO_THROW( 906 UserMgr::createUser(username, {"hostconsole"}, "priv-user", true)); 907 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 908 EXPECT_NO_THROW( 909 UserMgr::createUser(username, {"hostconsole"}, "priv-admin", true)); 910 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 911 EXPECT_NO_THROW( 912 UserMgr::createUser(username, {"hostconsole"}, "priv-operator", true)); 913 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 914 } 915 916 TEST_F(UserMgrInTest, UserEnableThrowsInternalFailureIfExecuteUserModifyFail) 917 { 918 std::string username = "user001"; 919 EXPECT_NO_THROW( 920 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true)); 921 UserInfoMap userInfo = getUserInfo(username); 922 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 923 924 EXPECT_CALL(*this, executeUserModifyUserEnable(testing::StrEq(username), 925 testing::Eq(false))) 926 .WillOnce(testing::Throw( 927 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 928 EXPECT_THROW( 929 userEnable(username, false), 930 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 931 932 userInfo = getUserInfo(username); 933 // Stay unchanged 934 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true); 935 936 EXPECT_NO_THROW(UserMgr::deleteUser(username)); 937 } 938 939 TEST_F( 940 UserMgrInTest, 941 UserLockedForFailedAttemptReturnsFalseIfMaxLoginAttemptBeforeLockoutIsZero) 942 { 943 EXPECT_FALSE(userLockedForFailedAttempt("whatever")); 944 } 945 946 TEST_F(UserMgrInTest, UserLockedForFailedAttemptZeroFailuresReturnsFalse) 947 { 948 std::string username = "user001"; 949 initializeAccountPolicy(); 950 // Example output from BMC 951 // root:~# faillock --user root 952 // root: 953 // When Type Source Valid 954 std::vector<std::string> output = {"whatever", 955 "When Type Source Valid"}; 956 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 957 .WillOnce(testing::Return(output)); 958 959 EXPECT_FALSE(userLockedForFailedAttempt(username)); 960 } 961 962 TEST_F(UserMgrInTest, UserLockedForFailedAttemptFailIfGetFailedAttemptFail) 963 { 964 std::string username = "user001"; 965 initializeAccountPolicy(); 966 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 967 .WillOnce(testing::Throw( 968 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 969 970 EXPECT_THROW( 971 userLockedForFailedAttempt(username), 972 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 973 } 974 975 TEST_F(UserMgrInTest, 976 UserLockedForFailedAttemptThrowsInternalFailureIfWrongDateFormat) 977 { 978 std::string username = "user001"; 979 initializeAccountPolicy(); 980 981 // Choose a date in the past. 982 std::vector<std::string> output = {"whatever", 983 "10/24/2002 00:00:00 type source V"}; 984 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 985 .WillOnce(testing::Return(output)); 986 987 EXPECT_THROW( 988 userLockedForFailedAttempt(username), 989 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 990 } 991 992 TEST_F(UserMgrInTest, 993 UserLockedForFailedAttemptReturnsFalseIfLastFailTimeHasTimedOut) 994 { 995 std::string username = "user001"; 996 initializeAccountPolicy(); 997 998 // Choose a date in the past. 999 std::vector<std::string> output = {"whatever", 1000 "2002-10-24 00:00:00 type source V"}; 1001 EXPECT_CALL(*this, getFailedAttempt(testing::StrEq(username.c_str()))) 1002 .WillOnce(testing::Return(output)); 1003 1004 EXPECT_EQ(userLockedForFailedAttempt(username), false); 1005 } 1006 1007 TEST_F(UserMgrInTest, CheckAndThrowForDisallowedGroupCreationOnSuccess) 1008 { 1009 // Base Redfish Roles 1010 EXPECT_NO_THROW( 1011 checkAndThrowForDisallowedGroupCreation("openbmc_rfr_Administrator")); 1012 EXPECT_NO_THROW( 1013 checkAndThrowForDisallowedGroupCreation("openbmc_rfr_Operator")); 1014 EXPECT_NO_THROW( 1015 checkAndThrowForDisallowedGroupCreation("openbmc_rfr_ReadOnly")); 1016 // Base Redfish Privileges 1017 EXPECT_NO_THROW( 1018 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_Login")); 1019 EXPECT_NO_THROW(checkAndThrowForDisallowedGroupCreation( 1020 "openbmc_rfp_ConfigureManager")); 1021 EXPECT_NO_THROW( 1022 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_ConfigureUsers")); 1023 EXPECT_NO_THROW( 1024 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_ConfigureSelf")); 1025 EXPECT_NO_THROW(checkAndThrowForDisallowedGroupCreation( 1026 "openbmc_rfp_ConfigureComponents")); 1027 // OEM Redfish Roles 1028 EXPECT_NO_THROW( 1029 checkAndThrowForDisallowedGroupCreation("openbmc_orfr_PowerService")); 1030 // OEM Redfish Privileges 1031 EXPECT_NO_THROW( 1032 checkAndThrowForDisallowedGroupCreation("openbmc_orfp_PowerService")); 1033 } 1034 1035 TEST_F(UserMgrInTest, 1036 CheckAndThrowForDisallowedGroupCreationThrowsIfGroupNameTooLong) 1037 { 1038 std::string groupName(maxSystemGroupNameLength + 1, 'A'); 1039 EXPECT_THROW( 1040 checkAndThrowForDisallowedGroupCreation(groupName), 1041 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1042 } 1043 1044 TEST_F( 1045 UserMgrInTest, 1046 CheckAndThrowForDisallowedGroupCreationThrowsIfGroupNameHasDisallowedCharacters) 1047 { 1048 EXPECT_THROW( 1049 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_?owerService"), 1050 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1051 EXPECT_THROW( 1052 checkAndThrowForDisallowedGroupCreation("openbmc_rfp_-owerService"), 1053 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1054 } 1055 1056 TEST_F( 1057 UserMgrInTest, 1058 CheckAndThrowForDisallowedGroupCreationThrowsIfGroupNameHasDisallowedPrefix) 1059 { 1060 EXPECT_THROW( 1061 checkAndThrowForDisallowedGroupCreation("google_rfp_"), 1062 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1063 EXPECT_THROW( 1064 checkAndThrowForDisallowedGroupCreation("com_rfp_"), 1065 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1066 } 1067 1068 TEST_F(UserMgrInTest, CheckAndThrowForMaxGroupCountOnSuccess) 1069 { 1070 constexpr size_t predefGroupCount = 4; 1071 1072 EXPECT_THAT(allGroups().size(), predefGroupCount); 1073 for (size_t i = 0; i < maxSystemGroupCount - predefGroupCount; ++i) 1074 { 1075 std::string groupName = "openbmc_rfr_role"; 1076 groupName += std::to_string(i); 1077 EXPECT_NO_THROW(createGroup(groupName)); 1078 } 1079 EXPECT_THROW( 1080 createGroup("openbmc_rfr_AnotherRole"), 1081 sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource); 1082 for (size_t i = 0; i < maxSystemGroupCount - predefGroupCount; ++i) 1083 { 1084 std::string groupName = "openbmc_rfr_role"; 1085 groupName += std::to_string(i); 1086 EXPECT_NO_THROW(deleteGroup(groupName)); 1087 } 1088 } 1089 1090 TEST_F(UserMgrInTest, CheckAndThrowForGroupExist) 1091 { 1092 std::string groupName = "openbmc_rfr_role"; 1093 EXPECT_NO_THROW(createGroup(groupName)); 1094 EXPECT_THROW( 1095 createGroup(groupName), 1096 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1097 EXPECT_NO_THROW(deleteGroup(groupName)); 1098 } 1099 1100 TEST_F(UserMgrInTest, ByDefaultAllGroupsArePredefinedGroups) 1101 { 1102 EXPECT_THAT(allGroups(), testing::UnorderedElementsAre( 1103 "redfish", "ipmi", "ssh", "hostconsole")); 1104 } 1105 1106 TEST_F(UserMgrInTest, AddGroupThrowsIfPreDefinedGroupAdd) 1107 { 1108 EXPECT_THROW( 1109 createGroup("ipmi"), 1110 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1111 EXPECT_THROW( 1112 createGroup("redfish"), 1113 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1114 EXPECT_THROW( 1115 createGroup("ssh"), 1116 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1117 EXPECT_THROW( 1118 createGroup("hostconsole"), 1119 sdbusplus::xyz::openbmc_project::User::Common::Error::GroupNameExists); 1120 } 1121 1122 TEST_F(UserMgrInTest, DeleteGroupThrowsIfGroupIsNotAllowedToChange) 1123 { 1124 EXPECT_THROW( 1125 deleteGroup("ipmi"), 1126 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1127 EXPECT_THROW( 1128 deleteGroup("redfish"), 1129 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1130 EXPECT_THROW( 1131 deleteGroup("ssh"), 1132 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1133 EXPECT_THROW( 1134 deleteGroup("hostconsole"), 1135 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument); 1136 } 1137 1138 TEST_F(UserMgrInTest, 1139 CreateGroupThrowsInternalFailureWhenExecuteGroupCreateFails) 1140 { 1141 EXPECT_CALL(*this, executeGroupCreation) 1142 .WillOnce(testing::Throw( 1143 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())); 1144 EXPECT_THROW( 1145 createGroup("openbmc_rfr_role1"), 1146 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 1147 } 1148 1149 TEST_F(UserMgrInTest, 1150 DeleteGroupThrowsInternalFailureWhenExecuteGroupDeleteFails) 1151 { 1152 std::string groupName = "openbmc_rfr_role1"; 1153 EXPECT_NO_THROW(UserMgr::createGroup(groupName)); 1154 EXPECT_CALL(*this, executeGroupDeletion(testing::StrEq(groupName))) 1155 .WillOnce(testing::Throw( 1156 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure())) 1157 .WillOnce(testing::DoDefault()); 1158 1159 EXPECT_THROW( 1160 deleteGroup(groupName), 1161 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure); 1162 EXPECT_NO_THROW(UserMgr::deleteGroup(groupName)); 1163 } 1164 1165 TEST_F(UserMgrInTest, CheckAndThrowForGroupNotExist) 1166 { 1167 EXPECT_THROW(deleteGroup("whatever"), 1168 sdbusplus::xyz::openbmc_project::User::Common::Error:: 1169 GroupNameDoesNotExist); 1170 } 1171 1172 TEST(ReadAllGroupsOnSystemTest, OnlyReturnsPredefinedGroups) 1173 { 1174 EXPECT_THAT( 1175 UserMgr::readAllGroupsOnSystem(), 1176 testing::UnorderedElementsAre("redfish", "ipmi", "ssh", "hostconsole")); 1177 } 1178 1179 } // namespace user 1180 } // namespace phosphor 1181