def test_get_masquerade_group(self): """ Tests that a staff member can masquerade as being in a group in a user partition """ # Verify there is no masquerading group initially group = get_masquerading_user_group(self.course.id, self.test_user, self.user_partition) assert group is None # Install a masquerading group self.ensure_masquerade_as_group_member(0, 1) # Verify that the masquerading group is returned group = get_masquerading_user_group(self.course.id, self.test_user, self.user_partition) assert group.id == 1
def has_full_access_role_in_masquerade(cls, user, course_key, course_masquerade, student_masquerade, user_partition): """ The roles of the masquerade user are used to determine whether the content gate displays. The gate will not appear if the masquerade user has any of the following roles: Staff, Instructor, Beta Tester, Forum Community TA, Forum Group Moderator, Forum Moderator, Forum Administrator """ if student_masquerade: # If a request is masquerading as a specific user, the user variable will represent the correct user. if user and user.id and has_staff_roles(user, course_key): return True elif user_partition: # If the current user is masquerading as a generic student in a specific group, # then return the value based on that group. masquerade_group = get_masquerading_user_group(course_key, user, user_partition) if masquerade_group is None: audit_mode_id = settings.COURSE_ENROLLMENT_MODES.get(CourseMode.AUDIT, {}).get('id') # We are checking the user partition id here because currently content # cannot have both the enrollment track partition and content gating partition # configured simultaneously. We may change this in the future and allow # configuring both partitions on content and selecting both partitions in masquerade. if course_masquerade.user_partition_id == ENROLLMENT_TRACK_PARTITION_ID: return course_masquerade.group_id != audit_mode_id elif masquerade_group is FULL_ACCESS: return True elif masquerade_group is LIMITED_ACCESS: return False
def get_group_for_user(cls, course_key, user, user_partition, **kwargs): # pylint: disable=unused-argument """ Returns the Group for the specified user. """ # First, check if we have to deal with masquerading. # If the current user is masquerading as a specific student, use the # same logic as normal to return that student's group. If the current # user is masquerading as a generic student in a specific group, then # return that group. if get_course_masquerade(user, course_key) and not is_masquerading_as_specific_student(user, course_key): return get_masquerading_user_group(course_key, user, user_partition) # For now, treat everyone as a Full-access user, until we have the rest of the # feature gating logic in place. if not CONTENT_TYPE_GATING_FLAG.is_enabled(): return cls.FULL_ACCESS # If CONTENT_TYPE_GATING is enabled use the following logic to determine whether a user should have FULL_ACCESS # or LIMITED_ACCESS course_mode = apps.get_model('course_modes.CourseMode') modes = course_mode.modes_for_course(course_key, include_expired=True, only_selectable=False) modes_dict = {mode.slug: mode for mode in modes} # If there is no verified mode, all users are granted FULL_ACCESS if not course_mode.has_verified_mode(modes_dict): return cls.FULL_ACCESS course_enrollment = apps.get_model('student.CourseEnrollment') mode_slug, is_active = course_enrollment.enrollment_mode_for_user(user, course_key) if mode_slug and is_active: course_mode = course_mode.mode_for_course( course_key, mode_slug, modes=modes, ) if course_mode is None: LOG.error( "User %s is in an unknown CourseMode '%s'" " for course %s. Granting full access to content for this user", user.username, mode_slug, course_key, ) return cls.FULL_ACCESS if mode_slug == CourseMode.AUDIT: return cls.LIMITED_ACCESS else: return cls.FULL_ACCESS else: # Unenrolled users don't get gated content return cls.LIMITED_ACCESS
def get_group_for_user(cls, course_key, user, user_partition, **kwargs): # pylint: disable=unused-argument """ Returns the Group from the specified user partition to which the user is assigned, via enrollment mode. If a user is in a Credit mode, the Verified or Professional mode for the course is returned instead. If a course is using the Verified Track Cohorting pilot feature, this method returns None regardless of the user's enrollment mode. """ if is_course_using_cohort_instead(course_key): return None # First, check if we have to deal with masquerading. # If the current user is masquerading as a specific student, use the # same logic as normal to return that student's group. If the current # user is masquerading as a generic student in a specific group, then # return that group. if get_course_masquerade( user, course_key) and not is_masquerading_as_specific_student( user, course_key): return get_masquerading_user_group(course_key, user, user_partition) mode_slug, is_active = CourseEnrollment.enrollment_mode_for_user( user, course_key) if mode_slug and is_active: course_mode = CourseMode.mode_for_course( course_key, mode_slug, modes=CourseMode.modes_for_course(course_key, include_expired=True, only_selectable=False), ) if course_mode and CourseMode.is_credit_mode(course_mode): # We want the verified track even if the upgrade deadline has passed, since we # are determining what content to show the user, not whether the user can enroll # in the verified track. course_mode = CourseMode.verified_mode_for_course( course_key, include_expired=True) if not course_mode: course_mode = CourseMode.DEFAULT_MODE return Group(ENROLLMENT_GROUP_IDS[course_mode.slug]["id"], six.text_type(course_mode.name)) else: return None
def get_group_for_user(cls, course_key, user, user_partition, **kwargs): # pylint: disable=unused-argument """ Returns the Group for the specified user. """ # First, check if we have to deal with masquerading. # If the current user is masquerading as a specific student, use the # same logic as normal to return that student's group. If the current # user is masquerading as a generic student in a specific group, then # return that group. if get_course_masquerade( user, course_key) and not is_masquerading_as_specific_student( user, course_key): return get_masquerading_user_group(course_key, user, user_partition) # For now, treat everyone as a Full-access user, until we have the rest of the # feature gating logic in place. return cls.FULL_ACCESS
def get_group_for_user(cls, course_key, user, user_partition, use_cached=True): """ Returns the Group from the specified user partition to which the user is assigned, via their cohort membership and any mappings from cohorts to partitions / groups that might exist. If the user has not yet been assigned to a cohort, an assignment *might* be created on-the-fly, as determined by the course's cohort config. Any such side-effects will be triggered inside the call to cohorts.get_cohort(). If the user has no cohort mapping, or there is no (valid) cohort -> partition group mapping found, the function returns None. """ # First, check if we have to deal with masquerading. # If the current user is masquerading as a specific student, use the # same logic as normal to return that student's group. If the current # user is masquerading as a generic student in a specific group, then # return that group. if get_course_masquerade(user, course_key) and not is_masquerading_as_specific_student(user, course_key): return get_masquerading_user_group(course_key, user, user_partition) cohort = get_cohort(user, course_key, use_cached=use_cached) if cohort is None: # student doesn't have a cohort return None group_id, partition_id = get_group_info_for_cohort(cohort, use_cached=use_cached) if partition_id is None: # cohort isn't mapped to any partition group. return None if partition_id != user_partition.id: # if we have a match but the partition doesn't match the requested # one it means the mapping is invalid. the previous state of the # partition configuration may have been modified. log.warn( u"partition mismatch in CohortPartitionScheme: %r", { "requested_partition_id": user_partition.id, "found_partition_id": partition_id, "found_group_id": group_id, "cohort_id": cohort.id, } ) # fail silently return None try: return user_partition.get_group(group_id) except NoSuchUserPartitionGroupError: # if we have a match but the group doesn't exist in the partition, # it means the mapping is invalid. the previous state of the # partition configuration may have been modified. log.warn( u"group not found in CohortPartitionScheme: %r", { "requested_partition_id": user_partition.id, "requested_group_id": group_id, "cohort_id": cohort.id, }, exc_info=True ) # fail silently return None
def get_group_for_user(cls, course_key, user, user_partition, **kwargs): # pylint: disable=unused-argument """ Returns the Group for the specified user. """ # First, check if we have to deal with masquerading. # If the current user is masquerading as a specific student, use the # same logic as normal to return that student's group. If the current # user is masquerading as a generic student in a specific group, then # return that group. course_masquerade = get_course_masquerade(user, course_key) if course_masquerade and not is_masquerading_as_specific_student(user, course_key): masquerade_group = get_masquerading_user_group(course_key, user, user_partition) if masquerade_group is not None: return masquerade_group else: audit_mode_id = settings.COURSE_ENROLLMENT_MODES.get(CourseMode.AUDIT, {}).get('id') if course_masquerade.user_partition_id == ENROLLMENT_TRACK_PARTITION_ID: if course_masquerade.group_id != audit_mode_id: return cls.FULL_ACCESS else: return cls.LIMITED_ACCESS # For now, treat everyone as a Full-access user, until we have the rest of the # feature gating logic in place. if not ContentTypeGatingConfig.enabled_for_enrollment(user=user, course_key=course_key): return cls.FULL_ACCESS # If CONTENT_TYPE_GATING is enabled use the following logic to determine whether a user should have FULL_ACCESS # or LIMITED_ACCESS course_mode = apps.get_model('course_modes.CourseMode') modes = course_mode.modes_for_course(course_key, include_expired=True, only_selectable=False) modes_dict = {mode.slug: mode for mode in modes} # If there is no verified mode, all users are granted FULL_ACCESS if not course_mode.has_verified_mode(modes_dict): return cls.FULL_ACCESS # If the user is a beta tester for this course they are granted FULL_ACCESS if CourseBetaTesterRole(course_key).has_user(user): return cls.FULL_ACCESS course_enrollment = apps.get_model('student.CourseEnrollment') mode_slug, is_active = course_enrollment.enrollment_mode_for_user(user, course_key) if mode_slug and is_active: course_mode = course_mode.mode_for_course( course_key, mode_slug, modes=modes, ) if course_mode is None: LOG.error( "User %s is in an unknown CourseMode '%s'" " for course %s. Granting full access to content for this user", user.username, mode_slug, course_key, ) return cls.FULL_ACCESS if mode_slug == CourseMode.AUDIT: return cls.LIMITED_ACCESS else: return cls.FULL_ACCESS else: # Unenrolled users don't get gated content return cls.LIMITED_ACCESS