Merge pull request #4237 from ostcar/fix_restricted_data_cache

fix restricted_data_cache for elements that exists, but a user is not allowed to see them
This commit is contained in:
Emanuel Schütze 2019-02-01 10:13:53 +01:00 committed by GitHub
commit fa8e0687bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 8 deletions

View File

@ -286,19 +286,26 @@ class ElementCache:
# The user_change_id is lower then the lowest change_id in the cache. # The user_change_id is lower then the lowest change_id in the cache.
# The whole restricted_data for that user has to be recreated. # The whole restricted_data for that user has to be recreated.
full_data_elements = await self.get_all_full_data() full_data_elements = await self.get_all_full_data()
deleted_elements = []
await self.cache_provider.del_restricted_data(user_id) await self.cache_provider.del_restricted_data(user_id)
else:
# Remove deleted elements
if deleted_elements:
await self.cache_provider.del_elements(
deleted_elements, user_id
)
mapping = {} mapping = {}
for collection_string, full_data in full_data_elements.items(): for collection_string, full_data in full_data_elements.items():
restricter = self.cachables[collection_string].restrict_elements restricter = self.cachables[collection_string].restrict_elements
elements = await restricter(user_id, full_data) restricted_elements = await restricter(user_id, full_data)
for element in elements:
# find all elements the user can not see at all
full_data_ids = set(element["id"] for element in full_data)
restricted_data_ids = set(
element["id"] for element in restricted_elements
)
for item_id in full_data_ids - restricted_data_ids:
deleted_elements.append(
get_element_id(collection_string, item_id)
)
for element in restricted_elements:
# The user can see the element
mapping.update( mapping.update(
{ {
get_element_id( get_element_id(
@ -308,6 +315,9 @@ class ElementCache:
) )
mapping["_config:change_id"] = str(change_id) mapping["_config:change_id"] = str(change_id)
await self.cache_provider.update_restricted_data(user_id, mapping) await self.cache_provider.update_restricted_data(user_id, mapping)
# Remove deleted elements
if deleted_elements:
await self.cache_provider.del_elements(deleted_elements, user_id)
# Unset the lock # Unset the lock
await self.cache_provider.del_lock(lock_name) await self.cache_provider.del_lock(lock_name)
future.set_result(1) future.set_result(1)

View File

@ -1,6 +1,7 @@
import asyncio import asyncio
import json import json
from typing import Any, Dict, List from typing import Any, Dict, List
from unittest.mock import patch
import pytest import pytest
@ -309,6 +310,30 @@ async def test_update_restricted_data(element_cache):
assert element_cache.restricted_data_cache_updater[0].done() assert element_cache.restricted_data_cache_updater[0].done()
@pytest.mark.asyncio
async def test_update_restricted_data_full_restricted_elements(element_cache):
"""
Tests that elements in the restricted_data cache, that are later hidden from
a user, gets deleted for this user.
"""
element_cache.use_restricted_data_cache = True
await element_cache.update_restricted_data(0)
element_cache.cache_provider.change_id_data = {
1: {"app/collection1:1", "app/collection1:3"}
}
with patch("tests.unit.utils.cache_provider.restrict_elements", lambda x: []):
await element_cache.update_restricted_data(0)
assert decode_dict(element_cache.cache_provider.restricted_data[0]) == decode_dict(
{"_config:change_id": "1"}
)
# Make sure the lock is deleted
assert not await element_cache.cache_provider.get_lock("restricted_data_0")
# And the future is done
assert element_cache.restricted_data_cache_updater[0].done()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_update_restricted_data_disabled_restricted_data(element_cache): async def test_update_restricted_data_disabled_restricted_data(element_cache):
element_cache.use_restricted_data_cache = False element_cache.use_restricted_data_cache = False