Files

88 lines
3.3 KiB
Python
Raw Permalink Normal View History

"""LDAP helpers and the fake directory; no domain controller needed."""
from __future__ import annotations
import uuid
from pathlib import Path
import pytest
from fakedir import FAKE_PASSWORD, FakeDirectory
from pshelpers import make_settings
from packetstation.auth import groups
from packetstation.auth.ldap import Directory, LdapUnavailable, guid_filter, parse_guid, user_from_entry
GUID = uuid.UUID("01234567-89ab-cdef-0123-456789abcdef")
def test_parse_guid_bytes_and_string() -> None:
raw = GUID.bytes_le
assert parse_guid(raw) == GUID
assert parse_guid([raw]) == GUID
assert parse_guid("{01234567-89ab-cdef-0123-456789abcdef}") == GUID
assert parse_guid("01234567-89AB-CDEF-0123-456789ABCDEF") == GUID
with pytest.raises(ValueError):
parse_guid(b"short")
def test_guid_filter_escapes_every_byte() -> None:
flt = guid_filter(GUID)
assert flt.startswith("(objectGUID=\\67\\45\\23\\01") and flt.endswith(")")
assert flt.count("\\") == 16
def test_user_from_entry() -> None:
entry = {
"dn": "CN=Andy,DC=x",
"raw_attributes": {"objectGUID": [GUID.bytes_le]},
"attributes": {
"sAMAccountName": ["weld.andy"],
"userPrincipalName": ["[email protected]"],
"displayName": ["Andy Welder"],
"employeeID": ["0303"],
"mail": [],
"userAccountControl": ["514"],
"distinguishedName": ["CN=Andy,DC=x"],
},
}
u = user_from_entry(entry)
assert u.guid == GUID and u.sam_account == "weld.andy" and u.display_name == "Andy Welder"
assert u.emp_no == "0303" # text, leading zero kept
assert u.email is None and u.disabled is True and u.dn == "CN=Andy,DC=x"
def test_plain_ldap_refused_without_starttls(tmp_path: Path) -> None:
pw = tmp_path / "pw"
pw.write_text("x")
s = make_settings(tmp_path, ldap_url="ldap://dc.example:389", ldap_bind_dn="CN=svc", ldap_password_file=pw)
with pytest.raises(LdapUnavailable, match="plain LDAP"):
Directory(s).find_user("someone")
def test_empty_password_never_binds(tmp_path: Path) -> None:
s = make_settings(tmp_path, ldap_url="ldaps://dc.invalid:636")
assert Directory(s).verify_password("CN=x,DC=y", "") is False
def test_missing_service_secret_is_unavailable(tmp_path: Path) -> None:
s = make_settings(
tmp_path, ldap_url="ldaps://dc.invalid:636", ldap_bind_dn="CN=svc", ldap_password_file=tmp_path / "none"
)
with pytest.raises(LdapUnavailable, match="LDAP_PASSWORD_FILE"):
Directory(s).list_groups()
def test_fake_directory_nested_and_ou() -> None:
d = FakeDirectory()
ned = d.find_user("NESTED.NED")
assert ned is not None
assert groups.roles_from_groups(d.groups_of(ned.dn)) == ["shop:10:worker"]
bo = d.find_user("[email protected]")
assert bo is not None
assert groups.roles_from_groups(d.groups_of(bo.dn)) == ["shop:03:supervisor"]
assert "PS-14-Electrical-Lead" not in d.list_groups() and "PS-Extra-Legacy" in d.list_groups()
sams = {u.sam_account for u in d.members_of("PS-03-WeldParts-Worker")}
assert {"weld.andy", "both.bo", "dup.dave", "disabled.dan"} <= sams
assert d.verify_password(bo.dn, FAKE_PASSWORD) and not d.verify_password(bo.dn, "nope")
assert d.verify_password(bo.dn, "") is False