fix: bypass access checks when populating course blocks cache

This commit is contained in:
Asad Ali
2024-10-16 13:08:54 +05:00
parent de55da2170
commit 1f86786b15
2 changed files with 20 additions and 4 deletions

View File

@@ -108,4 +108,5 @@ def get_course_blocks(
transformers,
starting_block_usage_key,
collected_block_structure,
user,
)

View File

@@ -35,7 +35,7 @@ class BlockStructureManager:
self.modulestore = modulestore
self.store = BlockStructureStore(cache)
def get_transformed(self, transformers, starting_block_usage_key=None, collected_block_structure=None):
def get_transformed(self, transformers, starting_block_usage_key=None, collected_block_structure=None, user=None):
"""
Returns the transformed Block Structure for the root_block_usage_key,
starting at starting_block_usage_key, getting block data from the cache
@@ -57,11 +57,14 @@ class BlockStructureManager:
get_collected. Can be optionally provided if already available,
for optimization.
user (django.contrib.auth.models.User) - User object for
which the block structure is to be transformed.
Returns:
BlockStructureBlockData - A transformed block structure,
starting at starting_block_usage_key.
"""
block_structure = collected_block_structure.copy() if collected_block_structure else self.get_collected()
block_structure = collected_block_structure.copy() if collected_block_structure else self.get_collected(user)
if starting_block_usage_key:
# Override the root_block_usage_key so traversals start at the
@@ -77,7 +80,7 @@ class BlockStructureManager:
transformers.transform(block_structure)
return block_structure
def get_collected(self):
def get_collected(self, user=None):
"""
Returns the collected Block Structure for the root_block_usage_key,
getting block data from the cache and modulestore, as needed.
@@ -86,6 +89,10 @@ class BlockStructureManager:
the modulestore is accessed if needed (at cache miss), and the
transformers data is collected if needed.
In the case of a cache miss, the function bypasses runtime access checks for the current
user. This is done to prevent inconsistencies in the data, which can occur when
certain blocks are inaccessible due to access restrictions.
Returns:
BlockStructureBlockData - A collected block structure,
starting at root_block_usage_key, with collected data
@@ -99,7 +106,15 @@ class BlockStructureManager:
BlockStructureTransformers.verify_versions(block_structure)
except (BlockStructureNotFound, TransformerDataIncompatible):
block_structure = self._update_collected()
if user:
# This bypasses the runtime access checks. When we are populating the course blocks cache,
# we do not want to perform access checks. Access checks result in inconsistent blocks where
# inaccessible blocks are missing from the cache. Cached course blocks are then used for all the users.
user.known = False
block_structure = self._update_collected()
user.known = True
else:
block_structure = self._update_collected()
return block_structure