[FW][FIX] knowledge: correctly copy members when desynchronizing on archive
Currently, when archiving an article, if you don't have write access to some of the children of the article, we do not archive them and do some extra post-processing. Meaning: - They become independent from the archived parent - They are moved as "root articles" - The potential specific member access from their parent(s) are copied To avoid loosing access if specific members where configured on the parent(s) of those articles, since they will no-longer inherit from them. This last part was not working properly and has been fixed. Existing tests have been adapted to ensure the behavior is kept. Task-2859616 X-original-commit: odoo/odoo@b35f2ace22 Part-of: odoo/odoo#95471
This commit is contained in:
committed by
Thibault Delavallée
parent
f92b925a5c
commit
11bef11248
@@ -1102,7 +1102,7 @@ class Article(models.Model):
|
||||
"""
|
||||
self.ensure_one()
|
||||
new_internal_permission = force_internal_permission or self.inherited_permission
|
||||
members_commands = self._copy_access_from_parents(
|
||||
members_commands = self._copy_access_from_parents_commands(
|
||||
force_partners=force_partners,
|
||||
force_member_permission=force_member_permission
|
||||
)
|
||||
@@ -1113,17 +1113,20 @@ class Article(models.Model):
|
||||
'is_desynchronized': True,
|
||||
})
|
||||
|
||||
def _copy_access_from_parents(self, force_partners=False, force_member_permission=False):
|
||||
""" Copies copy all inherited accesses from parents on the article and
|
||||
de-synchronize the article from its parent, allowing custom access management.
|
||||
def _copy_access_from_parents_commands(self, force_partners=False, force_member_permission=False):
|
||||
""" Prepares commands for all inherited accesses from parents on the given
|
||||
article. It allows to de-synchronize the article from its parent and
|
||||
allows custom access management. We allow to force permission of given
|
||||
partners, bypassing inherited ones.
|
||||
|
||||
We allow to force permission of given partners.
|
||||
|
||||
:param string force_internal_permission: force a new internal permission
|
||||
for the article. Otherwise fallback on inherited computed internal
|
||||
permission;
|
||||
:param <res.partner> force_partners: force permission of new members
|
||||
related to those partners;
|
||||
:param str force_member_permission: force a new permission to partners
|
||||
given by force_partners. Otherwise fallback on inherited computed
|
||||
internal permission;
|
||||
|
||||
:return list member_commands: commands to be applied on 'article_member_ids'
|
||||
field;
|
||||
"""
|
||||
self.ensure_one()
|
||||
members_permission = self._get_article_member_permissions()[self.id]
|
||||
@@ -1165,7 +1168,9 @@ class Article(models.Model):
|
||||
|
||||
# copy rights to allow breaking the hierarchy while keeping access for members
|
||||
for article_sudo in other_descendants_sudo:
|
||||
article_sudo._copy_access_from_parents()
|
||||
article_sudo.write({
|
||||
'article_member_ids': article_sudo._copy_access_from_parents_commands()
|
||||
})
|
||||
|
||||
# create new root articles: direct children of these articles
|
||||
new_roots_woperm = other_descendants_sudo.filtered(lambda article: article.parent_id in self and not article.internal_permission)
|
||||
|
||||
@@ -79,11 +79,10 @@ class TestKnowledgeArticleBusiness(KnowledgeCommonWData):
|
||||
wkspace_grandchildren = self.wkspace_grandchildren.with_env(self.env)
|
||||
wkspace_grandgrandchildren = self.wkspace_grandgrandchildren.with_env(self.env)
|
||||
|
||||
# TDE FIXME: currently failing
|
||||
# no write access -> cracboum
|
||||
# with self.assertRaises(exceptions.AccessError,
|
||||
# msg='Employee can read thus not archive'):
|
||||
# article_shared.action_archive()
|
||||
with self.assertRaises(exceptions.AccessError,
|
||||
msg='Employee can read thus not archive'):
|
||||
article_shared.action_archive()
|
||||
|
||||
# set the root + children inactive
|
||||
article_workspace.action_archive()
|
||||
@@ -109,6 +108,13 @@ class TestKnowledgeArticleBusiness(KnowledgeCommonWData):
|
||||
def test_article_archive_mixed_rights(self):
|
||||
""" Test archive in case of mixed rights """
|
||||
# give write access to shared section, but have children in read or none
|
||||
# and add a customer on top of shared articles to check propagation
|
||||
self.article_shared.write({
|
||||
'article_member_ids': [(0, 0, {
|
||||
'partner_id': self.customer.id,
|
||||
'permission': 'read',
|
||||
})]
|
||||
})
|
||||
self.article_shared.article_member_ids.sudo().filtered(
|
||||
lambda article: article.partner_id == self.partner_employee
|
||||
).write({'permission': 'write'})
|
||||
@@ -132,7 +138,6 @@ class TestKnowledgeArticleBusiness(KnowledgeCommonWData):
|
||||
self.assertTrue(writable_child.user_has_write_access)
|
||||
self.assertEqual(shared_children, writable_child + readonly_child, 'Should see only two first children')
|
||||
|
||||
# TDE FIXME: currently failing
|
||||
article_shared.action_archive()
|
||||
# check writable articles have been archived, readonly or hidden not
|
||||
self.assertFalse(article_shared.active)
|
||||
@@ -147,6 +152,23 @@ class TestKnowledgeArticleBusiness(KnowledgeCommonWData):
|
||||
self.assertFalse(hidden_child_su.parent_id, 'Archive: article should be extracted in archive process as non writable')
|
||||
self.assertEqual(hidden_child_su.root_article_id, hidden_child_su)
|
||||
|
||||
# verify that the child that was not accessible was moved as a root article...
|
||||
self.assertTrue(hidden_child_su.active)
|
||||
self.assertEqual(hidden_child_su.category, 'shared')
|
||||
self.assertEqual(hidden_child_su.internal_permission, 'none')
|
||||
self.assertFalse(hidden_child_su.parent_id)
|
||||
# ... and kept his access rights: still member for employee / admin and
|
||||
# copied customer access from the archived parent
|
||||
self.assertMembers(
|
||||
hidden_child_su,
|
||||
'none',
|
||||
{self.user_admin.partner_id: 'write',
|
||||
self.partner_employee_manager: 'read',
|
||||
self.partner_employee: 'none',
|
||||
self.customer: 'read',
|
||||
}
|
||||
)
|
||||
|
||||
@mute_logger('odoo.addons.base.models.ir_rule')
|
||||
@users('employee')
|
||||
def test_article_create(self):
|
||||
|
||||
@@ -81,7 +81,7 @@ class KnowledgePerformanceCase(KnowledgeCommonWData):
|
||||
@users('employee')
|
||||
@warmup
|
||||
def test_article_invite_members(self):
|
||||
with self.assertQueryCount(employee=84): # knowledge only: 84
|
||||
with self.assertQueryCount(employee=85): # knowledge only: 84
|
||||
shared_article = self.shared_children[0].with_env(self.env)
|
||||
partners = (self.customer + self.partner_employee_manager + self.partner_employee2).with_env(self.env)
|
||||
shared_article.invite_members(partners, 'write')
|
||||
|
||||
Reference in New Issue
Block a user