Add artifact.whitelist_expiration/src/artifact_whitelist_expiration/core.py
This commit is contained in:
parent
c1de678cc2
commit
5c12809983
1 changed files with 107 additions and 0 deletions
|
|
@ -0,0 +1,107 @@
|
|||
import json
|
||||
import os
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict
|
||||
|
||||
|
||||
class WhitelistEntry:
|
||||
"""Datenstruktur für Whitelist-Einträge mit Ablaufprüfung und Verlängerung."""
|
||||
|
||||
def __init__(self, entry_id: str, expires_at: str, reason_code: str) -> None:
|
||||
if not isinstance(entry_id, str) or not entry_id:
|
||||
raise ValueError("entry_id muss ein nicht-leerer String sein")
|
||||
if not isinstance(reason_code, str) or not reason_code:
|
||||
raise ValueError("reason_code muss ein nicht-leerer String sein")
|
||||
|
||||
try:
|
||||
self.expires_at = datetime.fromisoformat(expires_at)
|
||||
except Exception as e:
|
||||
raise ValueError(f"Ungültiges Datumsformat für expires_at: {e}") from e
|
||||
|
||||
self.entry_id = entry_id
|
||||
self.reason_code = reason_code
|
||||
|
||||
def is_expired(self) -> bool:
|
||||
"""Prüft, ob das Ablaufdatum überschritten ist."""
|
||||
return datetime.utcnow() > self.expires_at
|
||||
|
||||
def renew(self, days: int) -> None:
|
||||
"""Verlängert das Ablaufdatum um die angegebene Anzahl Tage."""
|
||||
if not isinstance(days, int) or days <= 0:
|
||||
raise ValueError("days muss eine positive Ganzzahl sein")
|
||||
self.expires_at = datetime.utcnow() + timedelta(days=days)
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return {
|
||||
"entry_id": self.entry_id,
|
||||
"expires_at": self.expires_at.isoformat(),
|
||||
"reason_code": self.reason_code,
|
||||
}
|
||||
|
||||
|
||||
# Hilfsfunktionen
|
||||
_DEF_INPUT_PATH = Path("data/unknown_whitelist.json")
|
||||
_DEF_OUTPUT_PATH = Path("output/unknown_whitelist_updated.json")
|
||||
|
||||
|
||||
def _load_whitelist(path: Path) -> Dict[str, WhitelistEntry]:
|
||||
if not path.exists():
|
||||
raise FileNotFoundError(f"Whitelist-Datei nicht gefunden: {path}")
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
entries: Dict[str, WhitelistEntry] = {}
|
||||
for entry in data:
|
||||
e = WhitelistEntry(
|
||||
entry_id=entry.get("entry_id"),
|
||||
expires_at=entry.get("expires_at"),
|
||||
reason_code=entry.get("reason_code"),
|
||||
)
|
||||
entries[e.entry_id] = e
|
||||
return entries
|
||||
|
||||
|
||||
def _save_whitelist(entries: Dict[str, WhitelistEntry], path: Path) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
json.dump([e.to_dict() for e in entries.values()], f, indent=2, ensure_ascii=False)
|
||||
|
||||
|
||||
def set_expiration(entry_id: str, days: int, input_path: Path | None = None, output_path: Path | None = None) -> None:
|
||||
"""Setzt das Ablaufdatum eines Eintrags neu."""
|
||||
if not isinstance(entry_id, str) or not entry_id:
|
||||
raise ValueError("entry_id darf nicht leer sein")
|
||||
if not isinstance(days, int) or days <= 0:
|
||||
raise ValueError("days muss > 0 sein")
|
||||
|
||||
input_path = input_path or _DEF_INPUT_PATH
|
||||
output_path = output_path or _DEF_OUTPUT_PATH
|
||||
|
||||
entries = _load_whitelist(input_path)
|
||||
if entry_id not in entries:
|
||||
raise KeyError(f"Eintrag {entry_id} nicht gefunden")
|
||||
|
||||
entry = entries[entry_id]
|
||||
entry.expires_at = datetime.utcnow() + timedelta(days=days)
|
||||
_save_whitelist(entries, output_path)
|
||||
|
||||
|
||||
def renew_entry(entry_id: str, input_path: Path | None = None, output_path: Path | None = None) -> bool:
|
||||
"""Verlängert den Ablauf eines vorhandenen Whitelist-Eintrags, wenn er vorhanden ist."""
|
||||
if not isinstance(entry_id, str) or not entry_id:
|
||||
raise ValueError("entry_id darf nicht leer sein")
|
||||
|
||||
input_path = input_path or _DEF_INPUT_PATH
|
||||
output_path = output_path or _DEF_OUTPUT_PATH
|
||||
|
||||
entries = _load_whitelist(input_path)
|
||||
if entry_id not in entries:
|
||||
return False
|
||||
|
||||
entry = entries[entry_id]
|
||||
if not entry.is_expired():
|
||||
entry.renew(7) # Standardverlängerung um 7 Tage
|
||||
_save_whitelist(entries, output_path)
|
||||
return True
|
||||
|
||||
return False
|
||||
Loading…
Reference in a new issue