diff --git a/trytond/trytond/ir/resource.py b/trytond/trytond/ir/resource.py index 31efac75fa..40672bc75f 100644 --- a/trytond/trytond/ir/resource.py +++ b/trytond/trytond/ir/resource.py @@ -77,7 +77,12 @@ class ResourceAccessMixin(ModelStorage): result = super().search( domain, offset=offset, limit=limit, order=order, count=False if enforce_access else count, query=query) - if enforce_access: + if not enforce_access: + return result + + loop = 0 + fetched = [] + while True: records = result resources = defaultdict(set) allowed = set() @@ -93,15 +98,27 @@ class ResourceAccessMixin(ModelStorage): ('id', 'in', ids), ])) - records = [ + fetched.extend([ r for r in records - if not r.resource or r.resource in allowed] - if count: - result = len(records) - else: - # re-browse to have same context - result = cls.browse(records) - return result + if not r.resource or r.resource in allowed]) + + if limit is None or len(fetched) >= limit: + if limit is not None: + fetched = fetched[:limit] + break + + loop += 1 + result = super().search( + domain, offset=offset + loop * limit, limit=limit, order=order, + count=False, query=False) + if not result: + break + + if count: + return len(fetched) + else: + # re-browse to have same context + return cls.browse(fetched) @classmethod def read(cls, ids, fields_names): diff --git a/trytond/trytond/tests/test_resource.py b/trytond/trytond/tests/test_resource.py index 623465b468..45664e7933 100644 --- a/trytond/trytond/tests/test_resource.py +++ b/trytond/trytond/tests/test_resource.py @@ -235,3 +235,28 @@ class ResourceTestCase(TestCase): Note.read([note.id], ['message']) with self.assertRaises(AccessError): Note.delete([note]) + + @with_transaction() + def test_resources_search_limit(self): + "Test resource search limit work as expected" + pool = Pool() + Note = pool.get('ir.note') + Warning_ = pool.get('res.user.warning') + + warning1 = Warning_(user=0, name="root") + warning1.save() + warning2 = Warning_(user=1, name="admin") + warning2.save() + for i in range(100): + note = Note(resource=warning2 if i % 3 else warning1) + note.save() + + with Transaction().set_context(_check_access=True): + notes = Note.search([], limit=10, offset=0) + self.assertEqual(len(notes), 10) + + notes = Note.search([], limit=200, offset=0) + self.assertEqual(len(notes), 66) + + notes = Note.search([]) + self.assertEqual(len(notes), 66)