details:   https://code.tryton.org/tryton/commit/22897711abb0
branch:    default
user:      Cédric Krier <[email protected]>
date:      Thu Nov 05 16:02:45 2026 +0100
description:
        Only permit administrators to execute wizards without models or groups

        Closes #15205
diffstat:

 trytond/CHANGELOG                    |   1 +
 trytond/trytond/tests/test_wizard.py |  41 ++++++++++++++++++++++++++++++++++++
 trytond/trytond/tests/wizard.py      |   5 ++++
 trytond/trytond/tests/wizard.xml     |   6 +++++
 trytond/trytond/wizard/wizard.py     |   8 ++++++-
 5 files changed, 60 insertions(+), 1 deletions(-)

diffs (115 lines):

diff -r 6c39c9437f47 -r 22897711abb0 trytond/CHANGELOG
--- a/trytond/CHANGELOG Wed Oct 21 12:36:12 2026 +0200
+++ b/trytond/CHANGELOG Thu Nov 05 16:02:45 2026 +0100
@@ -1,3 +1,4 @@
+* Only permit administrators to execute wizards without models or groups 
(issue15205)
 
 Version 8.2.0 - 2026-10-05
 --------------------------
diff -r 6c39c9437f47 -r 22897711abb0 trytond/trytond/tests/test_wizard.py
--- a/trytond/trytond/tests/test_wizard.py      Wed Oct 21 12:36:12 2026 +0200
+++ b/trytond/trytond/tests/test_wizard.py      Thu Nov 05 16:02:45 2026 +0100
@@ -204,3 +204,44 @@
                 with Transaction().set_context(
                         active_model='test.test_wizard.start'):
                     Wizard.execute(session_id, {}, start_state)
+
+    @with_transaction(context={'_check_access': True})
+    def test_execute_without_model(self):
+        "Execute wizard without model"
+        pool = Pool()
+        Wizard = pool.get('test.test_wizard_no_model', type='wizard')
+        User = pool.get('res.user')
+
+        user = User(login='foo')
+        user.save()
+        session_id, start_state, end_state = Wizard.create()
+
+        with Transaction().set_user(user.id):
+            with self.assertRaises(AccessError):
+                Wizard.execute(session_id, {}, start_state)
+
+    @with_transaction(context={'_check_access': True})
+    def test_execute_without_model_with_group(self):
+        "Execute wizard without model and groups"
+        pool = Pool()
+        Wizard = pool.get('test.test_wizard_no_model', type='wizard')
+        User = pool.get('res.user')
+        Group = pool.get('res.group')
+
+        user = User(login='foo', groups=[Group(name="Group")])
+        user.save()
+        session_id, start_state, end_state = Wizard.create()
+
+        with Transaction().set_user(user.id):
+            with self.assertRaises(AccessError):
+                Wizard.execute(session_id, {}, start_state)
+
+    @with_transaction(context={'_check_access': True})
+    def test_execute_without_model_with_admin(self):
+        "Execute wizard without model"
+        pool = Pool()
+        Wizard = pool.get('test.test_wizard_no_model', type='wizard')
+
+        session_id, start_state, end_state = Wizard.create()
+
+        Wizard.execute(session_id, {}, start_state)
diff -r 6c39c9437f47 -r 22897711abb0 trytond/trytond/tests/wizard.py
--- a/trytond/trytond/tests/wizard.py   Wed Oct 21 12:36:12 2026 +0200
+++ b/trytond/trytond/tests/wizard.py   Thu Nov 05 16:02:45 2026 +0100
@@ -47,10 +47,15 @@
         return 'end'
 
 
+class TestWizardNoModel(TestWizard):
+    __name__ = 'test.test_wizard_no_model'
+
+
 def register(module):
     Pool.register(
         TestWizardStart,
         module=module, type_='model')
     Pool.register(
         TestWizard,
+        TestWizardNoModel,
         module=module, type_='wizard')
diff -r 6c39c9437f47 -r 22897711abb0 trytond/trytond/tests/wizard.xml
--- a/trytond/trytond/tests/wizard.xml  Wed Oct 21 12:36:12 2026 +0200
+++ b/trytond/trytond/tests/wizard.xml  Thu Nov 05 16:02:45 2026 +0100
@@ -21,5 +21,11 @@
             <field name="wiz_name">test.test_wizard</field>
             <field name="model">test.access</field>
         </record>
+
+        <record model="ir.action.wizard" id="test_wizard_no_model">
+            <field name="name">Test Wizard</field>
+            <field name="wiz_name">test.test_wizard_no_model</field>
+            <field name="model" eval="None"/>
+        </record>
     </data>
 </tryton>
diff -r 6c39c9437f47 -r 22897711abb0 trytond/trytond/wizard/wizard.py
--- a/trytond/trytond/wizard/wizard.py  Wed Oct 21 12:36:12 2026 +0200
+++ b/trytond/trytond/wizard/wizard.py  Thu Nov 05 16:02:45 2026 +0100
@@ -264,7 +264,7 @@
                     ModelAccess.check(model, 'read')
                 models = ActionWizard.get_models(
                     cls.__name__, action_id=context.get('action_id'))
-                if model and models and model not in models:
+                if models and (not model or model not in models):
                     groups = Group.browse(User.get_groups())
                     raise AccessError(
                         gettext(
@@ -294,6 +294,12 @@
                             ):
                         ModelAccess.check(model, 'write')
 
+                if not models and not wizard_groups:
+                    raise AccessError(
+                        gettext(
+                            'ir.msg_access_wizard_error',
+                            wizard=cls.__name__))
+
             if model:
                 ids = context.get('active_ids') or []
                 id_ = context.get('active_id')

Reply via email to