diff --git a/addons/project/models/project.py b/addons/project/models/project.py
index 35a5860772c..31cc324057c 100644
--- a/addons/project/models/project.py
+++ b/addons/project/models/project.py
@@ -262,7 +262,11 @@ class Project(models.Model):
@api.multi
def write(self, vals):
- res = super(Project, self).write(vals)
+ # directly compute is_favorite to dodge allow write access right
+ if 'is_favorite' in vals:
+ vals.pop('is_favorite')
+ self._fields['is_favorite'].determine_inverse(self)
+ res = super(Project, self).write(vals) if vals else True
if 'active' in vals:
# archiving/unarchiving a project does it on its tasks, too
self.with_context(active_test=False).mapped('tasks').write({'active': vals['active']})
diff --git a/addons/project/tests/test_access_rights.py b/addons/project/tests/test_access_rights.py
index 0e3cc8cfb6e..ad31ccbb8b7 100644
--- a/addons/project/tests/test_access_rights.py
+++ b/addons/project/tests/test_access_rights.py
@@ -52,6 +52,15 @@ class TestPortalProject(TestPortalProjectBase):
'project_id': pigs.id})
tmp_task.sudo(self.user_projectuser).unlink()
+ @mute_logger('odoo.addons.base.ir.ir_model')
+ def test_favorite_project_access_rights(self):
+ pigs = self.project_pigs.sudo(self.user_projectuser)
+
+ # we can't write on project name
+ self.assertRaises(AccessError, pigs.write, {'name': 'False Pigs'})
+ # we can write on is_favorite
+ pigs.write({'is_favorite': True})
+
@mute_logger('odoo.addons.base.ir.ir_model')
def test_followers_project_access_rights(self):
pigs = self.project_pigs
diff --git a/addons/project/views/project_views.xml b/addons/project/views/project_views.xml
index d5f5afd6d5f..8916b4d3bc0 100644
--- a/addons/project/views/project_views.xml
+++ b/addons/project/views/project_views.xml
@@ -321,7 +321,7 @@
-