Ejemplo n.º 1
0
def _assign_course_staff_role(course_key, enrollments, staff_assignments):
    """
    Grant or remove the course staff role for a set of enrollments on a course.
    For enrollment without a linked user, a CourseAccessRoleAssignment will be
    created (or removed) for that enrollment.

    Arguments:
        enrollments (list): ProgramCourseEnrollments to update
        staff_assignments (dict): Maps an enrollment's external key to a course staff value
    """
    enrollment_role_assignments_to_delete = []
    for enrollment in enrollments:
        if enrollment.course_key != course_key:
            continue

        external_key = enrollment.program_enrollment.external_user_key
        user = enrollment.program_enrollment.user
        course_staff = staff_assignments.get(external_key)

        if user:
            if course_staff is True:
                CourseStaffRole(course_key).add_users(user)
            elif course_staff is False:
                CourseStaffRole(course_key).remove_users(user)
        else:
            if course_staff is True:
                CourseAccessRoleAssignment.objects.update_or_create(
                    enrollment=enrollment,
                    role=ProgramCourseEnrollmentRoles.COURSE_STAFF)
            elif course_staff is False:
                enrollment_role_assignments_to_delete.append(enrollment)

    if enrollment_role_assignments_to_delete:
        CourseAccessRoleAssignment.objects.filter(
            enrollment__in=enrollment_role_assignments_to_delete).delete()
Ejemplo n.º 2
0
    def test_no_libraries(self):
        """
        Verify that only Course IDs are returned, not anything else like libraries.
        """
        # Make this user a course staff user for a course, AND a library.
        course_staff_user = self.create_user(username='******',
                                             is_staff=False)
        add_users(self.global_admin, CourseStaffRole(self.course.id),
                  course_staff_user)
        add_users(
            self.global_admin,
            CourseStaffRole(
                LibraryLocator.from_string(
                    'library-v1:library_org+library_name')),
            course_staff_user,
        )

        # Requesting the courses should return *only* courses and not libraries.
        self.setup_user(self.staff_user)
        filtered_response = self.verify_response(
            params={
                'username': course_staff_user.username,
                'role': 'staff'
            })
        self.assertEqual(len(filtered_response.data['results']), 1)
        self.assertTrue(filtered_response.data['results'][0].startswith(
            self.course.org))
Ejemplo n.º 3
0
 def test_get_user_for_role(self):
     """
     test users_for_role
     """
     role = CourseStaffRole(self.course_key)
     role.add_users(self.student)
     assert len(role.users_with_role()) > 0
Ejemplo n.º 4
0
    def test_filter_by_roles_course_staff(self):
        """
        Verify that course_ids are filtered by the provided roles.
        """
        # Make this user a course staff user for the course.
        course_staff_user = self.create_user(username='******', is_staff=False)
        add_users(self.global_admin, CourseStaffRole(self.course.id), course_staff_user)

        # Create a second course, along with an instructor user for it.
        alternate_course1 = self.create_course(org='test1')
        course_instructor_user = self.create_user(username='******', is_staff=False)
        add_users(self.global_admin, CourseInstructorRole(alternate_course1.id), course_instructor_user)

        # Create a third course, along with an user that has both staff and instructor for it.
        alternate_course2 = self.create_course(org='test2')
        course_instructor_staff_user = self.create_user(username='******', is_staff=False)
        add_users(self.global_admin, CourseInstructorRole(alternate_course2.id), course_instructor_staff_user)
        add_users(self.global_admin, CourseStaffRole(alternate_course2.id), course_instructor_staff_user)

        # Requesting the courses for which the course staff user is staff should return *only* the single course.
        self.setup_user(self.staff_user)
        filtered_response = self.verify_response(params={
            'username': course_staff_user.username,
            'role': 'staff'
        })
        assert len(filtered_response.data['results']) == 1
        assert filtered_response.data['results'][0].startswith(self.course.org)

        # The course staff user does *not* have the course instructor role on any courses.
        filtered_response = self.verify_response(params={
            'username': course_staff_user.username,
            'role': 'instructor'
        })
        assert len(filtered_response.data['results']) == 0

        # The course instructor user only has the course instructor role on one course.
        filtered_response = self.verify_response(params={
            'username': course_instructor_user.username,
            'role': 'instructor'
        })
        assert len(filtered_response.data['results']) == 1
        assert filtered_response.data['results'][0].startswith(alternate_course1.org)

        # The course instructor user has the inferred course staff role on one course.
        self.setup_user(course_instructor_user)
        filtered_response = self.verify_response(params={
            'username': course_instructor_user.username,
            'role': 'staff'
        })
        assert len(filtered_response.data['results']) == 1
        assert filtered_response.data['results'][0].startswith(alternate_course1.org)

        # The user with both instructor AND staff on a course has the inferred course staff role on that one course.
        self.setup_user(course_instructor_staff_user)
        filtered_response = self.verify_response(params={
            'username': course_instructor_staff_user.username,
            'role': 'staff'
        })
        assert len(filtered_response.data['results']) == 1
        assert filtered_response.data['results'][0].startswith(alternate_course2.org)
Ejemplo n.º 5
0
def remove_all_instructors(course_key):
    """
    Removes all instructor and staff users from the given course.
    """
    staff_role = CourseStaffRole(course_key)
    staff_role.remove_users(*staff_role.users_with_role())
    instructor_role = CourseInstructorRole(course_key)
    instructor_role.remove_users(*instructor_role.users_with_role())
Ejemplo n.º 6
0
 def test_add_user_to_course_group_permission_denied(self):
     """
     Verifies PermissionDenied if caller of add_user_to_course_group is not instructor role.
     """
     add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
     add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator)
     with self.assertRaises(PermissionDenied):
         add_users(self.staff, CourseStaffRole(self.course_key), self.staff)
Ejemplo n.º 7
0
 def test_remove_user_from_course_group_permission_denied(self):
     """
     Verifies PermissionDenied if caller of remove_user_from_course_group is not instructor role.
     """
     add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
     another_staff = User.objects.create_user('another', '*****@*****.**', 'foo')
     add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator, self.staff, another_staff)
     with self.assertRaises(PermissionDenied):
         remove_users(self.staff, CourseStaffRole(self.course_key), another_staff)
Ejemplo n.º 8
0
    def make_staff(self):
        """
        create staff user.
        """
        staff = UserFactory.create(password="******")
        role = CourseStaffRole(self.course.id)
        role.add_users(staff)

        return staff
Ejemplo n.º 9
0
    def test_update_and_assign_or_revoke_staff(self):
        """
        Successfully updates existing enrollments to assign or revoke the CourseStaff role.
        """
        course_staff_role = CourseStaffRole(self.course_id)
        course_staff_role.add_users(self.student_2)

        self.create_program_and_course_enrollments('learner-1',
                                                   user=self.student_1)
        self.create_program_and_course_enrollments('learner-2',
                                                   user=self.student_2)
        self.create_program_and_course_enrollments('learner-3', user=None)
        learner_4_enrollment = self.create_program_and_course_enrollments(
            'learner-4', user=None)
        learner_5_enrollment = self.create_program_and_course_enrollments(
            'learner-5', user=None)
        CourseAccessRoleAssignment.objects.create(
            enrollment=learner_4_enrollment,
            role=ProgramCourseEnrollmentRoles.COURSE_STAFF,
        )
        CourseAccessRoleAssignment.objects.create(
            enrollment=learner_5_enrollment,
            role=ProgramCourseEnrollmentRoles.COURSE_STAFF,
        )
        course_enrollment_requests = [
            self.course_enrollment_request('learner-1', CourseStatuses.ACTIVE,
                                           True),
            self.course_enrollment_request('learner-2', CourseStatuses.ACTIVE,
                                           False),
            self.course_enrollment_request('learner-3', CourseStatuses.ACTIVE,
                                           True),
            self.course_enrollment_request('learner-4', CourseStatuses.ACTIVE,
                                           False),
            self.course_enrollment_request('learner-5', CourseStatuses.ACTIVE,
                                           True),
        ]
        write_program_course_enrollments(
            self.program_uuid,
            self.course_id,
            course_enrollment_requests,
            True,
            True,
        )
        # Role is revoked for user's with a linked enrollment
        self.assertListEqual([self.student_1],
                             list(course_staff_role.users_with_role()))

        # CourseAccessRoleAssignment objects are created/revoked for enrollments with no linked user
        pending_role_assingments = CourseAccessRoleAssignment.objects.all()
        assert pending_role_assingments.count() == 2
        pending_role_assingments.get(
            enrollment__program_enrollment__external_user_key='learner-3',
            enrollment__course_key=self.course_id)
        pending_role_assingments.get(
            enrollment__program_enrollment__external_user_key='learner-5',
            enrollment__course_key=self.course_id)
Ejemplo n.º 10
0
    def test_detail_delete_staff(self):
        auth.add_users(self.user, CourseStaffRole(self.course.id), self.ext_user)

        resp = self.client.delete(
            self.detail_url,
            HTTP_ACCEPT="application/json",
        )
        self.assertEqual(resp.status_code, 204)
        # reload user from DB
        ext_user = User.objects.get(email=self.ext_user.email)
        self.assertFalse(auth.user_has_role(ext_user, CourseStaffRole(self.course.id)))
Ejemplo n.º 11
0
 def test_add_users_doesnt_add_duplicate_entry(self):
     """
     Tests that calling add_users multiple times before a single call
     to remove_users does not result in the user remaining in the group.
     """
     role = CourseStaffRole(self.course_key)
     role.add_users(self.student)
     assert role.has_user(self.student)
     # Call add_users a second time, then remove just once.
     role.add_users(self.student)
     role.remove_users(self.student)
     assert not role.has_user(self.student)
Ejemplo n.º 12
0
    def test_staff_cannot_delete_other(self):
        auth.add_users(self.user, CourseStaffRole(self.course.id), self.user, self.ext_user)
        self.user.is_staff = False
        self.user.save()

        resp = self.client.delete(self.detail_url)
        self.assertEqual(resp.status_code, 403)
        result = json.loads(resp.content.decode('utf-8'))
        self.assertIn("error", result)
        # reload user from DB
        ext_user = User.objects.get(email=self.ext_user.email)
        self.assertTrue(auth.user_has_role(ext_user, CourseStaffRole(self.course.id)))
Ejemplo n.º 13
0
    def test_staff_can_delete_self(self):
        auth.add_users(self.user, CourseStaffRole(self.course.id), self.user)
        self.user.is_staff = False
        self.user.save()

        self_url = self.course_team_url(email=self.user.email)

        resp = self.client.delete(self_url)
        self.assertEqual(resp.status_code, 204)
        # reload user from DB
        user = User.objects.get(email=self.user.email)
        self.assertFalse(auth.user_has_role(user, CourseStaffRole(self.course.id)))
Ejemplo n.º 14
0
    def setUp(self):
        super().setUp()
        self.course_staff = UserFactory.create()
        CourseStaffRole(self.verified_course.id).add_users(self.course_staff)
        CourseStaffRole(self.masters_course.id).add_users(self.course_staff)

        # Enroll the user in the two courses
        CourseEnrollmentFactory.create(user=self.course_staff, course_id=self.verified_course.id)
        CourseEnrollmentFactory.create(user=self.course_staff, course_id=self.masters_course.id)

        # Log the staff user in
        self.client.login(username=self.course_staff.username, password=TEST_PASSWORD)
Ejemplo n.º 15
0
    def test_add_user_to_course_group(self):
        """
        Tests adding user to course group (happy path).
        """
        # Create groups for a new course (and assign instructor role to the creator).
        self.assertFalse(user_has_role(self.creator, CourseInstructorRole(self.course_key)))
        add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
        add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator)
        self.assertTrue(user_has_role(self.creator, CourseInstructorRole(self.course_key)))

        # Add another user to the staff role.
        self.assertFalse(user_has_role(self.staff, CourseStaffRole(self.course_key)))
        add_users(self.creator, CourseStaffRole(self.course_key), self.staff)
        self.assertTrue(user_has_role(self.staff, CourseStaffRole(self.course_key)))
Ejemplo n.º 16
0
    def test_course_role(self):
        """
        Test that giving a user a course role enables access appropriately
        """
        assert not CourseStaffRole(self.course_key).has_user(self.student), \
            f'Student has premature access to {self.course_key}'
        CourseStaffRole(self.course_key).add_users(self.student)
        assert CourseStaffRole(self.course_key).has_user(self.student), \
            f"Student doesn't have access to {six.text_type(self.course_key)}"

        # remove access and confirm
        CourseStaffRole(self.course_key).remove_users(self.student)
        assert not CourseStaffRole(self.course_key).has_user(self.student), \
            f'Student still has access to {self.course_key}'
Ejemplo n.º 17
0
    def test_remove_user_from_course_group(self):
        """
        Tests removing user from course group (happy path).
        """
        add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
        add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator)

        add_users(self.creator, CourseStaffRole(self.course_key), self.staff)
        self.assertTrue(user_has_role(self.staff, CourseStaffRole(self.course_key)))

        remove_users(self.creator, CourseStaffRole(self.course_key), self.staff)
        self.assertFalse(user_has_role(self.staff, CourseStaffRole(self.course_key)))

        remove_users(self.creator, CourseInstructorRole(self.course_key), self.creator)
        self.assertFalse(user_has_role(self.creator, CourseInstructorRole(self.course_key)))
    def setUp(self):
        super(MasqueradeTestBase, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
        self.course_staff = UserFactory.create()
        CourseStaffRole(self.verified_course.id).add_users(self.course_staff)
        CourseStaffRole(self.masters_course.id).add_users(self.course_staff)

        # Enroll the user in the two courses
        CourseEnrollmentFactory.create(user=self.course_staff,
                                       course_id=self.verified_course.id)
        CourseEnrollmentFactory.create(user=self.course_staff,
                                       course_id=self.masters_course.id)

        # Log the staff user in
        self.client.login(username=self.course_staff.username,
                          password=TEST_PASSWORD)
Ejemplo n.º 19
0
    def test_create_enrollments_and_assign_staff(self,
                                                 request_user_key_prefix):
        """
        Successfully creates both waiting and linked program course enrollments with the course staff role.
        """
        course_staff_role = CourseStaffRole(self.course_id)
        course_staff_role.add_users(self.student_1)

        self.create_program_enrollment('learner-1', user=None)
        self.create_program_enrollment('learner-2', user=self.student_1)
        self.create_program_enrollment('learner-3', user=self.student_2)

        course_enrollment_requests = [
            self.course_enrollment_request(
                '{}-1'.format(request_user_key_prefix), CourseStatuses.ACTIVE,
                True),
            self.course_enrollment_request(
                '{}-2'.format(request_user_key_prefix), CourseStatuses.ACTIVE,
                True),
            self.course_enrollment_request(
                '{}-3'.format(request_user_key_prefix), CourseStatuses.ACTIVE,
                True),
        ]
        write_program_course_enrollments(
            self.program_uuid,
            self.course_id,
            course_enrollment_requests,
            True,
            True,
        )

        self.assert_program_course_enrollment('learner-1',
                                              CourseStatuses.ACTIVE, False)
        self.assert_program_course_enrollment('learner-2',
                                              CourseStatuses.ACTIVE, True)
        self.assert_program_course_enrollment('learner-3',
                                              CourseStatuses.ACTIVE, True)

        # Users linked to either enrollment are given the course staff role
        self.assertListEqual([self.student_1, self.student_2],
                             list(course_staff_role.users_with_role()))

        # CourseAccessRoleAssignment objects are created for enrollments with no linked user
        pending_role_assingments = CourseAccessRoleAssignment.objects.all()
        assert pending_role_assingments.count() == 1
        pending_role_assingments.get(
            enrollment__program_enrollment__external_user_key='learner-1',
            enrollment__course_key=self.course_id)
Ejemplo n.º 20
0
 def test_remove_user_from_course_group_permission_denied(self):
     """
     Verifies PermissionDenied if caller of remove_user_from_course_group is not instructor role.
     """
     add_users(self.global_admin, CourseInstructorRole(self.course_key),
               self.creator)
     another_staff = UserFactory.create(
         username='******',
         email='*****@*****.**',
         password='******',
     )
     add_users(self.global_admin, CourseStaffRole(self.course_key),
               self.creator, self.staff, another_staff)
     with pytest.raises(PermissionDenied):
         remove_users(self.staff, CourseStaffRole(self.course_key),
                      another_staff)
Ejemplo n.º 21
0
    def setUp(self):
        """
        Add courses with the end date set to various values
        """
        super().setUp()

        # Base course has no end date (so is active)
        self.course.end = None
        self.course.display_name = 'Active Course 1'
        self.ORG = self.course.location.org
        self.save_course()

        # Active course has end date set to tomorrow
        self.active_course = CourseFactory.create(
            display_name='Active Course 2',
            org=self.ORG,
            end=self.TOMORROW,
        )

        # Archived course has end date set to yesterday
        self.archived_course = CourseFactory.create(
            display_name='Archived Course',
            org=self.ORG,
            end=self.YESTERDAY,
        )

        # Base user has global staff access
        self.assertTrue(GlobalStaff().has_user(self.user))

        # Staff user just has course staff access
        self.staff, self.staff_password = self.create_non_staff_user()
        for course in (self.course, self.active_course, self.archived_course):
            CourseStaffRole(course.id).add_users(self.staff)
Ejemplo n.º 22
0
def get_user_permissions(user, course_key, org=None):
    """
    Get the bitmask of permissions that this user has in the given course context.
    Can also set course_key=None and pass in an org to get the user's
    permissions for that organization as a whole.
    """
    if org is None:
        org = course_key.org
        course_key = course_key.for_branch(None)
    else:
        assert course_key is None
    # No one has studio permissions for CCX courses
    if is_ccx_course(course_key):
        return STUDIO_NO_PERMISSIONS
    all_perms = STUDIO_EDIT_ROLES | STUDIO_VIEW_USERS | STUDIO_EDIT_CONTENT | STUDIO_VIEW_CONTENT
    # global staff, org instructors, and course instructors have all permissions:
    if GlobalStaff().has_user(user) or OrgInstructorRole(org=org).has_user(user):
        return all_perms
    if course_key and user_has_role(user, CourseInstructorRole(course_key)):
        return all_perms
    # Staff have all permissions except EDIT_ROLES:
    if OrgStaffRole(org=org).has_user(user) or (course_key and user_has_role(user, CourseStaffRole(course_key))):
        return STUDIO_VIEW_USERS | STUDIO_EDIT_CONTENT | STUDIO_VIEW_CONTENT
    # Otherwise, for libraries, users can view only:
    if course_key and isinstance(course_key, LibraryLocator):
        if OrgLibraryUserRole(org=org).has_user(user) or user_has_role(user, LibraryUserRole(course_key)):
            return STUDIO_VIEW_USERS | STUDIO_VIEW_CONTENT
    return STUDIO_NO_PERMISSIONS
Ejemplo n.º 23
0
 def test_no_duplicate_emails_staff_instructor(self):
     """
     Test that no duplicate emails are sent to a course instructor that is
     also course staff
     """
     CourseStaffRole(self.course.id).add_users(self.instructor)
     self.test_send_to_all()
Ejemplo n.º 24
0
    def test_add_master_course_staff_to_ccx(self):
        """
        Test add staff of master course to ccx course
        """
        # adding staff to master course.
        staff = self.make_staff()
        assert CourseStaffRole(self.course.id).has_user(staff)

        # adding instructor to master course.
        instructor = self.make_instructor()
        assert CourseInstructorRole(self.course.id).has_user(instructor)

        add_master_course_staff_to_ccx(self.course, self.ccx_locator,
                                       self.ccx.display_name)

        # assert that staff and instructors of master course has staff and instructor roles on ccx
        list_staff_master_course = list_with_level(self.course.id, 'staff')
        list_instructor_master_course = list_with_level(
            self.course.id, 'instructor')

        with ccx_course(self.ccx_locator) as course_ccx:
            list_staff_ccx_course = list_with_level(course_ccx.id, 'staff')
            assert len(list_staff_master_course) == len(list_staff_ccx_course)
            assert list_staff_master_course[0].email == list_staff_ccx_course[
                0].email

            list_instructor_ccx_course = list_with_level(
                course_ccx.id, 'instructor')
            assert len(list_instructor_ccx_course) == len(
                list_instructor_master_course)
            assert list_instructor_ccx_course[
                0].email == list_instructor_master_course[0].email
Ejemplo n.º 25
0
    def test_remove_master_course_staff_from_ccx_display_name(self):
        """
        Test remove role of staff of master course on ccx course.
        Specific test to check that a passed display name is in the
        subject of the email sent to the unenrolled users.
        """
        staff = self.make_staff()
        assert CourseStaffRole(self.course.id).has_user(staff)

        # adding instructor to master course.
        instructor = self.make_instructor()
        assert CourseInstructorRole(self.course.id).has_user(instructor)
        outbox = self.get_outbox()
        add_master_course_staff_to_ccx(self.course,
                                       self.ccx_locator,
                                       self.ccx.display_name,
                                       send_email=False)
        # create a unique display name
        display_name = f'custom_display_{uuid.uuid4()}'
        list_staff_master_course = list_with_level(self.course.id, 'staff')
        list_instructor_master_course = list_with_level(
            self.course.id, 'instructor')
        assert len(outbox) == 0
        # give access to the course staff/instructor
        remove_master_course_staff_from_ccx(self.course, self.ccx_locator,
                                            display_name)
        assert len(outbox) == (len(list_staff_master_course) +
                               len(list_instructor_master_course))
        for email in outbox:
            assert display_name in email.subject
Ejemplo n.º 26
0
    def test_add_master_course_staff_to_ccx_with_exception(self):
        """
        When exception raise from ``enroll_email`` assert that enrollment skipped for that staff or
        instructor.
        """
        staff = self.make_staff()
        assert CourseStaffRole(self.course.id).has_user(staff)

        # adding instructor to master course.
        instructor = self.make_instructor()
        assert CourseInstructorRole(self.course.id).has_user(instructor)

        with mock.patch.object(CourseEnrollment,
                               'enroll_by_email',
                               side_effect=CourseEnrollmentException()):
            add_master_course_staff_to_ccx(self.course, self.ccx_locator,
                                           self.ccx.display_name)

            assert not CourseEnrollment.objects.filter(
                course_id=self.ccx_locator, user=staff).exists()
            assert not CourseEnrollment.objects.filter(
                course_id=self.ccx_locator, user=instructor).exists()

        with mock.patch.object(CourseEnrollment,
                               'enroll_by_email',
                               side_effect=SMTPException()):
            add_master_course_staff_to_ccx(self.course, self.ccx_locator,
                                           self.ccx.display_name)

            assert not CourseEnrollment.objects.filter(
                course_id=self.ccx_locator, user=staff).exists()
            assert not CourseEnrollment.objects.filter(
                course_id=self.ccx_locator, user=instructor).exists()
Ejemplo n.º 27
0
class RoleCacheTestCase(TestCase):  # lint-amnesty, pylint: disable=missing-class-docstring

    IN_KEY = CourseKey.from_string('edX/toy/2012_Fall')
    NOT_IN_KEY = CourseKey.from_string('edX/toy/2013_Fall')

    ROLES = (
        (CourseStaffRole(IN_KEY), ('staff', IN_KEY, 'edX')),
        (CourseInstructorRole(IN_KEY), ('instructor', IN_KEY, 'edX')),
        (OrgStaffRole(IN_KEY.org), ('staff', None, 'edX')),
        (OrgInstructorRole(IN_KEY.org), ('instructor', None, 'edX')),
        (CourseBetaTesterRole(IN_KEY), ('beta_testers', IN_KEY, 'edX')),
    )

    def setUp(self):
        super(RoleCacheTestCase, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
        self.user = UserFactory()

    @ddt.data(*ROLES)
    @ddt.unpack
    def test_only_in_role(self, role, target):
        role.add_users(self.user)
        cache = RoleCache(self.user)
        assert cache.has_role(*target)

        for other_role, other_target in self.ROLES:
            if other_role == role:
                continue

            assert not cache.has_role(*other_target)

    @ddt.data(*ROLES)
    @ddt.unpack
    def test_empty_cache(self, role, target):  # lint-amnesty, pylint: disable=unused-argument
        cache = RoleCache(self.user)
        assert not cache.has_role(*target)
Ejemplo n.º 28
0
    def get_users(self, course_id, user_id=None):
        """
        Gets the users for a given target.

        Result is returned in the form of a queryset, and may contain duplicates.
        """
        staff_qset = CourseStaffRole(course_id).users_with_role()
        instructor_qset = CourseInstructorRole(course_id).users_with_role()
        staff_instructor_qset = (staff_qset | instructor_qset)
        enrollment_query = models.Q(is_active=True,
                                    courseenrollment__course_id=course_id,
                                    courseenrollment__is_active=True)
        enrollment_qset = User.objects.filter(enrollment_query)
        if self.target_type == SEND_TO_MYSELF:
            if user_id is None:
                raise ValueError(
                    "Must define self user to send email to self.")
            user = User.objects.filter(id=user_id)
            return use_read_replica_if_available(user)
        elif self.target_type == SEND_TO_STAFF:
            return use_read_replica_if_available(staff_instructor_qset)
        elif self.target_type == SEND_TO_LEARNERS:
            return use_read_replica_if_available(
                enrollment_qset.exclude(id__in=staff_instructor_qset))
        elif self.target_type == SEND_TO_COHORT:
            return self.cohorttarget.cohort.users.filter(
                id__in=enrollment_qset)  # lint-amnesty, pylint: disable=no-member
        elif self.target_type == SEND_TO_TRACK:
            return use_read_replica_if_available(
                User.objects.filter(
                    models.Q(courseenrollment__mode=self.coursemodetarget.
                             track.mode_slug)
                    & enrollment_query))
        else:
            raise ValueError(f"Unrecognized target type {self.target_type}")
Ejemplo n.º 29
0
    def delete(self, request, course_key_string):
        course_key = CourseKey.from_string(course_key_string)

        email = request.data.get("email", None)
        validate_param_exist(email, "email")

        try:
            user = User.objects.get(email=email)
        except Exception:  # pylint: disable=broad-except
            msg = {
                "error":
                "Could not find user by email address '{email}'".format(
                    email=email)
            }
            return Response(msg, 404)

        auth.get_user_permissions(request.user, course_key)

        auth.remove_users(request.user, CourseStaffRole(course_key), user)
        auth.remove_users(request.user, CourseInstructorRole(course_key), user)

        CourseEnrollment.unenroll(user, course_key)

        msg = "'{email}''s permissions are revoked from '{course_key}'".format(
            email=email, course_key=course_key)
        log.info(msg)

        return Response(
            {'message': "User is removed from {}.".format(course_key)})
Ejemplo n.º 30
0
    def test_add_master_course_staff_to_ccx_display_name(self):
        """
        Test add staff of master course to ccx course.
        Specific test to check that a passed display name is in the
        subject of the email sent to the enrolled users.
        """
        staff = self.make_staff()
        self.assertTrue(CourseStaffRole(self.course.id).has_user(staff))

        # adding instructor to master course.
        instructor = self.make_instructor()
        self.assertTrue(
            CourseInstructorRole(self.course.id).has_user(instructor))
        outbox = self.get_outbox()
        # create a unique display name
        display_name = 'custom_display_{}'.format(uuid.uuid4())
        list_staff_master_course = list_with_level(self.course, 'staff')
        list_instructor_master_course = list_with_level(
            self.course, 'instructor')
        self.assertEqual(len(outbox), 0)
        # give access to the course staff/instructor
        add_master_course_staff_to_ccx(self.course, self.ccx_locator,
                                       display_name)
        self.assertEqual(
            len(outbox),
            len(list_staff_master_course) + len(list_instructor_master_course))
        for email in outbox:
            self.assertIn(display_name, email.subject)