blob: 626418232687778d8de7914e5f7731879a4c0062 [file] [log] [blame]
raviteja-b8cc44052019-02-27 23:29:36 -06001#include "mock_user_mgr.hpp"
Nan Zhoue47c09d2022-10-25 00:06:41 +00002#include "user_mgr.hpp"
Patrick Williams9638afb2021-02-22 17:16:24 -06003
Ravi Teja417c0892020-08-22 08:04:01 -05004#include <sdbusplus/test/sdbus_mock.hpp>
Patrick Williams9638afb2021-02-22 17:16:24 -06005#include <xyz/openbmc_project/Common/error.hpp>
6#include <xyz/openbmc_project/User/Common/error.hpp>
7
8#include <exception>
Nan Zhoue48085d2022-10-25 00:07:04 +00009#include <filesystem>
10#include <fstream>
Patrick Williams9638afb2021-02-22 17:16:24 -060011
12#include <gtest/gtest.h>
raviteja-b8cc44052019-02-27 23:29:36 -060013
14namespace phosphor
15{
16namespace user
17{
18
19using ::testing::Return;
20
21using InternalFailure =
22 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
23
24class TestUserMgr : public testing::Test
25{
26 public:
Nan Zhou78d85042022-08-29 17:50:22 +000027 sdbusplus::SdBusMock sdBusMock;
Patrick Williamsb3ef4e12022-07-22 19:26:55 -050028 sdbusplus::bus_t bus;
raviteja-b8cc44052019-02-27 23:29:36 -060029 MockManager mockManager;
30
31 TestUserMgr() :
Nan Zhou78d85042022-08-29 17:50:22 +000032 bus(sdbusplus::get_mocked_new(&sdBusMock)), mockManager(bus, objpath)
Patrick Williams9638afb2021-02-22 17:16:24 -060033 {}
raviteja-b8cc44052019-02-27 23:29:36 -060034
Patrick Williams9638afb2021-02-22 17:16:24 -060035 void createLocalUser(const std::string& userName,
raviteja-b8cc44052019-02-27 23:29:36 -060036 std::vector<std::string> groupNames,
Patrick Williams9638afb2021-02-22 17:16:24 -060037 const std::string& priv, bool enabled)
raviteja-b8cc44052019-02-27 23:29:36 -060038 {
P Dheeraj Srujan Kumarb01e2fe2021-12-13 09:43:28 +053039 sdbusplus::message::object_path tempObjPath(usersObjPath);
40 tempObjPath /= userName;
41 std::string userObj(tempObjPath);
raviteja-b8cc44052019-02-27 23:29:36 -060042 mockManager.usersList.emplace(
Nan Zhou78d85042022-08-29 17:50:22 +000043 userName, std::make_unique<phosphor::user::Users>(
raviteja-b8cc44052019-02-27 23:29:36 -060044 mockManager.bus, userObj.c_str(), groupNames, priv,
Nan Zhou78d85042022-08-29 17:50:22 +000045 enabled, mockManager));
raviteja-b8cc44052019-02-27 23:29:36 -060046 }
47
48 DbusUserObj createPrivilegeMapperDbusObject(void)
49 {
50 DbusUserObj object;
51 DbusUserObjValue objValue;
Ravi Teja5fe724a2019-05-07 05:14:42 -050052
Nan Zhou78d85042022-08-29 17:50:22 +000053 DbusUserObjPath objPath("/xyz/openbmc_project/user/ldap/openldap");
Ravi Teja5fe724a2019-05-07 05:14:42 -050054 DbusUserPropVariant enabled(true);
55 DbusUserObjProperties property = {std::make_pair("Enabled", enabled)};
56 std::string intf = "xyz.openbmc_project.Object.Enable";
57 objValue.emplace(intf, property);
Nan Zhou78d85042022-08-29 17:50:22 +000058 object.emplace(objPath, objValue);
Ravi Teja5fe724a2019-05-07 05:14:42 -050059
Nan Zhou78d85042022-08-29 17:50:22 +000060 DbusUserObjPath objectPath(
Ravi Teja5fe724a2019-05-07 05:14:42 -050061 "/xyz/openbmc_project/user/ldap/openldap/role_map/1");
62 std::string group = "ldapGroup";
63 std::string priv = "priv-admin";
raviteja-b8cc44052019-02-27 23:29:36 -060064 DbusUserObjProperties properties = {std::make_pair("GroupName", group),
65 std::make_pair("Privilege", priv)};
66 std::string interface = "xyz.openbmc_project.User.PrivilegeMapperEntry";
67
68 objValue.emplace(interface, properties);
Nan Zhou78d85042022-08-29 17:50:22 +000069 object.emplace(objectPath, objValue);
raviteja-b8cc44052019-02-27 23:29:36 -060070
71 return object;
72 }
Ravi Teja5fe724a2019-05-07 05:14:42 -050073
74 DbusUserObj createLdapConfigObjectWithoutPrivilegeMapper(void)
75 {
76 DbusUserObj object;
77 DbusUserObjValue objValue;
78
Nan Zhou78d85042022-08-29 17:50:22 +000079 DbusUserObjPath objPath("/xyz/openbmc_project/user/ldap/openldap");
Ravi Teja5fe724a2019-05-07 05:14:42 -050080 DbusUserPropVariant enabled(true);
81 DbusUserObjProperties property = {std::make_pair("Enabled", enabled)};
82 std::string intf = "xyz.openbmc_project.Object.Enable";
83 objValue.emplace(intf, property);
Nan Zhou78d85042022-08-29 17:50:22 +000084 object.emplace(objPath, objValue);
Ravi Teja5fe724a2019-05-07 05:14:42 -050085 return object;
86 }
raviteja-b8cc44052019-02-27 23:29:36 -060087};
88
89TEST_F(TestUserMgr, ldapEntryDoesNotExist)
90{
91 std::string userName = "user";
92 UserInfoMap userInfo;
93
94 EXPECT_CALL(mockManager, getLdapGroupName(userName))
95 .WillRepeatedly(Return(""));
96 EXPECT_THROW(userInfo = mockManager.getUserInfo(userName), InternalFailure);
97}
98
99TEST_F(TestUserMgr, localUser)
100{
101 UserInfoMap userInfo;
102 std::string userName = "testUser";
103 std::string privilege = "priv-admin";
104 std::vector<std::string> groups{"testGroup"};
105 // Create local user
106 createLocalUser(userName, groups, privilege, true);
107 EXPECT_CALL(mockManager, userLockedForFailedAttempt(userName)).Times(1);
108 userInfo = mockManager.getUserInfo(userName);
109
110 EXPECT_EQ(privilege, std::get<std::string>(userInfo["UserPrivilege"]));
111 EXPECT_EQ(groups,
112 std::get<std::vector<std::string>>(userInfo["UserGroups"]));
113 EXPECT_EQ(true, std::get<bool>(userInfo["UserEnabled"]));
114 EXPECT_EQ(false, std::get<bool>(userInfo["UserLockedForFailedAttempt"]));
Joseph Reynolds3ab6cc22020-03-03 14:09:03 -0600115 EXPECT_EQ(false, std::get<bool>(userInfo["UserPasswordExpired"]));
raviteja-b8cc44052019-02-27 23:29:36 -0600116 EXPECT_EQ(false, std::get<bool>(userInfo["RemoteUser"]));
117}
118
119TEST_F(TestUserMgr, ldapUserWithPrivMapper)
120{
121 UserInfoMap userInfo;
122 std::string userName = "ldapUser";
123 std::string ldapGroup = "ldapGroup";
124
125 EXPECT_CALL(mockManager, getLdapGroupName(userName))
126 .WillRepeatedly(Return(ldapGroup));
127 // Create privilege mapper dbus object
128 DbusUserObj object = createPrivilegeMapperDbusObject();
129 EXPECT_CALL(mockManager, getPrivilegeMapperObject())
130 .WillRepeatedly(Return(object));
131 userInfo = mockManager.getUserInfo(userName);
132 EXPECT_EQ(true, std::get<bool>(userInfo["RemoteUser"]));
133 EXPECT_EQ("priv-admin", std::get<std::string>(userInfo["UserPrivilege"]));
134}
135
136TEST_F(TestUserMgr, ldapUserWithoutPrivMapper)
137{
138 UserInfoMap userInfo;
139 std::string userName = "ldapUser";
140 std::string ldapGroup = "ldapGroup";
raviteja-b8cc44052019-02-27 23:29:36 -0600141
142 EXPECT_CALL(mockManager, getLdapGroupName(userName))
143 .WillRepeatedly(Return(ldapGroup));
Ravi Teja5fe724a2019-05-07 05:14:42 -0500144 // Create LDAP config object without privilege mapper
145 DbusUserObj object = createLdapConfigObjectWithoutPrivilegeMapper();
raviteja-b8cc44052019-02-27 23:29:36 -0600146 EXPECT_CALL(mockManager, getPrivilegeMapperObject())
147 .WillRepeatedly(Return(object));
148 userInfo = mockManager.getUserInfo(userName);
149 EXPECT_EQ(true, std::get<bool>(userInfo["RemoteUser"]));
150 EXPECT_EQ("", std::get<std::string>(userInfo["UserPrivilege"]));
151}
Nan Zhoue47c09d2022-10-25 00:06:41 +0000152
153TEST(GetCSVFromVector, EmptyVectorReturnsEmptyString)
154{
155 EXPECT_EQ(getCSVFromVector({}), "");
156}
157
158TEST(GetCSVFromVector, ElementsAreJoinedByComma)
159{
160 EXPECT_EQ(getCSVFromVector(std::vector<std::string>{"123"}), "123");
161 EXPECT_EQ(getCSVFromVector(std::vector<std::string>{"123", "456"}),
162 "123,456");
163}
164
Nan Zhou332fb9d2022-10-25 00:07:03 +0000165TEST(RemoveStringFromCSV, WithoutDeleteStringReturnsFalse)
166{
167 std::string expected = "whatever,https";
168 std::string str = expected;
169 EXPECT_FALSE(removeStringFromCSV(str, "ssh"));
170 EXPECT_EQ(str, expected);
171
172 std::string empty;
173 EXPECT_FALSE(removeStringFromCSV(empty, "ssh"));
174}
175
176TEST(RemoveStringFromCSV, WithDeleteStringReturnsTrue)
177{
178 std::string expected = "whatever";
179 std::string str = "whatever,https";
180 EXPECT_TRUE(removeStringFromCSV(str, "https"));
181 EXPECT_EQ(str, expected);
182
183 str = "https";
184 EXPECT_TRUE(removeStringFromCSV(str, "https"));
185 EXPECT_EQ(str, "");
186}
187
Nan Zhoue48085d2022-10-25 00:07:04 +0000188namespace
189{
190inline constexpr const char* objectRootInTest = "/xyz/openbmc_project/user";
191
192// Fake config; referenced config on real BMC
193inline constexpr const char* rawConfig = R"(
194#
195# /etc/pam.d/common-password - password-related modules common to all services
196#
197# This file is included from other service-specific PAM config files,
198# and should contain a list of modules that define the services to be
199# used to change user passwords. The default is pam_unix.
200
201# Explanation of pam_unix options:
202#
203# The "sha512" option enables salted SHA512 passwords. Without this option,
204# the default is Unix crypt. Prior releases used the option "md5".
205#
206# The "obscure" option replaces the old `OBSCURE_CHECKS_ENAB' option in
207# login.defs.
208#
209# See the pam_unix manpage for other options.
210
211# here are the per-package modules (the "Primary" block)
212password [success=ok default=die] pam_tally2.so debug enforce_for_root reject_username minlen=8 difok=0 lcredit=0 ocredit=0 dcredit=0 ucredit=0 #some comments
213password [success=ok default=die] pam_cracklib.so debug enforce_for_root reject_username minlen=8 difok=0 lcredit=0 ocredit=0 dcredit=0 ucredit=0 #some comments
214password [success=ok default=die] pam_ipmicheck.so spec_grp_name=ipmi use_authtok
215password [success=ok ignore=ignore default=die] pam_pwhistory.so debug enforce_for_root remember=0 use_authtok
216password [success=ok default=die] pam_unix.so sha512 use_authtok
217password [success=1 default=die] pam_ipmisave.so spec_grp_name=ipmi spec_pass_file=/etc/ipmi_pass key_file=/etc/key_file
218# here's the fallback if no module succeeds
219password requisite pam_deny.so
220# prime the stack with a positive return value if there isn't one already;
221# this avoids us returning an error just because nothing sets a success code
222# since the modules above will each just jump around
223password required pam_permit.so
224# and here are more per-package modules (the "Additional" block)
225)";
226} // namespace
227
228void dumpStringToFile(const std::string& str, const std::string& filePath)
229{
230 std::ofstream outputFileStream;
231
232 outputFileStream.exceptions(std::ofstream::failbit | std::ofstream::badbit |
233 std::ofstream::eofbit);
234
235 outputFileStream.open(filePath, std::ios::out);
236 outputFileStream << str << "\n" << std::flush;
237 outputFileStream.close();
238}
239
240void removeFile(const std::string& filePath)
241{
242 std::filesystem::remove(filePath);
243}
244
245class UserMgrInTest : public testing::Test, public UserMgr
246{
247 public:
248 UserMgrInTest() : UserMgr(busInTest, objectRootInTest)
249 {
250 tempPamConfigFile = "/tmp/test-data-XXXXXX";
251 mktemp(tempPamConfigFile.data());
252 EXPECT_NO_THROW(dumpStringToFile(rawConfig, tempPamConfigFile));
253 // Set config files to test files
254 pamPasswdConfigFile = tempPamConfigFile;
255 pamAuthConfigFile = tempPamConfigFile;
Nan Zhou49c81362022-10-25 00:07:08 +0000256
257 ON_CALL(*this, executeUserAdd).WillByDefault(testing::Return());
258
259 ON_CALL(*this, executeUserDelete).WillByDefault(testing::Return());
260
261 ON_CALL(*this, getIpmiUsersCount).WillByDefault(testing::Return(0));
Nan Zhouf25443e2022-10-25 00:07:11 +0000262
263 ON_CALL(*this, executeUserRename).WillByDefault(testing::Return());
Nan Zhoue48085d2022-10-25 00:07:04 +0000264 }
265
266 ~UserMgrInTest() override
267 {
268 EXPECT_NO_THROW(removeFile(tempPamConfigFile));
269 }
270
Nan Zhou49c81362022-10-25 00:07:08 +0000271 MOCK_METHOD(void, executeUserAdd, (const char*, const char*, bool, bool),
272 (override));
273
274 MOCK_METHOD(void, executeUserDelete, (const char*), (override));
275
276 MOCK_METHOD(size_t, getIpmiUsersCount, (), (override));
277
Nan Zhouf25443e2022-10-25 00:07:11 +0000278 MOCK_METHOD(void, executeUserRename, (const char*, const char*),
279 (override));
280
Nan Zhoue48085d2022-10-25 00:07:04 +0000281 static sdbusplus::bus_t busInTest;
282 std::string tempPamConfigFile;
283};
284
285sdbusplus::bus_t UserMgrInTest::busInTest = sdbusplus::bus::new_default();
286
287TEST_F(UserMgrInTest, GetPamModuleArgValueOnSuccess)
288{
289 std::string minLen;
290 EXPECT_EQ(getPamModuleArgValue("pam_tally2.so", "minlen", minLen), 0);
291 EXPECT_EQ(minLen, "8");
292 EXPECT_EQ(getPamModuleArgValue("pam_cracklib.so", "minlen", minLen), 0);
293 EXPECT_EQ(minLen, "8");
294}
295
296TEST_F(UserMgrInTest, SetPamModuleArgValueOnSuccess)
297{
298 EXPECT_EQ(setPamModuleArgValue("pam_cracklib.so", "minlen", "16"), 0);
299 EXPECT_EQ(setPamModuleArgValue("pam_tally2.so", "minlen", "16"), 0);
300 std::string minLen;
301 EXPECT_EQ(getPamModuleArgValue("pam_tally2.so", "minlen", minLen), 0);
302 EXPECT_EQ(minLen, "16");
303 EXPECT_EQ(getPamModuleArgValue("pam_cracklib.so", "minlen", minLen), 0);
304 EXPECT_EQ(minLen, "16");
305}
306
307TEST_F(UserMgrInTest, GetPamModuleArgValueOnFailure)
308{
309 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPamConfigFile));
310 std::string minLen;
311 EXPECT_EQ(getPamModuleArgValue("pam_tally2.so", "minlen", minLen), -1);
312 EXPECT_EQ(getPamModuleArgValue("pam_cracklib.so", "minlen", minLen), -1);
313
314 EXPECT_NO_THROW(removeFile(tempPamConfigFile));
315 EXPECT_EQ(getPamModuleArgValue("pam_tally2.so", "minlen", minLen), -1);
316 EXPECT_EQ(getPamModuleArgValue("pam_cracklib.so", "minlen", minLen), -1);
317}
318
319TEST_F(UserMgrInTest, SetPamModuleArgValueOnFailure)
320{
321 EXPECT_NO_THROW(dumpStringToFile("whatever", tempPamConfigFile));
322 EXPECT_EQ(setPamModuleArgValue("pam_cracklib.so", "minlen", "16"), -1);
323 EXPECT_EQ(setPamModuleArgValue("pam_tally2.so", "minlen", "16"), -1);
324
325 EXPECT_NO_THROW(removeFile(tempPamConfigFile));
326 EXPECT_EQ(setPamModuleArgValue("pam_cracklib.so", "minlen", "16"), -1);
327 EXPECT_EQ(setPamModuleArgValue("pam_tally2.so", "minlen", "16"), -1);
328}
329
Nan Zhou8a11d992022-10-25 00:07:06 +0000330TEST_F(UserMgrInTest, IsUserExistEmptyInputThrowsError)
331{
332 EXPECT_THROW(
333 isUserExist(""),
334 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument);
335}
336
337TEST_F(UserMgrInTest, ThrowForUserDoesNotExistThrowsError)
338{
339 EXPECT_THROW(throwForUserDoesNotExist("whatever"),
340 sdbusplus::xyz::openbmc_project::User::Common::Error::
341 UserNameDoesNotExist);
342}
343
344TEST_F(UserMgrInTest, ThrowForUserExistsThrowsError)
345{
346 EXPECT_THROW(
347 throwForUserExists("root"),
348 sdbusplus::xyz::openbmc_project::User::Common::Error::UserNameExists);
349}
350
Nan Zhou40e44972022-10-25 00:07:07 +0000351TEST_F(
352 UserMgrInTest,
353 ThrowForUserNameConstraintsExceedIpmiMaxUserNameLenThrowsUserNameGroupFail)
354{
355 std::string strWith17Chars(17, 'A');
356 EXPECT_THROW(throwForUserNameConstraints(strWith17Chars, {"ipmi"}),
357 sdbusplus::xyz::openbmc_project::User::Common::Error::
358 UserNameGroupFail);
359}
360
361TEST_F(
362 UserMgrInTest,
363 ThrowForUserNameConstraintsExceedSystemMaxUserNameLenThrowsInvalidArgument)
364{
365 std::string strWith31Chars(31, 'A');
366 EXPECT_THROW(
367 throwForUserNameConstraints(strWith31Chars, {}),
368 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument);
369}
370
371TEST_F(UserMgrInTest,
372 ThrowForUserNameConstraintsRegexMismatchThrowsInvalidArgument)
373{
374 std::string startWithNumber = "0ABC";
375 EXPECT_THROW(
376 throwForUserNameConstraints(startWithNumber, {"ipmi"}),
377 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument);
378}
379
Nan Zhou49c81362022-10-25 00:07:08 +0000380TEST_F(UserMgrInTest, UserAddNotRootFailedWithInternalFailure)
381{
382 EXPECT_THROW(
383 UserMgr::executeUserAdd("user0", "ipmi,ssh", true, true),
384 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure);
385}
386
387TEST_F(UserMgrInTest, UserDeleteNotRootFailedWithInternalFailure)
388{
389 EXPECT_THROW(
390 UserMgr::executeUserDelete("user0"),
391 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure);
392}
393
394TEST_F(UserMgrInTest,
395 ThrowForMaxGrpUserCountThrowsNoResourceWhenIpmiUserExceedLimit)
396{
397 EXPECT_CALL(*this, getIpmiUsersCount()).WillOnce(Return(ipmiMaxUsers));
398 EXPECT_THROW(
399 throwForMaxGrpUserCount({"ipmi"}),
400 sdbusplus::xyz::openbmc_project::User::Common::Error::NoResource);
401}
402
403TEST_F(UserMgrInTest, CreateUserThrowsInternalFailureWhenExecuteUserAddFails)
404{
405 EXPECT_CALL(*this, executeUserAdd)
406 .WillOnce(testing::Throw(
407 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure()));
408 EXPECT_THROW(
409 createUser("whatever", {"redfish"}, "", true),
410 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure);
411}
412
413TEST_F(UserMgrInTest, DeleteUserThrowsInternalFailureWhenExecuteUserDeleteFails)
414{
415 std::string username = "user";
416 EXPECT_NO_THROW(
417 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true));
418 EXPECT_CALL(*this, executeUserDelete(testing::StrEq(username)))
419 .WillOnce(testing::Throw(
420 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure()))
421 .WillOnce(testing::DoDefault());
422
423 EXPECT_THROW(
424 deleteUser(username),
425 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure);
426 EXPECT_NO_THROW(UserMgr::deleteUser(username));
427}
428
Nan Zhou589aeb42022-10-25 00:07:09 +0000429TEST_F(UserMgrInTest, ThrowForInvalidPrivilegeThrowsWhenPrivilegeIsInvalid)
430{
431 EXPECT_THROW(
432 throwForInvalidPrivilege("whatever"),
433 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument);
434}
435
436TEST_F(UserMgrInTest, ThrowForInvalidPrivilegeNoThrowWhenPrivilegeIsValid)
437{
438 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-admin"));
439 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-operator"));
440 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-user"));
441 EXPECT_NO_THROW(throwForInvalidPrivilege("priv-noaccess"));
442}
443
Nan Zhouecf88762022-10-25 00:07:10 +0000444TEST_F(UserMgrInTest, ThrowForInvalidGroupsThrowsWhenGroupIsInvalid)
445{
446 EXPECT_THROW(
447 throwForInvalidGroups({"whatever"}),
448 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument);
449}
450
451TEST_F(UserMgrInTest, ThrowForInvalidGroupsNoThrowWhenGroupIsValid)
452{
453 EXPECT_NO_THROW(throwForInvalidGroups({"ipmi"}));
454 EXPECT_NO_THROW(throwForInvalidGroups({"ssh"}));
455 EXPECT_NO_THROW(throwForInvalidGroups({"redfish"}));
456 EXPECT_NO_THROW(throwForInvalidGroups({"web"}));
457}
458
Nan Zhouf25443e2022-10-25 00:07:11 +0000459TEST_F(UserMgrInTest, RenameUserOnSuccess)
460{
461 std::string username = "user001";
462 EXPECT_NO_THROW(
463 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true));
464 std::string newUsername = "user002";
465
466 EXPECT_NO_THROW(UserMgr::renameUser(username, newUsername));
467
468 // old username doesn't exist
469 EXPECT_THROW(getUserInfo(username),
470 sdbusplus::xyz::openbmc_project::User::Common::Error::
471 UserNameDoesNotExist);
472
473 UserInfoMap userInfo = getUserInfo(newUsername);
474 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-user");
475 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]),
476 testing::UnorderedElementsAre("redfish", "ssh"));
477 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true);
478
479 EXPECT_NO_THROW(UserMgr::deleteUser(newUsername));
480}
481
482TEST_F(UserMgrInTest, RenameUserThrowsInternalFailureIfExecuteUserModifyFails)
483{
484 std::string username = "user001";
485 EXPECT_NO_THROW(
486 UserMgr::createUser(username, {"redfish", "ssh"}, "priv-user", true));
487 std::string newUsername = "user002";
488
489 EXPECT_CALL(*this, executeUserRename(testing::StrEq(username),
490 testing::StrEq(newUsername)))
491 .WillOnce(testing::Throw(
492 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure()));
493 EXPECT_THROW(
494 UserMgr::renameUser(username, newUsername),
495 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure);
496
497 // The original user is unchanged
498 UserInfoMap userInfo = getUserInfo(username);
499 EXPECT_EQ(std::get<Privilege>(userInfo["UserPrivilege"]), "priv-user");
500 EXPECT_THAT(std::get<GroupList>(userInfo["UserGroups"]),
501 testing::UnorderedElementsAre("redfish", "ssh"));
502 EXPECT_EQ(std::get<UserEnabled>(userInfo["UserEnabled"]), true);
503
504 EXPECT_NO_THROW(UserMgr::deleteUser(username));
505}
506
507TEST_F(UserMgrInTest, DefaultUserModifyFailedWithInternalFailure)
508{
509 EXPECT_THROW(
510 UserMgr::executeUserRename("user0", "user1"),
511 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure);
512}
513
raviteja-b8cc44052019-02-27 23:29:36 -0600514} // namespace user
515} // namespace phosphor