0.1.6
This commit is contained in:
parent
3fc5aec5fc
commit
921801caa6
15 changed files with 1102 additions and 423 deletions
143
tests/test_accounts.py
Normal file
143
tests/test_accounts.py
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def test_parse_login_defs_parses_known_keys(tmp_path: Path):
|
||||
from enroll.accounts import parse_login_defs
|
||||
|
||||
p = tmp_path / "login.defs"
|
||||
p.write_text(
|
||||
"""
|
||||
# comment
|
||||
UID_MIN 1000
|
||||
UID_MAX 60000
|
||||
SYS_UID_MIN 100
|
||||
SYS_UID_MAX 999
|
||||
UID_MIN not_an_int
|
||||
OTHER 123
|
||||
""",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
vals = parse_login_defs(str(p))
|
||||
assert vals["UID_MIN"] == 1000
|
||||
assert vals["UID_MAX"] == 60000
|
||||
assert vals["SYS_UID_MIN"] == 100
|
||||
assert vals["SYS_UID_MAX"] == 999
|
||||
assert "OTHER" not in vals
|
||||
|
||||
|
||||
def test_parse_passwd_and_group_and_ssh_files(tmp_path: Path):
|
||||
from enroll.accounts import find_user_ssh_files, parse_group, parse_passwd
|
||||
|
||||
passwd = tmp_path / "passwd"
|
||||
passwd.write_text(
|
||||
"\n".join(
|
||||
[
|
||||
"root:x:0:0:root:/root:/bin/bash",
|
||||
"# comment",
|
||||
"alice:x:1000:1000:Alice:/home/alice:/bin/bash",
|
||||
"bob:x:1001:1000:Bob:/home/bob:/usr/sbin/nologin",
|
||||
"badline",
|
||||
"cathy:x:notint:1000:Cathy:/home/cathy:/bin/bash",
|
||||
"",
|
||||
]
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
group = tmp_path / "group"
|
||||
group.write_text(
|
||||
"\n".join(
|
||||
[
|
||||
"root:x:0:",
|
||||
"users:x:1000:alice,bob",
|
||||
"admins:x:1002:alice",
|
||||
"badgroup:x:notint:alice",
|
||||
"",
|
||||
]
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
rows = parse_passwd(str(passwd))
|
||||
assert ("alice", 1000, 1000, "Alice", "/home/alice", "/bin/bash") in rows
|
||||
assert all(r[0] != "cathy" for r in rows) # skipped invalid UID
|
||||
|
||||
gid_to_name, name_to_gid, members = parse_group(str(group))
|
||||
assert gid_to_name[1000] == "users"
|
||||
assert name_to_gid["admins"] == 1002
|
||||
assert "alice" in members["admins"]
|
||||
|
||||
# ssh discovery: only authorized_keys, no symlinks
|
||||
home = tmp_path / "home" / "alice"
|
||||
sshdir = home / ".ssh"
|
||||
sshdir.mkdir(parents=True)
|
||||
ak = sshdir / "authorized_keys"
|
||||
ak.write_text("ssh-ed25519 AAA...", encoding="utf-8")
|
||||
# a symlink should be ignored
|
||||
(sshdir / "authorized_keys2").write_text("x", encoding="utf-8")
|
||||
os.symlink(str(sshdir / "authorized_keys2"), str(sshdir / "authorized_keys_link"))
|
||||
assert find_user_ssh_files(str(home)) == [str(ak)]
|
||||
|
||||
|
||||
def test_collect_non_system_users(monkeypatch, tmp_path: Path):
|
||||
import enroll.accounts as a
|
||||
|
||||
orig_parse_login_defs = a.parse_login_defs
|
||||
orig_parse_passwd = a.parse_passwd
|
||||
orig_parse_group = a.parse_group
|
||||
|
||||
# Provide controlled passwd/group/login.defs inputs via monkeypatch.
|
||||
passwd = tmp_path / "passwd"
|
||||
passwd.write_text(
|
||||
"\n".join(
|
||||
[
|
||||
"root:x:0:0:root:/root:/bin/bash",
|
||||
"nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin",
|
||||
"alice:x:1000:1000:Alice:/home/alice:/bin/bash",
|
||||
"sysuser:x:200:200:Sys:/home/sys:/bin/bash",
|
||||
"bob:x:1001:1000:Bob:/home/bob:/bin/false",
|
||||
"",
|
||||
]
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
group = tmp_path / "group"
|
||||
group.write_text(
|
||||
"\n".join(
|
||||
[
|
||||
"users:x:1000:alice,bob",
|
||||
"admins:x:1002:alice",
|
||||
"",
|
||||
]
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
defs = tmp_path / "login.defs"
|
||||
defs.write_text("UID_MIN 1000\n", encoding="utf-8")
|
||||
|
||||
monkeypatch.setattr(
|
||||
a, "parse_login_defs", lambda path=str(defs): orig_parse_login_defs(path)
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
a, "parse_passwd", lambda path=str(passwd): orig_parse_passwd(path)
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
a, "parse_group", lambda path=str(group): orig_parse_group(path)
|
||||
)
|
||||
|
||||
# Use a stable fake ssh discovery.
|
||||
monkeypatch.setattr(
|
||||
a, "find_user_ssh_files", lambda home: [f"{home}/.ssh/authorized_keys"]
|
||||
)
|
||||
|
||||
users = a.collect_non_system_users()
|
||||
assert [u.name for u in users] == ["alice"]
|
||||
u = users[0]
|
||||
assert u.primary_group == "users"
|
||||
assert u.supplementary_groups == ["admins"]
|
||||
assert u.ssh_files == ["/home/alice/.ssh/authorized_keys"]
|
||||
Loading…
Add table
Add a link
Reference in a new issue