From b4329a5b771134b8553234852e8e6138259ab19f Mon Sep 17 00:00:00 2001 From: Adam Goldsmith Date: Tue, 3 Dec 2024 18:56:59 -0500 Subject: [PATCH] doorcontrol: Keep better track of which cards are 26 bit --- doorcontrol/hid/Credential.py | 9 +++------ doorcontrol/tasks/update_doors.py | 14 +++++++++++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/doorcontrol/hid/Credential.py b/doorcontrol/hid/Credential.py index 826f3d0..a05a557 100644 --- a/doorcontrol/hid/Credential.py +++ b/doorcontrol/hid/Credential.py @@ -24,6 +24,7 @@ class InvalidParity(InvalidHexCode): @dataclasses.dataclass(frozen=True) class Credential: bits: bitstring.Bits + is_26bit: bool = dataclasses.field(default=False, compare=False) @staticmethod def even_parity(bits: bitstring.Bits) -> bool: @@ -55,16 +56,12 @@ class Credential: if bits[31] != (cls.odd_parity(bits)): raise InvalidParity(bits, "odd") - return cls(bits) + return cls(bits, is_26bit=True) @classmethod - def from_any_hex(cls, hex_code: str) -> "Credential": + def from_raw_hex(cls, hex_code: str) -> "Credential": return cls(bitstring.Bits(hex=hex_code)) - @property - def is_26bit(self) -> bool: - return self.bits[:6].all(0) - @property def facility_code(self) -> int: if not self.is_26bit: diff --git a/doorcontrol/tasks/update_doors.py b/doorcontrol/tasks/update_doors.py index 95a91b1..42307e3 100644 --- a/doorcontrol/tasks/update_doors.py +++ b/doorcontrol/tasks/update_doors.py @@ -45,7 +45,7 @@ class DoorMember: ) ) if member.nfc_card_number: - credentials.add(Credential.from_any_hex(member.nfc_card_number)) + credentials.add(Credential.from_raw_hex(member.nfc_card_number)) reasons_and_schedules: dict[str, str] = {} if ( @@ -107,7 +107,11 @@ class DoorMember: }, cardholderID=data.attrib["cardholderID"], credentials={ - Credential.from_any_hex(c.attrib["rawCardNumber"]) + ( + Credential.from_26bit_hex(c.attrib["rawCardNumber"]) + if "formatID" in c.attrib + else Credential.from_raw_hex(c.attrib["rawCardNumber"]) + ) for c in data.findall("{*}Credential") }, schedules={r.attrib["scheduleName"] for r in data.findall("{*}Role")}, @@ -237,7 +241,11 @@ def update_door(door: Door, dry_run: bool = False): logger.debug(f"Fetching credentials from {door}") existing_door_credentials = { - Credential.from_any_hex(c.attrib["rawCardNumber"]) + ( + Credential.from_26bit_hex(c.attrib["rawCardNumber"]) + if "formatID" in c.attrib + else Credential.from_raw_hex(c.attrib["rawCardNumber"]) + ) for c in door.controller.get_credentials() }