Seguridad y Control de Accesos en Odoo
En Odoo 20, los accesos se representan mediante ir.access. Un registro con grupo concede operaciones sobre el dominio indicado; uno sin grupo añade una restricción global. No confundas esta semántica con las ACL y reglas separadas de versiones anteriores.
1. Grupos y privilegios #
Crea el siguiente archivo y colócalo antes de security/ir.access.csv en el manifiesto:
Fichero security/groups.xml:
1<odoo> 2 <record id="privilege_library" model="res.groups.privilege"> 3 <field name="name">Biblioteca</field> 4 <field name="category_id" ref="base.module_category_services"/> 5 </record> 6 <record id="group_library_user" model="res.groups"> 7 <field name="name">Lector</field> 8 <field name="privilege_id" ref="privilege_library"/> 9 <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/> 10 </record> 11 <record id="group_library_manager" model="res.groups"> 12 <field name="name">Responsable</field> 13 <field name="privilege_id" ref="privilege_library"/> 14 <field name="implied_ids" eval="[(4, ref('group_library_user'))]"/> 15 <field name="user_ids" eval="[(4, ref('base.user_admin'))]"/> 16 </record> 17</odoo>
2. Accesos con operaciones y dominios #
Sustituye el CSV inicial por este contenido completo. Reutilizamos sus identificadores para actualizar los permisos existentes, evitando dejar concesiones antiguas activas:
Fichero security/ir.access.csv:
1id,name,model_id,group_id/id,operation,domain 2access_library_book_user,Read books,library.book,group_library_user,r, 3access_library_tag_user,Read tags,library.tag,group_library_user,r, 4access_library_loan_user,Manage loans,library.loan,group_library_user,cru, 5access_library_book_manager,Manage books,library.book,group_library_manager,crud, 6access_library_tag_manager,Manage tags,library.tag,group_library_manager,crud, 7access_library_loan_manager,Manage all loans,library.loan,group_library_manager,crud, 8library_book_company,Book company restriction,library.book,,crud,"[('company_id', 'in', company_ids)]" 9library_loan_company,Loan company restriction,library.loan,,crud,"[('company_id', 'in', company_ids)]"
Las columnas son id, name, model_id (nombre técnico del modelo), group_id/id (ID externo del grupo), operation y domain. Las operaciones son c crear, r leer, u modificar y d borrar; se combinan, por ejemplo cru.
Los permisos aplicables de los grupos se combinan con OR; las restricciones globales, con AND. Un grupo vacío no concede acceso en Odoo 20. Se necesita alguna concesión de grupo y cumplir las restricciones globales. El grupo base.group_user representa usuarios internos; público y portal no reciben los permisos de estos grupos. Asigna el rol de biblioteca desde Ajustes para probar con usuarios normales.
Una restricción multiempresa debe usar campos definidos realmente en el modelo. En biblioteca, company_id ya existe y los préstamos lo heredan del libro. El responsable tampoco evita una restricción global; el modo superusuario sí omite las comprobaciones de acceso y no sirve para comprobar el aislamiento.
3. Diferencias con versiones anteriores #
En Odoo 16–19 se usaban ir.model.access.csv y ir.rule, con otra semántica para grupos vacíos. Es información histórica: no copies esos archivos en este curso. Consulta el modelo de accesos de Odoo 20 y el CSV oficial.
Prueba con lector, responsable, usuario interno sin rol, portal y público. Comprueba también dos compañías; tener un menú visible no concede acceso a sus datos.