[FIX] project: filter stages based on the user_id

Steps to reproduce:
- have a project with a stage having the user_id set to Mitchell Admin (in this scenario you would have to add the field in the view)
- create a task in this stage
- log in with Marc Demo
- Try to open the project

Issue:
There will be an access error

Cause:
The domain allows to fetch all tasks from a project; even those from a prohibited stage

Solution:
- As in d4252825f5, we'll restrict the domain and "hide task stages if user is set".
- Prevent the user to create/modify a record to it with with a `user_id` and `project_ids`

opw-2917631

closes odoo/odoo#101965

X-original-commit: fdaef9276b89e2170128e205a4b7fd0b8defc2b1
Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
Signed-off-by: Xavier <xbo@odoo.com>
This commit is contained in:
Yolann Sabaux
2022-10-03 17:18:31 +02:00
committed by Xavier BOL (xbo)
parent d1d9a5f2de
commit bece0fb675
4 changed files with 73 additions and 0 deletions
+8
View File
@@ -576,6 +576,14 @@ msgstr ""
msgid "A tag with the same name already exists."
msgstr ""
#. module: project
#: code:addons/project/models/project.py:0
#, python-format
msgid ""
"A personal stage cannot be linked to a project because it is only visible to"
" its corresponding user."
msgstr ""
#. module: project
#: model:ir.model.constraint,message:project.constraint_project_task_user_rel_project_personal_stage_unique
msgid "A task can only have a single personal stage per user."
+5
View File
@@ -169,6 +169,11 @@ class ProjectTaskType(models.Model):
else:
stage.disabled_rating_warning = False
@api.constrains('user_id', 'project_ids')
def _check_personal_stage_not_linked_to_projects(self):
if any(stage.user_id and stage.project_ids for stage in self):
raise UserError(_('A personal stage cannot be linked to a project because it is only visible to its corresponding user.'))
def remove_personal_stage(self):
"""
Remove a personal stage, tasks using that stage will move to the first
+1
View File
@@ -12,6 +12,7 @@ from . import test_project_sharing
from . import test_project_sharing_portal_access
from . import test_project_sharing_ui
from . import test_project_subtasks
from . import test_project_task_type
from . import test_project_ui
from . import test_project_update_access_rights
from . import test_project_update_flow
@@ -0,0 +1,59 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.exceptions import UserError
from odoo.addons.project.tests.test_project_base import TestProjectCommon
class TestProjectTaskType(TestProjectCommon):
@classmethod
def setUpClass(cls):
super(TestProjectTaskType, cls).setUpClass()
cls.stage_created = cls.env['project.task.type'].create({
'name': 'Stage Already Created',
})
def test_create_stage(self):
'''
Verify that it is not possible to add to a newly created stage a `user_id` and a `project_ids`
'''
with self.assertRaises(UserError):
self.env['project.task.type'].create({
'name': 'New Stage',
'user_id': self.uid,
'project_ids': [self.project_goats.id],
})
def test_modify_existing_stage(self):
'''
- case 1: [`user_id`: not set, `project_ids`: not set] | Add `user_id` and `project_ids` => UserError
- case 2: [`user_id`: set, `project_ids`: not set] | Add `project_ids` => UserError
- case 3: [`user_id`: not set, `project_ids`: set] | Add `user_id` => UserError
'''
# case 1
with self.assertRaises(UserError):
self.stage_created.write({
'user_id': self.uid,
'project_ids': [self.project_goats.id],
})
# case 2
self.stage_created.write({
'user_id': self.uid,
})
with self.assertRaises(UserError):
self.stage_created.write({
'project_ids': [self.project_goats.id],
})
# case 3
self.stage_created.write({
'user_id': False,
'project_ids': [self.project_goats.id],
})
with self.assertRaises(UserError):
self.stage_created.write({
'user_id': self.uid,
})