Source code for tropicsquare.config.uap_base

"""Base classes and helpers for User Access Policy (UAP) configuration"""

from tropicsquare.config.base import BaseConfig


[docs] class UapPermissionField: """Represents an 8-bit UAP permission field. Each field contains permission bits for 4 pairing key slots: - Bit 0: Pairing Key slot 0 has access - Bit 1: Pairing Key slot 1 has access - Bit 2: Pairing Key slot 2 has access - Bit 3: Pairing Key slot 3 has access - Bits 4-7: Reserved """
[docs] def __init__(self, value: int = 0xFF) -> None: """Initialize permission field. :param value: 8-bit permission value (default: 0xFF = all slots have access) """ self._value = value & 0xFF
[docs] def get_slot_permission(self, slot: int) -> bool: """Check if pairing key slot has access. :param slot: Slot number (0-3) :returns: True if slot has access """ if not 0 <= slot <= 3: raise ValueError("Slot must be 0-3, got {}".format(slot)) return bool((self._value >> slot) & 1)
[docs] def set_slot_permission(self, slot: int, has_access: bool) -> None: """Set permission for pairing key slot. :param slot: Slot number (0-3) :param has_access: True to grant access, False to deny """ if not 0 <= slot <= 3: raise ValueError("Slot must be 0-3, got {}".format(slot)) if has_access: self._value |= (1 << slot) else: self._value &= ~(1 << slot)
@property def pkey_slot_0(self) -> bool: """Pairing Key slot 0 has access.""" return self.get_slot_permission(0) @pkey_slot_0.setter def pkey_slot_0(self, value: bool) -> None: self.set_slot_permission(0, value) @property def pkey_slot_1(self) -> bool: """Pairing Key slot 1 has access.""" return self.get_slot_permission(1) @pkey_slot_1.setter def pkey_slot_1(self, value: bool) -> None: self.set_slot_permission(1, value) @property def pkey_slot_2(self) -> bool: """Pairing Key slot 2 has access.""" return self.get_slot_permission(2) @pkey_slot_2.setter def pkey_slot_2(self, value: bool) -> None: self.set_slot_permission(2, value) @property def pkey_slot_3(self) -> bool: """Pairing Key slot 3 has access.""" return self.get_slot_permission(3) @pkey_slot_3.setter def pkey_slot_3(self, value: bool) -> None: self.set_slot_permission(3, value) @property def value(self) -> int: """Raw 8-bit value.""" return self._value @value.setter def value(self, val: int) -> None: self._value = val & 0xFF
[docs] def to_dict(self) -> dict: """Export as dictionary.""" return { 'pkey_slot_0': self.pkey_slot_0, 'pkey_slot_1': self.pkey_slot_1, 'pkey_slot_2': self.pkey_slot_2, 'pkey_slot_3': self.pkey_slot_3 }
[docs] def __str__(self) -> str: """Format as table cells: x | x | | x No leading/trailing pipes - will be added by parent class. Returns 4 cells separated by ' | '. """ parts = [] for i in range(4): if self.get_slot_permission(i): parts.append("x") else: parts.append(" ") # 1 space for alignment return " | ".join(parts)
[docs] class UapMultiSlotConfig(BaseConfig): """Base class for UAP configs with multiple slots. Used for configs that have 4 slots, each with 8-bit permission field. """ def _get_slot_field(self, slot_pos: int) -> UapPermissionField: """Get 8-bit permission field at slot position. :param slot_pos: Bit position of slot (0, 8, 16, or 24) :returns: Permission field at the specified slot position :rtype: UapPermissionField """ field_value = (self._value >> slot_pos) & 0xFF return UapPermissionField(field_value) def _set_slot_field(self, slot_pos: int, field: UapPermissionField) -> None: """Set 8-bit permission field at slot position. :param slot_pos: Bit position of slot (0, 8, 16, or 24) :param field: UapPermissionField object """ field_value = field.value # Clear existing field and set new value mask = 0xFF << slot_pos self._value = (self._value & ~mask) | (field_value << slot_pos)
[docs] def __str__(self) -> str: """Table row: ClassName | slot_0 || slot_1 || slot_2 || slot_3 | Uses || to visually separate 4 different slot permission fields. """ s0 = str(self._get_slot_field(0)) s1 = str(self._get_slot_field(8)) s2 = str(self._get_slot_field(16)) s3 = str(self._get_slot_field(24)) return "{:26s} | {} || {} || {} || {} |".format( self.__class__.__name__, s0, s1, s2, s3 )
[docs] class UapSingleFieldConfig(BaseConfig): """Base class for UAP configs with single 8-bit permission field."""
[docs] def __init__(self, value: int = 0xFFFFFFFF) -> None: """Initialize with default all-access value.""" super().__init__(value)
@property def permissions(self) -> UapPermissionField: """Get permission field (8 bits at position 0).""" field_value = self._value & 0xFF return UapPermissionField(field_value) @permissions.setter def permissions(self, field: UapPermissionField) -> None: """Set permission field.""" self._value = (self._value & ~0xFF) | field.value
[docs] def to_dict(self) -> dict: """Export as dictionary.""" return { 'permissions': self.permissions.to_dict() }
[docs] def __str__(self) -> str: """Table row: ClassName | permissions cells |""" perm_str = str(self.permissions) return "{:26s} | {} |".format( self.__class__.__name__, perm_str )
[docs] class UapDualFieldConfig(BaseConfig): """Base class for UAP configs with two 8-bit permission fields (CFG and FUNC)."""
[docs] def __init__(self, value: int = 0xFFFFFFFF) -> None: """Initialize with default all-access value.""" super().__init__(value)
@property def cfg_permissions(self) -> UapPermissionField: """Get CFG permission field (8 bits at position 0).""" field_value = self._value & 0xFF return UapPermissionField(field_value) @cfg_permissions.setter def cfg_permissions(self, field: UapPermissionField) -> None: """Set CFG permission field.""" self._value = (self._value & ~0xFF) | field.value @property def func_permissions(self) -> UapPermissionField: """Get FUNC permission field (8 bits at position 8).""" field_value = (self._value >> 8) & 0xFF return UapPermissionField(field_value) @func_permissions.setter def func_permissions(self, field: UapPermissionField) -> None: """Set FUNC permission field.""" self._value = (self._value & ~0xFF00) | (field.value << 8)
[docs] def to_dict(self) -> dict: """Export as dictionary.""" return { 'cfg_permissions': self.cfg_permissions.to_dict(), 'func_permissions': self.func_permissions.to_dict() }
[docs] def __str__(self) -> str: """Table row: ClassName | cfg cells || func cells | Uses || to visually separate cfg and func permission fields. """ cfg_str = str(self.cfg_permissions) func_str = str(self.func_permissions) return "{:26s} | {} || {} |".format( self.__class__.__name__, cfg_str, func_str )