commit
2fa180a9ae
3 changed files with 122 additions and 28 deletions
|
|
@ -42,11 +42,19 @@ class ChatAccess:
|
||||||
|
|
||||||
# Apply filtering based on privilege
|
# Apply filtering based on privilege
|
||||||
if table_name == "AutomationDefinition":
|
if table_name == "AutomationDefinition":
|
||||||
# Users see only their own automation definitions
|
# Filter automations based on user privilege
|
||||||
filtered_records = [
|
if userPrivilege == UserPrivilege.SYSADMIN:
|
||||||
r for r in recordset
|
# System admins see all automations
|
||||||
if r.get("mandateId","-") == self.mandateId and r.get("_createdBy") == self.userId
|
filtered_records = recordset
|
||||||
]
|
elif userPrivilege == UserPrivilege.ADMIN:
|
||||||
|
# Admins see all automations in their mandate
|
||||||
|
filtered_records = [r for r in recordset if r.get("mandateId","-") == self.mandateId]
|
||||||
|
else:
|
||||||
|
# Regular users see only their own automations
|
||||||
|
filtered_records = [
|
||||||
|
r for r in recordset
|
||||||
|
if r.get("mandateId","-") == self.mandateId and r.get("_createdBy") == self.userId
|
||||||
|
]
|
||||||
elif userPrivilege == UserPrivilege.SYSADMIN:
|
elif userPrivilege == UserPrivilege.SYSADMIN:
|
||||||
filtered_records = recordset # System admins see all records
|
filtered_records = recordset # System admins see all records
|
||||||
elif userPrivilege == UserPrivilege.ADMIN:
|
elif userPrivilege == UserPrivilege.ADMIN:
|
||||||
|
|
|
||||||
|
|
@ -185,14 +185,26 @@ class ChatObjects:
|
||||||
# First apply access control
|
# First apply access control
|
||||||
filteredRecords = self.access.uam(model_class, recordset)
|
filteredRecords = self.access.uam(model_class, recordset)
|
||||||
|
|
||||||
# Then filter out database-specific fields
|
# For AutomationDefinition, keep _createdBy and mandateId for enrichment purposes
|
||||||
cleanedRecords = []
|
# Other fields starting with _ are filtered out as they're database-specific
|
||||||
for record in filteredRecords:
|
if model_class.__name__ == "AutomationDefinition":
|
||||||
# Create a new dict with only non-database fields
|
# Keep _createdBy and mandateId for enrichment, filter out other _ fields
|
||||||
cleanedRecord = {k: v for k, v in record.items() if not k.startswith('_')}
|
cleanedRecords = []
|
||||||
cleanedRecords.append(cleanedRecord)
|
for record in filteredRecords:
|
||||||
|
cleanedRecord = {}
|
||||||
return cleanedRecords
|
for k, v in record.items():
|
||||||
|
# Keep _createdBy and mandateId, filter out other _ fields
|
||||||
|
if k == "_createdBy" or k == "mandateId" or not k.startswith('_'):
|
||||||
|
cleanedRecord[k] = v
|
||||||
|
cleanedRecords.append(cleanedRecord)
|
||||||
|
return cleanedRecords
|
||||||
|
else:
|
||||||
|
# For other models, filter out all database-specific fields
|
||||||
|
cleanedRecords = []
|
||||||
|
for record in filteredRecords:
|
||||||
|
cleanedRecord = {k: v for k, v in record.items() if not k.startswith('_')}
|
||||||
|
cleanedRecords.append(cleanedRecord)
|
||||||
|
return cleanedRecords
|
||||||
|
|
||||||
def _canModify(self, model_class: type, recordId: Optional[str] = None) -> bool:
|
def _canModify(self, model_class: type, recordId: Optional[str] = None) -> bool:
|
||||||
"""Delegate to access control module."""
|
"""Delegate to access control module."""
|
||||||
|
|
@ -1221,6 +1233,69 @@ class ChatObjects:
|
||||||
eventId = automation.get("eventId")
|
eventId = automation.get("eventId")
|
||||||
return "Running" if eventId else "Idle"
|
return "Running" if eventId else "Idle"
|
||||||
|
|
||||||
|
def _enrichAutomationsWithUserAndMandate(self, automations: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Batch enrich automations with user names and mandate names for display.
|
||||||
|
Uses AppObjects interface to fetch users and mandates with proper access control.
|
||||||
|
"""
|
||||||
|
if not automations:
|
||||||
|
return automations
|
||||||
|
|
||||||
|
from modules.interfaces.interfaceDbAppObjects import getInterface as getAppInterface
|
||||||
|
|
||||||
|
# Collect all unique user IDs and mandate IDs
|
||||||
|
userIds = set()
|
||||||
|
mandateIds = set()
|
||||||
|
|
||||||
|
for automation in automations:
|
||||||
|
createdBy = automation.get("_createdBy")
|
||||||
|
if createdBy:
|
||||||
|
userIds.add(createdBy)
|
||||||
|
|
||||||
|
mandateId = automation.get("mandateId")
|
||||||
|
if mandateId:
|
||||||
|
mandateIds.add(mandateId)
|
||||||
|
|
||||||
|
# Use AppObjects interface to fetch users (respects access control)
|
||||||
|
appInterface = getAppInterface(self.currentUser)
|
||||||
|
usersMap = {}
|
||||||
|
if userIds:
|
||||||
|
for user_id in userIds:
|
||||||
|
user = appInterface.getUser(user_id)
|
||||||
|
if user:
|
||||||
|
usersMap[user_id] = user.username or user.email or user_id
|
||||||
|
|
||||||
|
# Use AppObjects interface to fetch mandates (respects access control)
|
||||||
|
mandatesMap = {}
|
||||||
|
if mandateIds:
|
||||||
|
for mandate_id in mandateIds:
|
||||||
|
mandate = appInterface.getMandate(mandate_id)
|
||||||
|
if mandate:
|
||||||
|
mandatesMap[mandate_id] = mandate.name or mandate_id
|
||||||
|
|
||||||
|
# Enrich each automation with the fetched data
|
||||||
|
for automation in automations:
|
||||||
|
createdBy = automation.get("_createdBy")
|
||||||
|
if createdBy:
|
||||||
|
automation["_createdByUserName"] = usersMap.get(createdBy, createdBy)
|
||||||
|
else:
|
||||||
|
automation["_createdByUserName"] = "-"
|
||||||
|
|
||||||
|
mandateId = automation.get("mandateId")
|
||||||
|
if mandateId:
|
||||||
|
automation["mandateName"] = mandatesMap.get(mandateId, mandateId)
|
||||||
|
else:
|
||||||
|
automation["mandateName"] = "-"
|
||||||
|
|
||||||
|
return automations
|
||||||
|
|
||||||
|
def _enrichAutomationWithUserAndMandate(self, automation: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Enrich a single automation with user name and mandate name for display.
|
||||||
|
For multiple automations, use _enrichAutomationsWithUserAndMandate for better performance.
|
||||||
|
"""
|
||||||
|
return self._enrichAutomationsWithUserAndMandate([automation])[0]
|
||||||
|
|
||||||
def getAllAutomationDefinitions(self, pagination: Optional[PaginationParams] = None) -> Union[List[Dict[str, Any]], PaginatedResult]:
|
def getAllAutomationDefinitions(self, pagination: Optional[PaginationParams] = None) -> Union[List[Dict[str, Any]], PaginatedResult]:
|
||||||
"""
|
"""
|
||||||
Returns automation definitions based on user access level.
|
Returns automation definitions based on user access level.
|
||||||
|
|
@ -1237,6 +1312,9 @@ class ChatObjects:
|
||||||
if automation.get("executionLogs") is None:
|
if automation.get("executionLogs") is None:
|
||||||
automation["executionLogs"] = []
|
automation["executionLogs"] = []
|
||||||
|
|
||||||
|
# Batch enrich with user and mandate names
|
||||||
|
self._enrichAutomationsWithUserAndMandate(filteredAutomations)
|
||||||
|
|
||||||
# If no pagination requested, return all items
|
# If no pagination requested, return all items
|
||||||
if pagination is None:
|
if pagination is None:
|
||||||
return filteredAutomations
|
return filteredAutomations
|
||||||
|
|
@ -1278,6 +1356,8 @@ class ChatObjects:
|
||||||
# Ensure executionLogs is always a list, not None
|
# Ensure executionLogs is always a list, not None
|
||||||
if automation.get("executionLogs") is None:
|
if automation.get("executionLogs") is None:
|
||||||
automation["executionLogs"] = []
|
automation["executionLogs"] = []
|
||||||
|
# Enrich with user and mandate names
|
||||||
|
self._enrichAutomationWithUserAndMandate(automation)
|
||||||
return automation
|
return automation
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error getting automation definition: {str(e)}")
|
logger.error(f"Error getting automation definition: {str(e)}")
|
||||||
|
|
|
||||||
|
|
@ -66,23 +66,29 @@ async def get_automations(
|
||||||
|
|
||||||
# If pagination was requested, result is PaginatedResult
|
# If pagination was requested, result is PaginatedResult
|
||||||
# If no pagination, result is List[Dict]
|
# If no pagination, result is List[Dict]
|
||||||
|
# Note: Using JSONResponse to bypass Pydantic validation which would filter out _createdBy
|
||||||
|
# The enriched fields (_createdByUserName, mandateName) are not in the Pydantic model
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
if paginationParams:
|
if paginationParams:
|
||||||
return PaginatedResponse(
|
response_data = {
|
||||||
items=result.items,
|
"items": result.items,
|
||||||
pagination=PaginationMetadata(
|
"pagination": {
|
||||||
currentPage=paginationParams.page,
|
"currentPage": paginationParams.page,
|
||||||
pageSize=paginationParams.pageSize,
|
"pageSize": paginationParams.pageSize,
|
||||||
totalItems=result.totalItems,
|
"totalItems": result.totalItems,
|
||||||
totalPages=result.totalPages,
|
"totalPages": result.totalPages,
|
||||||
sort=paginationParams.sort,
|
"sort": paginationParams.sort,
|
||||||
filters=paginationParams.filters
|
"filters": paginationParams.filters
|
||||||
)
|
}
|
||||||
)
|
}
|
||||||
else:
|
else:
|
||||||
return PaginatedResponse(
|
response_data = {
|
||||||
items=result,
|
"items": result,
|
||||||
pagination=None
|
"pagination": None
|
||||||
)
|
}
|
||||||
|
|
||||||
|
return JSONResponse(content=response_data)
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue