chore(refactor): Improve conversation permission filtering (#11166)

1. Add permission filter service to separate permission filtering logic
from conversation queries
2. Implement hierarchical permissions with cleaner logic:
   - conversation_manage gives access to all conversations
- conversation_unassigned_manage gives access to unassigned and user's
conversations
- conversation_participating_manage gives access only to user's
conversations

---------

Co-authored-by: Pranav <pranav@chatwoot.com>
This commit is contained in:
Sojan Jose
2025-03-31 19:30:02 -07:00
committed by GitHub
parent f20a18b03f
commit ca83a27e95
12 changed files with 759 additions and 260 deletions

View File

@@ -0,0 +1,38 @@
module Enterprise::Conversations::PermissionFilterService
def perform
account_user = AccountUser.find_by(account_id: account.id, user_id: user.id)
permissions = account_user&.permissions || []
user_role = account_user&.role
# Skip filtering for administrators
return conversations if user_role == 'administrator'
# Skip filtering for regular agents (without custom roles/permissions)
return conversations if user_role == 'agent' && account_user&.custom_role_id.nil?
filter_by_permissions(permissions)
end
private
def filter_by_permissions(permissions)
# Permission-based filtering with hierarchy
# conversation_manage > conversation_unassigned_manage > conversation_participating_manage
if permissions.include?('conversation_manage')
conversations
elsif permissions.include?('conversation_unassigned_manage')
filter_unassigned_and_mine
elsif permissions.include?('conversation_participating_manage')
conversations.assigned_to(user)
else
Conversation.none
end
end
def filter_unassigned_and_mine
mine = conversations.assigned_to(user)
unassigned = conversations.unassigned
Conversation.from("(#{mine.to_sql} UNION #{unassigned.to_sql}) as conversations")
.where(account_id: account.id)
end
end