Merge pull request #25503 from edx/mikix/parent-access
AA-408: Treat group_access as inheritable in gating transformer
This commit is contained in:
@@ -58,7 +58,7 @@ def update_masters_access_course(sender, instance, **kwargs): # pylint: disable
|
||||
masters_id = getattr(settings, 'COURSE_ENROLLMENT_MODES', {}).get('masters', {}).get('id', None)
|
||||
verified_id = getattr(settings, 'COURSE_ENROLLMENT_MODES', {}).get('verified', {}).get('id', None)
|
||||
if not (masters_id and verified_id):
|
||||
log.error("Missing settings.COURSE_ENROLLMENT_MODES -> verified:%s masters:%s", verified, masters)
|
||||
log.error("Missing settings.COURSE_ENROLLMENT_MODES -> verified:%s masters:%s", verified_id, masters_id)
|
||||
return
|
||||
|
||||
course_id = instance.course_id
|
||||
|
||||
@@ -31,6 +31,7 @@ class StackedConfigModelAdmin(ConfigurationModelAdmin):
|
||||
form = StackedConfigModelAdminForm
|
||||
|
||||
raw_id_fields = ('course',)
|
||||
search_fields = ('site__domain', 'org', 'org_course', 'course__id')
|
||||
|
||||
def get_fieldsets(self, request, obj=None):
|
||||
return (
|
||||
@@ -65,13 +66,12 @@ class StackedConfigModelAdmin(ConfigurationModelAdmin):
|
||||
def stackable_fields(self):
|
||||
return list(self.model.STACKABLE_FIELDS)
|
||||
|
||||
@property
|
||||
def config_fields(self):
|
||||
fields = super(StackedConfigModelAdmin, self).get_fields(request, obj)
|
||||
def get_config_fields(self, request, obj=None):
|
||||
fields = super().get_fields(request, obj)
|
||||
return [field for field in fields if field not in self.key_fields]
|
||||
|
||||
def get_fields(self, request, obj=None):
|
||||
return self.key_fields + self.config_fields
|
||||
return self.key_fields + self.get_config_fields(request, obj)
|
||||
|
||||
def get_displayable_field_names(self):
|
||||
"""
|
||||
|
||||
@@ -6,6 +6,7 @@ Limits access for certain users to certain types of content.
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from lms.djangoapps.course_blocks.transformers.user_partitions import UserPartitionTransformer
|
||||
from openedx.core.djangoapps.content.block_structure.transformer import BlockStructureTransformer
|
||||
from openedx.features.content_type_gating.helpers import CONTENT_GATING_PARTITION_ID
|
||||
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
|
||||
@@ -15,6 +16,8 @@ class ContentTypeGateTransformer(BlockStructureTransformer):
|
||||
"""
|
||||
A transformer that adds a partition condition for all graded content
|
||||
so that the content is only visible to verified users.
|
||||
|
||||
This transformer requires that the UserPartitionTransformer also be included in your transformer list.
|
||||
"""
|
||||
WRITE_VERSION = 1
|
||||
READ_VERSION = 1
|
||||
@@ -48,6 +51,24 @@ class ContentTypeGateTransformer(BlockStructureTransformer):
|
||||
for parent_block_key in block_structure.get_parents(block_key):
|
||||
self._set_contains_gated_content_on_parents(block_structure, parent_block_key)
|
||||
|
||||
@staticmethod
|
||||
def _get_block_group_access(block_structure, block_key):
|
||||
"""
|
||||
Gets the current group_access value for a block, supporting inheritance when possible.
|
||||
In order to support inheritance, UserPartitionTransformer must also be used.
|
||||
"""
|
||||
# See user_partitions.py for the code that sets this field.
|
||||
merged_access = block_structure.get_transformer_block_field(
|
||||
block_key, UserPartitionTransformer, 'merged_group_access', None
|
||||
)
|
||||
if merged_access:
|
||||
current_access = merged_access.get_allowed_groups()
|
||||
else:
|
||||
# This fallback code has a bug if UserPartitionTranformer is not being used -- it does not consider
|
||||
# inheritance from parent blocks. This is why our class docstring recommends UserPartitionTranformer.
|
||||
current_access = block_structure.get_xblock_field(block_key, 'group_access')
|
||||
return current_access or {}
|
||||
|
||||
def transform(self, usage_info, block_structure):
|
||||
if not ContentTypeGatingConfig.enabled_for_enrollment(
|
||||
user=usage_info.user,
|
||||
@@ -61,9 +82,7 @@ class ContentTypeGateTransformer(BlockStructureTransformer):
|
||||
weight_not_zero = block_structure.get_xblock_field(block_key, 'weight') != 0
|
||||
problem_eligible_for_content_gating = graded and has_score and weight_not_zero
|
||||
if problem_eligible_for_content_gating:
|
||||
current_access = block_structure.get_xblock_field(block_key, 'group_access')
|
||||
if current_access is None:
|
||||
current_access = {}
|
||||
current_access = self._get_block_group_access(block_structure, block_key)
|
||||
current_access.setdefault(
|
||||
CONTENT_GATING_PARTITION_ID,
|
||||
[settings.CONTENT_TYPE_GATE_GROUP_IDS['full_access']]
|
||||
|
||||
@@ -56,7 +56,7 @@ class ContentTypeGatingFieldOverride(FieldOverrideProvider):
|
||||
if parent is not None:
|
||||
merged_group_access = parent.merged_group_access
|
||||
if merged_group_access and CONTENT_GATING_PARTITION_ID in merged_group_access:
|
||||
return original_group_access
|
||||
return default
|
||||
|
||||
original_group_access.setdefault(
|
||||
CONTENT_GATING_PARTITION_ID,
|
||||
@@ -67,5 +67,5 @@ class ContentTypeGatingFieldOverride(FieldOverrideProvider):
|
||||
|
||||
@classmethod
|
||||
def enabled_for(cls, course):
|
||||
"""This simple override provider is always enabled"""
|
||||
"""Check our stackable config for this specific course"""
|
||||
return ContentTypeGatingConfig.enabled_for_course(course_key=course.scope_ids.usage_id.course_key)
|
||||
|
||||
Reference in New Issue
Block a user