This PRD details the modifications required for the `get_collection_handler` to incorporate granular permission checks for each asset (Metric, Dashboard, etc.) contained within a collection. It introduces a `has_access` flag to the `CollectionAsset` type to indicate whether the requesting user has permission to view the specific asset.
**Note on Concurrency:** This work depends on the completion of the [Refactor Sharing Permission Helper](mdc:prds/active/refactor_sharing_permission_helper.md). Once the helper is available, this task can potentially be performed concurrently with the enhancements for the dashboard and data execution handlers.
The current `get_collection_handler` lists assets associated with a collection but doesn't verify the user's permission for each *individual* asset. This can lead to users seeing assets in the list that they cannot actually access, creating a confusing user experience.
## 3. Goals
- Modify `get_collection_handler` to check permissions for each contained asset using the `check_specific_asset_access` helper.
- Add a `has_access: bool` field to the `CollectionAsset` struct in `libs/handlers/src/collections/types.rs`.
- Populate the `has_access` field based on the permission check result for each asset.
- Ensure the API response includes all associated assets, clearly marking accessible vs. inaccessible ones.
## 4. Non-Goals
- Changing the permission check logic for the collection itself.
- Modifying how assets are associated with collections.
- Implementing checks for asset types not currently queried (e.g., Chats).
## 5. Technical Design
1.**Type Modification:**
- Add `has_access: bool` to `CollectionAsset` struct:
-**Fetch Assets:** Continue fetching associated metric and dashboard assets as currently done (results in `Vec<AssetQueryResult>`). Add `organization_id` from the joined `metric_files` or `dashboard_files` table to the `AssetQueryResult` struct if not already present.
```rust
// Define or modify AssetQueryResult
#[derive(Queryable, Clone, Debug)]
struct AssetQueryResult {
id: Uuid,
name: String,
user_name: Option<String>,
email: Option<String>,
created_at: DateTime<Utc>,
updated_at: DateTime<Utc>,
asset_type: AssetType,
organization_id: Uuid, // Ensure this is selected
}
```
-**Check Permissions:** After fetching `all_assets: Vec<AssetQueryResult>`, iterate through them. For each `asset_result`:
- Call `sharing::check_specific_asset_access` with the user context, asset details (`asset_result.id`, `asset_result.asset_type`, `asset_result.organization_id`), and required roles (e.g., `&[AssetPermissionRole::CanView]`).
- Store the boolean result (true/false) alongside the asset data. Handle potential `Err` results from the check (log and treat as `has_access: false` or filter out as per project decision).
```rust
// Example logic within get_collection_handler
let mut assets_with_access: Vec<(AssetQueryResult, bool)> = Vec::new();
for asset_result in all_assets {
let required_roles = [AssetPermissionRole::CanView]; // Minimum role needed
let check_result = sharing::check_specific_asset_access(
-**Format Response:** Modify `format_assets` (or create a new formatting step) to accept the `Vec<(AssetQueryResult, bool)>` and populate the `CollectionAsset` including the `has_access` field.
2. Update database queries in `get_collection_handler` to select `organization_id` for assets.
3. Integrate the call to `check_specific_asset_access` for each asset.
4. Update the asset formatting logic to include the `has_access` flag.
5. Add/update integration tests.
## 7. Testing Strategy
-**Unit Tests:** Not directly applicable to the handler itself, focus on integration tests. Test modifications to `format_assets` logic if separated.
-**Integration Tests:**
- Setup: User, Collection, Metric A (user has CanView), Dashboard B (user has no permission), Metric C (doesn't exist).
- Execute `get_collection_handler`.
- Verify:
- Response status is OK.
-`collection_state.assets` contains representations for Metric A and Dashboard B.
- Metric A has `has_access: true`.
- Dashboard B has `has_access: false`.
- Metric C is not present.
- Basic details (id, name, type) are present for both A and B.
- Test variations with different user roles (Owner, Org Admin, Member, No Access).
- Test scenario where `check_specific_asset_access` returns an `Err` (e.g., simulate DB failure during check) -> Verify asset is omitted or marked inaccessible based on error handling decision.
## 8. Rollback Plan
- Revert changes to the handler and types files.
## 9. Dependencies
- Completion of [Refactor Sharing Permission Helper](mdc:prds/active/refactor_sharing_permission_helper.md).