From c15bd975e74debd13f6454aac54ff5dbf23d3bd8 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Thu, 29 Oct 2020 15:49:24 +0100 Subject: [PATCH] Store 'su' flag in jobs "record.sudo().with_delay().foo()" generates a job that will be run as sudo, keeping the current user, following the new implementation of sudo/with_user of 13.0. --- queue_job/job.py | 13 ++++++++++--- queue_job/models/queue_job.py | 3 +++ test_queue_job/tests/test_job.py | 22 ++++++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/queue_job/job.py b/queue_job/job.py index 457cb1c77c..1c0b5fa5ec 100644 --- a/queue_job/job.py +++ b/queue_job/job.py @@ -257,7 +257,7 @@ def load(cls, env, job_uuid): @classmethod def _load_from_db_record(cls, job_db_record): stored = job_db_record - env = job_db_record.env + env = job_db_record.env(su=stored.func_env.get("su", False)) args = stored.args kwargs = stored.kwargs @@ -529,6 +529,11 @@ def perform(self): raise return self.result + def _func_env_values(self): + return { + "su": self.env.su, + } + def store(self): """Store the Job""" vals = { @@ -546,6 +551,7 @@ def store(self): "eta": False, "identity_key": False, "worker_pid": self.worker_pid, + "func_env": self._func_env_values(), } if self.date_enqueued: @@ -595,8 +601,9 @@ def db_record(self): @property def func(self): - recordset = self.recordset.with_context(job_uuid=self.uuid) - recordset = recordset.with_user(self.user_id) + env = self.recordset.env(user=self.user_id, su=self.env.su) + recordset = self.recordset.with_env(env) + recordset = recordset.with_context(job_uuid=self.uuid) return getattr(recordset, self.method_name) @property diff --git a/queue_job/models/queue_job.py b/queue_job/models/queue_job.py index 25d5caace5..e93f27f935 100644 --- a/queue_job/models/queue_job.py +++ b/queue_job/models/queue_job.py @@ -49,6 +49,7 @@ class QueueJob(models.Model): ) uuid = fields.Char(string="UUID", readonly=True, index=True, required=True) + # maybe be better to keep this one out of "func_env" for searches? user_id = fields.Many2one(comodel_name="res.users", string="User ID", required=True) company_id = fields.Many2one( comodel_name="res.company", string="Company", index=True @@ -58,6 +59,8 @@ class QueueJob(models.Model): model_name = fields.Char(string="Model", readonly=True) method_name = fields.Char(readonly=True) record_ids = JobSerialized(readonly=True, base_type=list) + # TODO store a context in func_env, based on https://github.com/OCA/queue/pull/121 + func_env = JobSerialized(readonly=True, base_type=dict) args = JobSerialized(readonly=True, base_type=tuple) kwargs = JobSerialized(readonly=True, base_type=dict) func_string = fields.Char( diff --git a/test_queue_job/tests/test_job.py b/test_queue_job/tests/test_job.py index e55636362a..b7149eb81b 100644 --- a/test_queue_job/tests/test_job.py +++ b/test_queue_job/tests/test_job.py @@ -432,6 +432,28 @@ def test_job_with_mutable_arguments(self): self.assertEquals(([1],), job_instance.args) self.assertEquals({"mutable_kwarg": {"a": 1}}, job_instance.kwargs) + def test_store_env_su_no_sudo(self): + demo_user = self.env.ref("base.user_demo") + self.env = self.env(user=demo_user) + delayable = self.env["test.queue.job"].with_delay() + test_job = delayable.testing_method() + stored = test_job.db_record() + self.assertDictEqual(stored.func_env, {"su": False}) + job_instance = Job.load(self.env, stored.uuid) + self.assertFalse(job_instance.env.su) + self.assertFalse(job_instance.recordset.env.su) + + def test_store_env_su_sudo(self): + demo_user = self.env.ref("base.user_demo") + self.env = self.env(user=demo_user) + delayable = self.env["test.queue.job"].sudo().with_delay() + test_job = delayable.testing_method() + stored = test_job.db_record() + self.assertDictEqual(stored.func_env, {"su": True}) + job_instance = Job.load(self.env, stored.uuid) + self.assertTrue(job_instance.env.su) + self.assertTrue(job_instance.recordset.env.su) + class TestJobModel(JobCommonCase): def test_job_change_state(self):