Files
Netbox-Store/netbox_plugin/netbox_plugin_store/redaction.py
T
MrBlake f36d6be511
CI / php-store (push) Waiting to run
CI / python-components (push) Waiting to run
feat: add NetBox plugin store
2026-08-24 20:51:25 +02:00

36 lines
1.2 KiB
Python

from __future__ import annotations
import re
from collections.abc import Mapping, Sequence
_SECRET_KEYS = re.compile(r"token|secret|password|authorization|cookie|api[_-]?key", re.I)
_BEARER = re.compile(r"(?i)\bBearer\s+[A-Za-z0-9._~+\-/]+=*")
_URL_CREDENTIALS = re.compile(r"(?i)(https?://)([^/@\s:]+):([^/@\s]+)@")
_ASSIGNMENT = re.compile(
r"(?i)\b(token|secret|password|authorization|api[_-]?key)\s*([=:])\s*([^\s,;]+)"
)
def redact_text(value: object, *, limit: int = 8_000) -> str:
text = str(value)
text = _BEARER.sub("Bearer [REDACTED]", text)
text = _URL_CREDENTIALS.sub(r"\1[REDACTED]@", text)
text = _ASSIGNMENT.sub(r"\1\2[REDACTED]", text)
if len(text) > limit:
return text[:limit] + "\n...[truncated]"
return text
def redact_data(value: object) -> object:
if isinstance(value, Mapping):
return {
str(key): "[REDACTED]" if _SECRET_KEYS.search(str(key)) else redact_data(item)
for key, item in value.items()
}
if isinstance(value, Sequence) and not isinstance(value, (str, bytes, bytearray)):
return [redact_data(item) for item in value]
if isinstance(value, str):
return redact_text(value)
return value