security: fullstack hardening — task ownership, mapping validation, API-key scoping, test fixes

Backend:
- Add validate_mapping_database_ownership() to verify source/target UUIDs
  belong to declared environments before persisting mappings (mappings.py)
- Add API-key environment scoping to get_mappings (filter) and
  suggest_mappings_api (enforce) (mappings.py)
- Add user_id Column to TaskRecord model + Alembic migration (task.py)
- Persist task.user_id on save, restore on load (persistence.py)
- Wire current_user.id into migrate_dashboards + backup_dashboards
  task creation (_action_routes.py)
- Fix test_migration_routes.py: module-level patch leak → autouse fixture,
  SupersetClient→AsyncSupersetClient, AsyncMock for sync_environment/run
- Fix 7 Pydantic serializer warnings: 'PENDING'→TaskStatus.PENDING
  in test_tasks.py + import TaskStatus

Frontend:
- Deepen isDryRunResult(): validate selection field, risk.items entries
  (all 5 fields), and diff object uuids individually (ExecutorModel.svelte.ts)

Prior work included: task password redaction, resume ownership checks,
canonical dry-run DTO alignment, migration UI callback fixes, credential
exposure reduction, assistant dry-run await fix.
This commit is contained in:
2026-07-15 23:02:23 +03:00
parent 30c8acf7ae
commit 20071b8c7a
68 changed files with 3845 additions and 376 deletions

View File

@@ -429,7 +429,7 @@ class TestMigrationPluginExecute:
mock_task_manager.get_task.return_value = MagicMock(
params={"passwords": {"PostgreSQL": "secret123"}}
)
mock_task_manager.await_input = MagicMock()
mock_task_manager.await_input = AsyncMock()
mock_task_manager.wait_for_input = AsyncMock()
mock_src_client = _make_mock_superset_client()
@@ -716,7 +716,7 @@ class TestMigrationPluginExecute:
mock_task_manager.get_task.return_value = MagicMock(
params={"passwords": {"PostgreSQL": "secret123"}}
)
mock_task_manager.await_input = MagicMock()
mock_task_manager.await_input = AsyncMock()
mock_task_manager.wait_for_input = AsyncMock()
mock_src_client = _make_mock_superset_client()