fix(telefoni): accept callbacks via db whitelist and internal fallback
This commit is contained in:
parent
8e5b3cf3d2
commit
6a68aecafa
6
RELEASE_NOTES_v2.3.6.md
Normal file
6
RELEASE_NOTES_v2.3.6.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# Release Notes v2.3.6 — 16. maj 2026
|
||||||
|
|
||||||
|
## Telefoni Callback Fix
|
||||||
|
- telefoni callbacks now use both env and DB whitelist
|
||||||
|
- added internal 172.16.0.0/12 fallback acceptance
|
||||||
|
- added migration `migrations/186_telefoni_ip_whitelist_setting.sql`
|
||||||
@ -122,11 +122,23 @@ def _is_internal_bmc_ip(client_ip: str) -> bool:
|
|||||||
return ip_obj in ipaddress.ip_network("172.16.31.0/24")
|
return ip_obj in ipaddress.ip_network("172.16.31.0/24")
|
||||||
|
|
||||||
|
|
||||||
|
def _is_internal_bmc_supernet_ip(client_ip: str) -> bool:
|
||||||
|
if not client_ip:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
ip_obj = ipaddress.ip_address(client_ip)
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
|
return ip_obj in ipaddress.ip_network("172.16.0.0/12")
|
||||||
|
|
||||||
|
|
||||||
def _validate_yealink_request(request: Request, token: Optional[str]) -> None:
|
def _validate_yealink_request(request: Request, token: Optional[str]) -> None:
|
||||||
env_secret = (getattr(settings, "TELEFONI_SHARED_SECRET", "") or "").strip()
|
env_secret = (getattr(settings, "TELEFONI_SHARED_SECRET", "") or "").strip()
|
||||||
db_secret = (_get_setting_value("telefoni_shared_secret", "") or "").strip()
|
db_secret = (_get_setting_value("telefoni_shared_secret", "") or "").strip()
|
||||||
accepted_tokens = {s for s in (env_secret, db_secret) if s}
|
accepted_tokens = {s for s in (env_secret, db_secret) if s}
|
||||||
whitelist = (getattr(settings, "TELEFONI_IP_WHITELIST", "") or "").strip()
|
env_whitelist = (getattr(settings, "TELEFONI_IP_WHITELIST", "") or "").strip()
|
||||||
|
db_whitelist = (_get_setting_value("telefoni_ip_whitelist", "") or "").strip()
|
||||||
|
whitelist = ",".join([part for part in (env_whitelist, db_whitelist) if part])
|
||||||
client_ip = _get_client_ip(request)
|
client_ip = _get_client_ip(request)
|
||||||
path = request.url.path
|
path = request.url.path
|
||||||
|
|
||||||
@ -174,6 +186,15 @@ def _validate_yealink_request(request: Request, token: Optional[str]) -> None:
|
|||||||
else:
|
else:
|
||||||
logger.info("ℹ️ Telefoni callback whitelist not configured path=%s ip=%s", path, client_ip)
|
logger.info("ℹ️ Telefoni callback whitelist not configured path=%s ip=%s", path, client_ip)
|
||||||
|
|
||||||
|
# Safety fallback: allow callbacks from internal BMC network range.
|
||||||
|
if _is_internal_bmc_supernet_ip(client_ip):
|
||||||
|
logger.warning(
|
||||||
|
"⚠️ Telefoni callback accepted via internal supernet fallback path=%s ip=%s",
|
||||||
|
path,
|
||||||
|
client_ip,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
logger.warning("❌ Telefoni callback forbidden path=%s ip=%s", path, client_ip)
|
logger.warning("❌ Telefoni callback forbidden path=%s ip=%s", path, client_ip)
|
||||||
raise HTTPException(status_code=403, detail="Forbidden")
|
raise HTTPException(status_code=403, detail="Forbidden")
|
||||||
|
|
||||||
|
|||||||
6
migrations/186_telefoni_ip_whitelist_setting.sql
Normal file
6
migrations/186_telefoni_ip_whitelist_setting.sql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
-- Migration 186: Telefoni callback IP whitelist setting
|
||||||
|
|
||||||
|
INSERT INTO settings (key, value, category, description, value_type, is_public)
|
||||||
|
VALUES
|
||||||
|
('telefoni_ip_whitelist', '', 'telefoni', 'CSV med tilladte callback IP/CIDR til Yealink callbacks', 'string', false)
|
||||||
|
ON CONFLICT (key) DO NOTHING;
|
||||||
Loading…
Reference in New Issue
Block a user