833
# Customer user - filter by accessible customers
834
alerts = await list_alerts_multiple_filters(
835
ioc_value=ioc_value,
836
- customer_code=accessible_customers[0] if len(accessible_customers) == 1 else None,
836
+ customer_codes=accessible_customers,
837
db=db,
838
page=page,
839
page_size=page_size,
886
tag: str,
887
page: int = Query(1, ge=1),
888
page_size: int = Query(25, ge=1),
889
+ customer_codes: Optional[List[str]] = Query(None, description="Optional subset of customer codes to scope the results to"),
890
current_user: User = Depends(AuthHandler().get_current_user),
891
db: AsyncSession = Depends(get_db),
892
):
893
"""List alerts by tag with customer access filtering"""
894
logger.info(f"Listing alerts by tag {tag} for user: {current_user.username} with role_id: {current_user.role_id}")
895
895
- # Get customer access filtering
896
- accessible_customers = await customer_access_handler.get_user_accessible_customers(current_user, db)
896
+ # Get customer access filtering (optionally narrowed to a requested subset)
897
+ accessible_customers = await customer_access_handler.resolve_effective_customers(current_user, customer_codes, db)
898
899
if "*" in accessible_customers:
900
# Admin/analyst - no filtering needed
907
# Customer user - filter by accessible customers
908
alerts = await list_alerts_multiple_filters(
909
tags=[tag],
909
- customer_code=accessible_customers[0] if len(accessible_customers) == 1 else None,
910
+ customer_codes=accessible_customers,
911
db=db,
912
page=page,
913
page_size=page_size,
1404
page: int = Query(1, ge=1),
1405
page_size: int = Query(25, ge=1),
1406
order: str = Query("desc", pattern="^(asc|desc)$"),
1407
+ customer_codes: Optional[List[str]] = Query(None, description="Optional subset of customer codes to scope the results to"),
1408
current_user: User = Depends(AuthHandler().get_current_user),
1409
db: AsyncSession = Depends(get_db),
1410
):
1414
1415
logger.info(f"Listing alerts by status {status} for user: {current_user.username} with role_id: {current_user.role_id}")
1416
1415
- # Get customer access filtering
1416
- accessible_customers = await customer_access_handler.get_user_accessible_customers(current_user, db)
1417
+ # Get customer access filtering (optionally narrowed to a requested subset)
1418
+ accessible_customers = await customer_access_handler.resolve_effective_customers(current_user, customer_codes, db)
1419
1420
if "*" in accessible_customers:
1421
# Admin/analyst - no filtering needed
1430
# For now, let's use the multiple filters function with customer codes
1431
alerts = await list_alerts_multiple_filters(
1432
status=status.value,
1431
- customer_code=accessible_customers[0] if len(accessible_customers) == 1 else None,
1433
+ customer_codes=accessible_customers,
1434
db=db,
1435
page=page,
1436
page_size=page_size,
1482
# Customer user - filter by accessible customers
1483
alerts = await list_alerts_multiple_filters(
1484
assigned_to=assigned_to,
1483
- customer_code=accessible_customers[0] if len(accessible_customers) == 1 else None,
1485
+ customer_codes=accessible_customers,
1486
db=db,
1487
page=page,
1488
page_size=page_size,
1514
page: int = Query(1, ge=1),
1515
page_size: int = Query(25, ge=1),
1516
order: str = Query("desc", pattern="^(asc|desc)$"),
1517
+ customer_codes: Optional[List[str]] = Query(None, description="Optional subset of customer codes to scope the results to"),
1518
current_user: User = Depends(AuthHandler().get_current_user),
1519
db: AsyncSession = Depends(get_db),
1520
):
1521
"""List alerts by asset name with customer access filtering"""
1522
logger.info(f"Listing alerts by asset {asset_name} for user: {current_user.username} with role_id: {current_user.role_id}")
1523
1521
- # Get customer access filtering
1522
- accessible_customers = await customer_access_handler.get_user_accessible_customers(current_user, db)
1524
+ # Get customer access filtering (optionally narrowed to a requested subset)
1525
+ accessible_customers = await customer_access_handler.resolve_effective_customers(current_user, customer_codes, db)
1526
1527
if "*" in accessible_customers:
1528
# Admin/analyst - no filtering needed
1535
# Customer user - filter by accessible customers
1536
alerts = await list_alerts_multiple_filters(
1537
asset_name=asset_name,
1535
- customer_code=accessible_customers[0] if len(accessible_customers) == 1 else None,
1538
+ customer_codes=accessible_customers,
1539
db=db,
1540
page=page,
1541
page_size=page_size,
1587
# Customer user - filter by accessible customers
1588
alerts = await list_alerts_multiple_filters(
1589
alert_title=title,
1587
- customer_code=accessible_customers[0] if len(accessible_customers) == 1 else None,
1590
+ customer_codes=accessible_customers,
1591
db=db,
1592
page=page,
1593
page_size=page_size,
1648
page: int = Query(1, ge=1),
1649
page_size: int = Query(25, ge=1),
1650
order: str = Query("desc", pattern="^(asc|desc)$"),
1651
+ customer_codes: Optional[List[str]] = Query(None, description="Optional subset of customer codes to scope the results to"),
1652
current_user: User = Depends(AuthHandler().get_current_user),
1653
db: AsyncSession = Depends(get_db),
1654
):
1655
"""List alerts by source with customer access filtering"""
1656
logger.info(f"Listing alerts by source {source} for user: {current_user.username} with role_id: {current_user.role_id}")
1657
1654
- # Get customer access filtering
1655
- accessible_customers = await customer_access_handler.get_user_accessible_customers(current_user, db)
1658
+ # Get customer access filtering (optionally narrowed to a requested subset)
1659
+ accessible_customers = await customer_access_handler.resolve_effective_customers(current_user, customer_codes, db)
1660
1661
if "*" in accessible_customers:
1662
# Admin/analyst - no filtering needed
1669
# Customer user - filter by accessible customers
1670
alerts = await list_alerts_multiple_filters(
1671
source=source,
1668
- customer_code=accessible_customers[0] if len(accessible_customers) == 1 else None,
1672
+ customer_codes=accessible_customers,
1673
db=db,
1674
page=page,
1675
page_size=page_size,
1743
page=page,
1744
page_size=page_size,
1745
order=order,
1746
+ # Constrain scoped users to their accessible customers (prevents cross-tenant
1747
+ # disclosure when the user has >1 customer and no explicit customer_code).
1748
+ customer_codes=None if "*" in accessible_customers else accessible_customers,
1749
user=current_user, # Pass user for tag filtering
1750
)
1751
2141
page: int = Query(1, ge=1),
2142
page_size: int = Query(25, ge=1),
2143
order: str = Query("desc", pattern="^(asc|desc)$"),
2144
+ customer_codes: Optional[List[str]] = Query(None, description="Optional subset of customer codes to scope the results to"),
2145
current_user: User = Depends(AuthHandler().get_current_user),
2146
db: AsyncSession = Depends(get_db),
2147
):
2159
cases = await list_cases_by_status(status.value, db, page=page, page_size=page_size, order=order)
2160
else:
2161
# Customer user - get paginated cases and filter by status
2154
- all_user_cases = await list_cases_for_user(current_user, db, page, page_size, order)
2162
+ all_user_cases = await list_cases_for_user(current_user, db, page, page_size, order, customer_codes=customer_codes)
2163
cases = [case for case in all_user_cases if case.case_status == status.value]
2164
2157
- total = await case_total_for_user(current_user, db)
2158
- open_cases = await cases_open_for_user(current_user, db)
2159
- in_progress = await cases_in_progress_for_user(current_user, db)
2160
- closed = await cases_closed_for_user(current_user, db)
2165
+ total = await case_total_for_user(current_user, db, customer_codes=customer_codes)
2166
+ open_cases = await cases_open_for_user(current_user, db, customer_codes=customer_codes)
2167
+ in_progress = await cases_in_progress_for_user(current_user, db, customer_codes=customer_codes)
2168
+ closed = await cases_closed_for_user(current_user, db, customer_codes=customer_codes)
2169
2170
return CaseOutResponse(
2171
cases=cases,
2185
)
2186
async def list_cases_by_assigned_to_endpoint(
2187
assigned_to: str,
2188
+ customer_codes: Optional[List[str]] = Query(None, description="Optional subset of customer codes to scope the results to"),
2189
current_user: User = Depends(AuthHandler().get_current_user),
2190
db: AsyncSession = Depends(get_db),
2191
):
2200
cases = await list_cases_by_assigned_to(assigned_to, db)
2201
else:
2202
# Customer user - filter by accessible customers
2194
- all_user_cases = await list_cases_for_user(current_user, db)
2203
+ all_user_cases = await list_cases_for_user(current_user, db, customer_codes=customer_codes)
2204
cases = [case for case in all_user_cases if case.assigned_to == assigned_to]
2205
2206
return CaseOutResponse(cases=cases, success=True, message="Cases retrieved successfully")