File fix-the-regression-of-user.present-state-when-group-.patch of Package salt
From 502354be32fcff9b0607f6e435ca8825a4c2cd56 Mon Sep 17 00:00:00 2001
From: Victor Zhestkov <vzhestkov@suse.com>
Date: Thu, 3 Aug 2023 11:07:03 +0200
Subject: [PATCH] Fix the regression of user.present state when group is
unset (#589)
* Fix user.present state when group is unset
* Fix user unit test
---------
Co-authored-by: Megan Wilhite <mwilhite@vmware.com>
---
changelog/64211.fixed.md | 1 +
salt/states/user.py | 2 +-
tests/pytests/functional/states/test_user.py | 74 +++++++++++++++++++-
tests/pytests/unit/states/test_user.py | 2 +
4 files changed, 76 insertions(+), 3 deletions(-)
create mode 100644 changelog/64211.fixed.md
diff --git a/changelog/64211.fixed.md b/changelog/64211.fixed.md
new file mode 100644
index 0000000000..26b39acf02
--- /dev/null
+++ b/changelog/64211.fixed.md
@@ -0,0 +1 @@
+Fix user.present state when groups is unset to ensure the groups are unchanged, as documented.
diff --git a/salt/states/user.py b/salt/states/user.py
index ed2d5a05f4..929afb2cd1 100644
--- a/salt/states/user.py
+++ b/salt/states/user.py
@@ -100,7 +100,7 @@ def _changes(
change = {}
wanted_groups = sorted(set((groups or []) + (optional_groups or [])))
- if not remove_groups:
+ if not remove_groups or groups is None and not optional_groups:
wanted_groups = sorted(set(wanted_groups + lusr["groups"]))
if uid and lusr["uid"] != uid:
change["uid"] = uid
diff --git a/tests/pytests/functional/states/test_user.py b/tests/pytests/functional/states/test_user.py
index 09d34da168..96b1ec55c8 100644
--- a/tests/pytests/functional/states/test_user.py
+++ b/tests/pytests/functional/states/test_user.py
@@ -117,7 +117,6 @@ def test_user_present_when_home_dir_does_not_18843(states, existing_account):
ret = states.user.present(
name=existing_account.username,
home=existing_account.info.home,
- remove_groups=False,
)
assert ret.result is True
assert pathlib.Path(existing_account.info.home).is_dir()
@@ -228,7 +227,6 @@ def test_user_present_unicode(states, username, subtests):
roomnumber="①②③",
workphone="١٢٣٤",
homephone="६७८",
- remove_groups=False,
)
assert ret.result is True
@@ -429,3 +427,75 @@ def test_user_present_change_optional_groups(
user_info = modules.user.info(username)
assert user_info
assert user_info["groups"] == [group_1.name]
+
+
+@pytest.mark.skip_unless_on_linux(reason="underlying functionality only runs on Linux")
+def test_user_present_no_groups(modules, states, username):
+ """
+ test user.present when groups arg is not
+ included by the group is created in another
+ state. Re-run the states to ensure there are
+ not changes and it is idempotent.
+ """
+ groups = ["testgroup1", "testgroup2"]
+ try:
+ ret = states.group.present(name=username, gid=61121)
+ assert ret.result is True
+
+ ret = states.user.present(
+ name=username,
+ uid=61121,
+ gid=61121,
+ )
+ assert ret.result is True
+ assert ret.changes["groups"] == [username]
+ assert ret.changes["name"] == username
+
+ ret = states.group.present(
+ name=groups[0],
+ members=[username],
+ )
+ assert ret.changes["members"] == [username]
+
+ ret = states.group.present(
+ name=groups[1],
+ members=[username],
+ )
+ assert ret.changes["members"] == [username]
+
+ user_info = modules.user.info(username)
+ assert user_info
+ assert user_info["groups"] == [username, groups[0], groups[1]]
+
+ # run again, expecting no changes
+ ret = states.group.present(name=username)
+ assert ret.result is True
+ assert ret.changes == {}
+
+ ret = states.user.present(
+ name=username,
+ )
+ assert ret.result is True
+ assert ret.changes == {}
+
+ ret = states.group.present(
+ name=groups[0],
+ members=[username],
+ )
+ assert ret.result is True
+ assert ret.changes == {}
+
+ ret = states.group.present(
+ name=groups[1],
+ members=[username],
+ )
+ assert ret.result is True
+ assert ret.changes == {}
+
+ user_info = modules.user.info(username)
+ assert user_info
+ assert user_info["groups"] == [username, groups[0], groups[1]]
+ finally:
+ for group in groups:
+ ret = states.group.absent(name=group)
+ assert ret.result is True
diff --git a/tests/pytests/unit/states/test_user.py b/tests/pytests/unit/states/test_user.py
index 94e69d70ed..d50d16e3be 100644
--- a/tests/pytests/unit/states/test_user.py
+++ b/tests/pytests/unit/states/test_user.py
@@ -189,6 +189,8 @@ def test_present_uid_gid_change():
"user.chgid": Mock(),
"file.group_to_gid": mock_group_to_gid,
"file.gid_to_group": mock_gid_to_group,
+ "group.info": MagicMock(return_value=after),
+ "user.chgroups": MagicMock(return_value=True),
}
with patch.dict(user.__grains__, {"kernel": "Linux"}), patch.dict(
user.__salt__, dunder_salt
--
2.41.0