feat(datasources): enforce policy-aware data visibility
Module Package Release / publish-packages (push) Successful in 11s
Module Package Release / publish-packages (push) Successful in 11s
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
from collections.abc import Mapping
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query, status
|
||||
@@ -370,7 +372,17 @@ def api_update_datasource_governance(
|
||||
action="datasources.governance.updated",
|
||||
object_type="datasource",
|
||||
object_id=item.ref,
|
||||
details={"governance": item.governance.to_dict()},
|
||||
details={
|
||||
"classification": item.governance.classification,
|
||||
"publication_state": item.governance.publication_state,
|
||||
"access_policy_ref": item.governance.access_policy_ref,
|
||||
"visibility_policy_configured": bool(
|
||||
item.governance.visibility_policy
|
||||
),
|
||||
"visibility_policy_hash": _mapping_hash(
|
||||
item.governance.visibility_policy
|
||||
),
|
||||
},
|
||||
)
|
||||
session.commit()
|
||||
return _datasource_response(item)
|
||||
@@ -580,6 +592,7 @@ def _datasource_response(item: DatasourceDescriptor) -> DatasourceResponse:
|
||||
name=field.name,
|
||||
data_type=field.data_type,
|
||||
nullable=field.nullable,
|
||||
classification=field.classification,
|
||||
)
|
||||
for field in item.schema
|
||||
],
|
||||
@@ -610,6 +623,7 @@ def _materialization_response(
|
||||
name=field.name,
|
||||
data_type=field.data_type,
|
||||
nullable=field.nullable,
|
||||
classification=field.classification,
|
||||
)
|
||||
for field in item.schema
|
||||
],
|
||||
@@ -643,6 +657,7 @@ def _stage_response(item: DatasourceStage) -> DatasourceStageResponse:
|
||||
name=field.name,
|
||||
data_type=field.data_type,
|
||||
nullable=field.nullable,
|
||||
classification=field.classification,
|
||||
)
|
||||
for field in item.schema
|
||||
],
|
||||
@@ -673,6 +688,7 @@ def _origin_response(item: DatasourceOrigin) -> DatasourceOriginResponse:
|
||||
name=field.name,
|
||||
data_type=field.data_type,
|
||||
nullable=field.nullable,
|
||||
classification=field.classification,
|
||||
)
|
||||
for field in item.schema
|
||||
],
|
||||
@@ -715,6 +731,13 @@ def _safe_mapping(value: object) -> Mapping[str, object]:
|
||||
return value if isinstance(value, Mapping) else {}
|
||||
|
||||
|
||||
def _mapping_hash(value: Mapping[str, object]) -> str | None:
|
||||
if not value:
|
||||
return None
|
||||
encoded = json.dumps(value, sort_keys=True, separators=(",", ":"), default=str)
|
||||
return hashlib.sha256(encoded.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
def _audit(
|
||||
session: Session,
|
||||
principal: ApiPrincipal,
|
||||
|
||||
Reference in New Issue
Block a user