From 261252abdd2dbb7662823c1999f411827e699088 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Date: Sat, 16 May 2026 01:28:01 -0400 Subject: [PATCH] fix: resolve group XML IDs via ir.model.data in access check AGENT_ACCESS_GROUPS uses XML IDs (e.g. hr_expense.group_hr_expense_user) but the check compared them against res.groups.full_name strings which never matched, denying every user access to all restricted agents. Co-Authored-By: Claude Sonnet 4.6 --- agent_service/agents/master_agent.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/agent_service/agents/master_agent.py b/agent_service/agents/master_agent.py index fe77939..936ad19 100644 --- a/agent_service/agents/master_agent.py +++ b/agent_service/agents/master_agent.py @@ -185,16 +185,24 @@ class MasterAgent: denied = [] try: user_data = await self._odoo.call('res.users', 'read', [[user_id]], {'fields': ['groups_id']}) - group_ids = user_data[0].get('groups_id', []) if user_data else [] - group_rows = await self._odoo.search_read('res.groups', [['id', 'in', group_ids]], ['full_name']) - user_group_names = {r['full_name'] for r in group_rows} + user_group_ids = set(user_data[0].get('groups_id', [])) if user_data else set() except Exception as exc: logger.warning('Access check failed, permitting: %s', exc) return AccessResult(allowed=True) for agent_key in agents: - required = AGENT_ACCESS_GROUPS.get(agent_key) - if required and required not in user_group_names: - denied.append(agent_key) + required_xml_id = AGENT_ACCESS_GROUPS.get(agent_key) + if not required_xml_id: + continue + try: + module, name = required_xml_id.split('.', 1) + imd = await self._odoo.search_read( + 'ir.model.data', + [['module', '=', module], ['name', '=', name], ['model', '=', 'res.groups']], + ['res_id']) + if not imd or imd[0]['res_id'] not in user_group_ids: + denied.append(agent_key) + except Exception as exc: + logger.warning('Group lookup failed for %s, permitting: %s', required_xml_id, exc) if denied: return AccessResult(allowed=False, denied_agents=denied) return AccessResult(allowed=True)