refactor(tasks): centralize access request lookup
This commit is contained in:
@@ -60,8 +60,7 @@ from app.domain.schemas.operational_task import (
|
|||||||
RecoverExpiredLeasesResult,
|
RecoverExpiredLeasesResult,
|
||||||
StoredEvidenceRecord,
|
StoredEvidenceRecord,
|
||||||
)
|
)
|
||||||
from app.domain.schemas.operational_data import TaskDataSnapshot
|
from app.domain.schemas.operational_data import TaskDataSnapshot, TaskDataSource
|
||||||
from app.domain.schemas.operational_data import TaskDataSource
|
|
||||||
from app.services.content_digest import digest
|
from app.services.content_digest import digest
|
||||||
|
|
||||||
|
|
||||||
@@ -122,6 +121,12 @@ class OperationalTaskService:
|
|||||||
append_event = getattr(self.repo, "append_event", None)
|
append_event = getattr(self.repo, "append_event", None)
|
||||||
return await append_event(**kwargs) if append_event is not None else None
|
return await append_event(**kwargs) if append_event is not None else None
|
||||||
|
|
||||||
|
async def _list_access_requests(self, task_id: UUID | str) -> list[dict]:
|
||||||
|
list_access_requests = getattr(self.repo, "list_access_requests", None)
|
||||||
|
if list_access_requests is None:
|
||||||
|
return []
|
||||||
|
return await list_access_requests(str(task_id))
|
||||||
|
|
||||||
def _permission_view(self) -> OperationalTaskPermissions:
|
def _permission_view(self) -> OperationalTaskPermissions:
|
||||||
permissions = self.permissions
|
permissions = self.permissions
|
||||||
return OperationalTaskPermissions(
|
return OperationalTaskPermissions(
|
||||||
@@ -219,7 +224,7 @@ class OperationalTaskService:
|
|||||||
for document in await self.repo.list_evidence(str(task_id))
|
for document in await self.repo.list_evidence(str(task_id))
|
||||||
]
|
]
|
||||||
actions = await self.repo.list_actions(str(task_id))
|
actions = await self.repo.list_actions(str(task_id))
|
||||||
access_requests = await self.repo.list_access_requests(str(task_id)) if hasattr(self.repo, "list_access_requests") else []
|
access_requests = await self._list_access_requests(task_id)
|
||||||
active_run = await self._active_run(task)
|
active_run = await self._active_run(task)
|
||||||
work_order_snapshot = None
|
work_order_snapshot = None
|
||||||
if task["task_type"] == "external_work_order" and task["source"].get("external_id"):
|
if task["task_type"] == "external_work_order" and task["source"].get("external_id"):
|
||||||
@@ -249,10 +254,9 @@ class OperationalTaskService:
|
|||||||
])
|
])
|
||||||
if SCADA_VIEW in self.permissions:
|
if SCADA_VIEW in self.permissions:
|
||||||
scopes.extend(["scada_devices", "scada_readings"])
|
scopes.extend(["scada_devices", "scada_readings"])
|
||||||
if hasattr(self.repo, "list_access_requests"):
|
for request in await self._list_access_requests(task_id):
|
||||||
for request in await self.repo.list_access_requests(str(task_id)):
|
if request["status"] == "approved":
|
||||||
if request["status"] == "approved":
|
scopes.extend(request["approved_scopes"])
|
||||||
scopes.extend(request["approved_scopes"])
|
|
||||||
return AgentTaskContext(
|
return AgentTaskContext(
|
||||||
task=await self.detail(task_id),
|
task=await self.detail(task_id),
|
||||||
approved_data_scopes=list(dict.fromkeys(scopes)),
|
approved_data_scopes=list(dict.fromkeys(scopes)),
|
||||||
@@ -263,8 +267,6 @@ class OperationalTaskService:
|
|||||||
permission = SCADA_VIEW if source.startswith("scada_") else SIMULATION_VIEW
|
permission = SCADA_VIEW if source.startswith("scada_") else SIMULATION_VIEW
|
||||||
if permission in self.permissions:
|
if permission in self.permissions:
|
||||||
return True
|
return True
|
||||||
if not hasattr(self.repo, "list_access_requests"):
|
|
||||||
return False
|
|
||||||
active_run = await self._active_run(task)
|
active_run = await self._active_run(task)
|
||||||
if active_run is None or active_run.get("status") not in {"claimed", "running"}:
|
if active_run is None or active_run.get("status") not in {"claimed", "running"}:
|
||||||
return False
|
return False
|
||||||
@@ -273,7 +275,7 @@ class OperationalTaskService:
|
|||||||
self._require_active_run_lease(active_run, self._now())
|
self._require_active_run_lease(active_run, self._now())
|
||||||
return any(
|
return any(
|
||||||
row["status"] == "approved" and source in row["approved_scopes"]
|
row["status"] == "approved" and source in row["approved_scopes"]
|
||||||
for row in await self.repo.list_access_requests(str(task_id))
|
for row in await self._list_access_requests(task_id)
|
||||||
)
|
)
|
||||||
|
|
||||||
async def request_access(self, task_id: UUID, command: TaskAccessRequestCreate) -> TaskAccessRequest:
|
async def request_access(self, task_id: UUID, command: TaskAccessRequestCreate) -> TaskAccessRequest:
|
||||||
@@ -297,7 +299,7 @@ class OperationalTaskService:
|
|||||||
"SESSION_MISMATCH", "Current Agent session must own the task run", status=409)
|
"SESSION_MISMATCH", "Current Agent session must own the task run", status=409)
|
||||||
self._require_active_run_lease(active_run, self._now())
|
self._require_active_run_lease(active_run, self._now())
|
||||||
pending = [
|
pending = [
|
||||||
item for item in await self.repo.list_access_requests(str(task_id))
|
item for item in await self._list_access_requests(task_id)
|
||||||
if item["status"] == "pending"
|
if item["status"] == "pending"
|
||||||
]
|
]
|
||||||
require(
|
require(
|
||||||
@@ -721,7 +723,7 @@ class OperationalTaskService:
|
|||||||
if command.plan.schema_name == "execution-plan@2":
|
if command.plan.schema_name == "execution-plan@2":
|
||||||
requests = {
|
requests = {
|
||||||
row["access_request_id"]: TaskAccessRequest.model_validate(row)
|
row["access_request_id"]: TaskAccessRequest.model_validate(row)
|
||||||
for row in await self.repo.list_access_requests(str(task_id))
|
for row in await self._list_access_requests(task_id)
|
||||||
}
|
}
|
||||||
for node in command.plan.nodes:
|
for node in command.plan.nodes:
|
||||||
if node.kind == "gate":
|
if node.kind == "gate":
|
||||||
@@ -1357,16 +1359,15 @@ class OperationalTaskService:
|
|||||||
now=now,
|
now=now,
|
||||||
reason="external_source_withdrawn",
|
reason="external_source_withdrawn",
|
||||||
)
|
)
|
||||||
if hasattr(self.repo, "list_access_requests"):
|
for access_request in await self._list_access_requests(task_id):
|
||||||
for access_request in await self.repo.list_access_requests(str(task_id)):
|
await self._resolve_notifications(
|
||||||
await self._resolve_notifications(
|
task_id,
|
||||||
task_id,
|
kinds=["access_approval_pending"],
|
||||||
kinds=["access_approval_pending"],
|
subject_type="access_request",
|
||||||
subject_type="access_request",
|
subject_id=UUID(str(access_request["access_request_id"])),
|
||||||
subject_id=UUID(str(access_request["access_request_id"])),
|
now=now,
|
||||||
now=now,
|
reason="external_source_withdrawn",
|
||||||
reason="external_source_withdrawn",
|
)
|
||||||
)
|
|
||||||
await self._resolve_notifications(
|
await self._resolve_notifications(
|
||||||
task_id,
|
task_id,
|
||||||
kinds=["human_input_required", "run_delivery_degraded", "task_failed"],
|
kinds=["human_input_required", "run_delivery_degraded", "task_failed"],
|
||||||
@@ -1667,7 +1668,7 @@ class OperationalTaskService:
|
|||||||
]
|
]
|
||||||
access_requests = [
|
access_requests = [
|
||||||
TaskAccessRequest.model_validate(item)
|
TaskAccessRequest.model_validate(item)
|
||||||
for item in await self.repo.list_access_requests(str(task_id))
|
for item in await self._list_access_requests(task_id)
|
||||||
]
|
]
|
||||||
lifecycle = self._status_from_plan(
|
lifecycle = self._status_from_plan(
|
||||||
plan.plan.nodes, actions, access_requests
|
plan.plan.nodes, actions, access_requests
|
||||||
@@ -1712,10 +1713,7 @@ class OperationalTaskService:
|
|||||||
)
|
)
|
||||||
pending_access = any(
|
pending_access = any(
|
||||||
request.get("status") == "pending"
|
request.get("status") == "pending"
|
||||||
for request in (
|
for request in await self._list_access_requests(task_id)
|
||||||
await self.repo.list_access_requests(str(task_id))
|
|
||||||
if hasattr(self.repo, "list_access_requests") else []
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
if not pending_actions and not pending_access:
|
if not pending_actions and not pending_access:
|
||||||
await self._notify(
|
await self._notify(
|
||||||
|
|||||||
Reference in New Issue
Block a user