Changeset 4af65b0 in flexoentity
- Timestamp:
- 11/04/25 20:20:01 (2 months ago)
- Branches:
- master
- Children:
- 73d392f
- Parents:
- bf30018
- Files:
-
- 1 added
- 5 edited
-
flexoentity/__init__.py (modified) (2 diffs)
-
flexoentity/flexo_entity.py (modified) (8 diffs)
-
flexoentity/flexo_logging.conf (added)
-
flexoentity/id_factory.py (modified) (1 diff)
-
tests/test_id_lifecycle.py (modified) (1 diff)
-
tests/test_persistance_integrity.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
flexoentity/__init__.py
rbf30018 r4af65b0 10 10 from .flexo_entity import FlexoEntity, EntityType, EntityState 11 11 from .domain import Domain 12 import logging 13 import logging.config 14 import os 15 from pathlib import Path 12 16 13 17 __all__ = [ … … 20 24 ] 21 25 26 # FIXME: change the default log path to /var/log/ammos/ammos.log when system 27 # configuration created this dir with the appropriate rights 28 29 log_dir = Path(os.environ.get('FLEXO_LOG_DIR', '/tmp/')) 30 31 log_path = log_dir / 'flexo.log' 32 33 if not log_path.exists(): 34 try: 35 log_path.touch() 36 except PermissionError: 37 conf_file = Path(__file__).parent / 'flexo_logging.conf' 38 print("Conf file", conf_file) 39 logging.config.fileConfig(conf_file) 40 else: 41 logging.basicConfig(filename=str(log_path), encoding='utf-8', level=logging.DEBUG) 42 43 logger = logging.getLogger(__name__) 44 45 logger.setLevel(os.environ.get('FLEXO_LOG_LEVEL', logger.getEffectiveLevel())) 22 46 # Optional: keep dynamic version retrieval synced with pyproject.toml 23 47 try: -
flexoentity/flexo_entity.py
rbf30018 r4af65b0 75 75 """ 76 76 I map a fixed number of entity types to a single unique letter, 77 that structures different types 77 that structures different types 78 78 """ 79 GENERIC = "G"79 GENERIC = "G" 80 80 DOMAIN = "D" 81 81 MEDIA = "M" … … 288 288 EntityState.PUBLISHED, 289 289 ) 290 290 291 def _compute_fingerprint(self) -> str: 291 292 """I always recompute the entity's content fingerprint.""" … … 302 303 self.fingerprint = new_fp 303 304 self.flexo_id = FlexOID.safe_generate(self.domain_code(), 304 self.entity_type.value,305 self.state.value,306 self.text_seed,307 self.flexo_id.version)305 self.entity_type.value, 306 self.state.value, 307 self.text_seed, 308 self.flexo_id.version) 308 309 return True 309 310 return False … … 367 368 if self.state == EntityState.DRAFT: 368 369 new_fid = FlexOID.safe_generate(self.domain_code(), 369 self.entity_type.value,370 EntityState.APPROVED.value,371 self.text_seed,372 version=self.version373 )370 self.entity_type.value, 371 EntityState.APPROVED.value, 372 self.text_seed, 373 version=self.version 374 ) 374 375 self.origin = self.flexo_id # optional: keep audit trail 375 376 self.flexo_id = new_fid … … 377 378 raise ValueError("Only drafts can be approved") 378 379 379 380 380 def sign(self): 381 381 """ … … 394 394 """ 395 395 I move from APPROVED or APPROVED_AND_SIGNED to PUBLISHED. 396 396 397 397 Uses allowed_transitions() to verify legality, 398 398 then performs a version bump and lineage update. … … 469 469 info["stored_fingerprint"] = getattr(entity, "fingerprint", None) 470 470 471 # Expected ID hash from current seed (should match fid.hash_part if content didn't change) 471 # Expected ID hash from current seed (should match fid.hash_part 472 # if content didn't change) 472 473 exp_hash = FlexOID._blake_hash(canonical_seed(f"{fid.domain}:{fid.entity_type}:{entity.text_seed}")) 473 474 info["expected_id_hash_from_seed"] = exp_hash … … 507 508 # --- Fingerprint validation --- 508 509 if hasattr(entity, "fingerprint") and entity.fingerprint: 509 seed = canonical_seed(entity.text_seed)510 510 expected_fp = entity._compute_fingerprint() 511 511 if expected_fp != entity.fingerprint: -
flexoentity/id_factory.py
rbf30018 r4af65b0 76 76 import json 77 77 from datetime import datetime, timezone 78 from logging import Logger 79 80 logger = Logger(__file__) 78 from flexoentity import logger 81 79 82 80 def canonical_seed(obj) -> str: -
tests/test_id_lifecycle.py
rbf30018 r4af65b0 79 79 # simulate tampering 80 80 q.text = "Tampered text" 81 print(FlexoEntity.debug_integrity(q))82 81 assert not FlexoEntity.verify_integrity(q) 83 82 -
tests/test_persistance_integrity.py
rbf30018 r4af65b0 34 34 """ 35 35 json_str = approved_question.to_json() 36 print("JSON", json_str)37 36 loaded = SingleChoiceQuestion.from_json(json_str) 38 37 39 print("Approved", approved_question.text_seed)40 print("Loaded", loaded.text_seed)41 38 # Fingerprint and state should match — integrity must pass 42 39 assert SingleChoiceQuestion.verify_integrity(loaded)
Note:
See TracChangeset
for help on using the changeset viewer.
