generated from coulomb/repo-seed
profile-scoped ACL policy and redaction
This commit is contained in:
@@ -421,6 +421,26 @@ class ServiceRuntime:
|
||||
)
|
||||
return content_stream
|
||||
|
||||
def cmis_acl(
|
||||
self,
|
||||
access_point_id: str,
|
||||
object_id: str,
|
||||
context: OperationContext,
|
||||
) -> dict[str, Any]:
|
||||
mapper = self._cmis_mapper(access_point_id)
|
||||
decision = mapper.access_point.decide_action(CMISAction.GET_ACL, context, resource=object_id)
|
||||
if not decision.allowed:
|
||||
raise _cmis_authorization_error(decision, "getACL")
|
||||
asset_id = _cmis_asset_id(object_id)
|
||||
asset = self.repository.get_asset(asset_id)
|
||||
acl = mapper.acl_for_asset(asset, context)
|
||||
if acl is None:
|
||||
raise NotFoundError(
|
||||
"CMIS object not found",
|
||||
details={"object_id": object_id, "access_point_id": access_point_id},
|
||||
)
|
||||
return acl
|
||||
|
||||
def cmis_create_document(
|
||||
self,
|
||||
access_point_id: str,
|
||||
@@ -593,6 +613,7 @@ class ServiceRuntime:
|
||||
projections = [
|
||||
projection.to_dict()
|
||||
for relationship in self.repository.list_relationships(source_id=source_id)
|
||||
if self._cmis_relationship_visible(mapper, relationship, context)
|
||||
if (projection := mapper.map_relationship(relationship, context))
|
||||
]
|
||||
return {"items": projections, "count": len(projections)}
|
||||
@@ -621,6 +642,7 @@ class ServiceRuntime:
|
||||
}
|
||||
for event in events
|
||||
if event.target.startswith("asset:")
|
||||
if self._cmis_asset_visible(mapper, event.target.removeprefix("asset:"), context)
|
||||
]
|
||||
paged = changes[max(skip_count, 0) : max(skip_count, 0) + max(max_items, 0)]
|
||||
return {
|
||||
@@ -640,6 +662,29 @@ class ServiceRuntime:
|
||||
details={"access_point_id": access_point_id, "available": [profile.name for profile in _cmis_profiles()]},
|
||||
)
|
||||
|
||||
def _cmis_asset_visible(
|
||||
self,
|
||||
mapper: CMISDomainMapper,
|
||||
asset_id: str,
|
||||
context: OperationContext,
|
||||
) -> bool:
|
||||
try:
|
||||
return mapper.access_point.exposes_asset(self.repository.get_asset(asset_id), context)
|
||||
except NotFoundError:
|
||||
return False
|
||||
|
||||
def _cmis_relationship_visible(
|
||||
self,
|
||||
mapper: CMISDomainMapper,
|
||||
relationship: Any,
|
||||
context: OperationContext,
|
||||
) -> bool:
|
||||
if not self._cmis_asset_visible(mapper, relationship.source_id, context):
|
||||
return False
|
||||
if relationship.target_kind == RelationshipTargetKind.ASSET:
|
||||
return self._cmis_asset_visible(mapper, relationship.target_id, context)
|
||||
return True
|
||||
|
||||
def create_asset(self, payload: dict[str, Any], context: OperationContext) -> dict[str, Any]:
|
||||
classification = Classification.from_dict(payload["classification"])
|
||||
result = self.asset_service().create_asset(
|
||||
@@ -2087,6 +2132,14 @@ def create_app(runtime: ServiceRuntime | None = None):
|
||||
) -> dict[str, Any]:
|
||||
return response(runtime.cmis_content_stream, access_point_id, object_id, context)
|
||||
|
||||
@app.get("/cmis/{access_point_id}/browser/acl/{object_id:path}", tags=["cmis"])
|
||||
def cmis_acl(
|
||||
access_point_id: str,
|
||||
object_id: str,
|
||||
context: OperationContext = Depends(context_from_headers),
|
||||
) -> dict[str, Any]:
|
||||
return response(runtime.cmis_acl, access_point_id, object_id, context)
|
||||
|
||||
@app.post("/cmis/{access_point_id}/browser/document", tags=["cmis"])
|
||||
def cmis_create_document(
|
||||
access_point_id: str,
|
||||
|
||||
Reference in New Issue
Block a user