From: Iker Pedrosa Date: Wed, 5 Mar 2025 17:05:59 +0000 (+0100) Subject: tests/: implement binding for `getent gshadow $name` X-Git-Tag: 4.18.0-rc1~94 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d17e1133ee832129c54d1defaa8afc0580508ef8;p=thirdparty%2Fshadow.git tests/: implement binding for `getent gshadow $name` Provide a way for the system framework to run `getent gshadow $name` and check its output in a meaningful way. Signed-off-by: Iker Pedrosa Reviewed-by: Dan Lavu --- diff --git a/tests/system/framework/utils/tools.py b/tests/system/framework/utils/tools.py index 0d7a3f53f..c03091c4c 100644 --- a/tests/system/framework/utils/tools.py +++ b/tests/system/framework/utils/tools.py @@ -16,6 +16,7 @@ __all__ = [ "PasswdEntry", "ShadowEntry", "GroupEntry", + "GShadowEntry" "InitgroupsEntry", "LinuxToolsUtils", "KillCommand", @@ -369,6 +370,69 @@ class GroupEntry(object): return cls.FromDict(result[0]) +class GShadowEntry(object): + """ + Result of ``getent gshadow`` + """ + + def __init__( + self, + name: str, + password: str, + administrators: str, + members: str, + ) -> None: + self.name: str | None = name + """ + Group name. + """ + + self.password: str | None = password + """ + Group password. + """ + + self.administrators: int = administrators + """ + Group administrators. + """ + + self.members: int = members + """ + Group members. + """ + + def __str__(self) -> str: + return ( + f"({self.name}:{self.password}:{self.administrators}:" + f"{self.members})" + ) + + def __repr__(self) -> str: + return str(self) + + @classmethod + def FromDict(cls, d: dict[str, Any]) -> GShadowEntry: + return cls( + name=d.get("group_name", None), + password=d.get("password", None), + administrators=d.get("administrators", None), + members=d.get("members", []), + ) + + @classmethod + def FromOutput(cls, stdout: str) -> GShadowEntry: + result = jc.parse("gshadow", stdout) + + if not isinstance(result, list): + raise TypeError(f"Unexpected type: {type(result)}, expecting list") + + if len(result) != 1: + raise ValueError("More then one entry was returned") + + return cls.FromDict(result[0]) + + class InitgroupsEntry(object): """ Result of ``getent initgroups`` @@ -554,6 +618,19 @@ class GetentUtils(MultihostUtility[MultihostHost]): """ return self.__exec(GroupEntry, "group", name, service) + def gshadow(self, name: str | int, *, service: str | None = None) -> GShadowEntry | None: + """ + Call ``getent gshadow $name`` + + :param name: Group name or id. + :type name: str | int + :param service: Service used, defaults to None + :type service: str | None + :return: group data, None if not found + :rtype: GShadowEntry | None + """ + return self.__exec(GShadowEntry, "gshadow", name, service) + def initgroups(self, name: str, *, service: str | None = None) -> InitgroupsEntry: """ Call ``getent initgroups $name``