details: https://code.tryton.org/tryton/commit/2bad239629b3
branch: default
user: Cédric Krier <[email protected]>
date: Fri Oct 30 16:25:08 2026 +0100
description:
Restrict the wizard session to the user who created it
Closes #15206
diffstat:
trytond/CHANGELOG | 1 +
trytond/trytond/tests/test_wizard.py | 32 ++++++++++++++++++++++++++++++++
trytond/trytond/wizard/wizard.py | 16 +++++++++++++---
3 files changed, 46 insertions(+), 3 deletions(-)
diffs (97 lines):
diff -r 2e84ffa5c760 -r 2bad239629b3 trytond/CHANGELOG
--- a/trytond/CHANGELOG Fri Oct 30 15:49:54 2026 +0100
+++ b/trytond/CHANGELOG Fri Oct 30 16:25:08 2026 +0100
@@ -1,3 +1,4 @@
+* Restrict the wizard session to the user who created it (issue15206)
* Only permit administrators to execute wizards without models or groups
(issue15205)
Version 8.2.0 - 2026-10-05
diff -r 2e84ffa5c760 -r 2bad239629b3 trytond/trytond/tests/test_wizard.py
--- a/trytond/trytond/tests/test_wizard.py Fri Oct 30 15:49:54 2026 +0100
+++ b/trytond/trytond/tests/test_wizard.py Fri Oct 30 16:25:08 2026 +0100
@@ -31,6 +31,22 @@
Wizard.delete(session_id)
@with_transaction()
+ def test_delete_different_user(self):
+ "Delete session from a different user"
+ pool = Pool()
+ Wizard = pool.get('test.test_wizard', type='wizard')
+ User = pool.get('res.user')
+
+ user = User(login='foo')
+ user.save()
+
+ session_id, _, _ = Wizard.create()
+
+ with Transaction().set_user(user.id):
+ with self.assertRaises(AccessError):
+ Wizard.delete(session_id)
+
+ @with_transaction()
def test_session(self):
'Session Wizard'
pool = Pool()
@@ -90,6 +106,22 @@
session_id, start_state, end_state = Wizard.create()
@with_transaction()
+ def test_session_different_user(self):
+ "Use session from a different user"
+ pool = Pool()
+ Wizard = pool.get('test.test_wizard', type='wizard')
+ User = pool.get('res.user')
+
+ user = User(login='foo')
+ user.save()
+
+ session_id, _, _ = Wizard.create()
+
+ with Transaction().set_user(user.id):
+ with self.assertRaises(AccessError):
+ Wizard(session_id)
+
+ @with_transaction()
def test_execute(self):
'Execute Wizard'
pool = Pool()
diff -r 2e84ffa5c760 -r 2bad239629b3 trytond/trytond/wizard/wizard.py
--- a/trytond/trytond/wizard/wizard.py Fri Oct 30 15:49:54 2026 +0100
+++ b/trytond/trytond/wizard/wizard.py Fri Oct 30 16:25:08 2026 +0100
@@ -318,14 +318,20 @@
@classmethod
def delete(cls, session_id):
"Delete the session"
- Session = Pool().get('ir.session.wizard')
+ pool = Pool()
+ Session = pool.get('ir.session.wizard')
+ transaction = Transaction()
+ session = Session(session_id)
+ if session.create_uid.id != transaction.user:
+ raise AccessError(
+ gettext('ir.msg_access_wizard_error', wizard=cls.__name__))
end = getattr(cls, cls.end_state, None)
if end:
wizard = cls(session_id)
action = end(wizard)
else:
action = None
- Session.delete([Session(session_id)])
+ Session.delete([session])
return action
@classmethod
@@ -407,8 +413,12 @@
def __init__(self, session_id):
pool = Pool()
Session = pool.get('ir.session.wizard')
- self._session_id = session_id
+ transaction = Transaction()
session = Session(session_id)
+ if session.create_uid.id != transaction.user:
+ raise AccessError(
+ gettext('ir.msg_access_wizard_error', wizard=self.__name__))
+ self._session_id = session.id
data = defaultdict(dict)
data.update(json.loads(session.data, object_hook=JSONDecoder()))
for state_name, state in self.states.items():