Пример #1
0
def _has_access_to_course(user, access_level, course_key):
    '''
    Returns True if the given user has access_level (= staff or
    instructor) access to the course with the given course_key.
    This ensures the user is authenticated and checks if global staff or has
    staff / instructor access.

    access_level = string, either "staff" or "instructor"
    '''
    if user is None or (not user.is_authenticated()):
        debug("Deny: no user or anon user")
        return False

    if is_masquerading_as_student(user):
        return False

    if GlobalStaff().has_user(user):
        debug("Allow: user.is_staff")
        return True

    if access_level not in ('staff', 'instructor'):
        log.debug("Error in access._has_access_to_course access_level=%s unknown", access_level)
        debug("Deny: unknown access level")
        return False

    staff_access = (
        CourseStaffRole(course_key).has_user(user) or
        OrgStaffRole(course_key.org).has_user(user)
    )

    if staff_access and access_level == 'staff':
        debug("Allow: user has course staff access")
        return True

    instructor_access = (
        CourseInstructorRole(course_key).has_user(user) or
        OrgInstructorRole(course_key.org).has_user(user)
    )

    if instructor_access and access_level in ('staff', 'instructor'):
        debug("Allow: user has course instructor access")
        return True

    debug("Deny: user did not have correct access")
    return False
Пример #2
0
    def test_data(self, expected_pacing_type, self_paced):
        start = datetime.datetime.now(pytz.UTC)
        end = start + datetime.timedelta(days=30)
        enrollment_start = start - datetime.timedelta(days=7)
        enrollment_end = end - datetime.timedelta(days=14)

        course = CourseFactory(
            start=start,
            end=end,
            enrollment_start=enrollment_start,
            enrollment_end=enrollment_end,
            self_paced=self_paced
        )
        instructor = UserFactory()
        CourseInstructorRole(course.id).add_users(instructor)
        staff = UserFactory()
        CourseStaffRole(course.id).add_users(staff)

        request = RequestFactory().get('')
        serializer = CourseRunSerializer(course, context={'request': request})
        expected = {
            'id': str(course.id),
            'title': course.display_name,
            'schedule': {
                'start': serialize_datetime(start),
                'end': serialize_datetime(end),
                'enrollment_start': serialize_datetime(enrollment_start),
                'enrollment_end': serialize_datetime(enrollment_end),
            },
            'team': [
                {
                    'user': instructor.username,
                    'role': 'instructor',
                },
                {
                    'user': staff.username,
                    'role': 'staff',
                },
            ],
            'images': {
                'card_image': request.build_absolute_uri(course_image_url(course)),
            },
            'pacing_type': expected_pacing_type,
        }
        assert serializer.data == expected
Пример #3
0
def _get_recipient_querysets(user_id, to_option, course_id):
    """
    Returns a list of query sets of email recipients corresponding to the
    requested `to_option` category.

    `to_option` is either SEND_TO_MYSELF, SEND_TO_STAFF, or SEND_TO_ALL.

    Recipients who are in more than one category (e.g. enrolled in the course
    and are staff or self) will be properly deduped.
    """
    if to_option not in TO_OPTIONS:
        log.error("Unexpected bulk email TO_OPTION found: %s", to_option)
        raise Exception(
            "Unexpected bulk email TO_OPTION found: {0}".format(to_option))

    if to_option == SEND_TO_MYSELF:
        user = User.objects.filter(id=user_id)
        return [use_read_replica_if_available(user)]
    else:
        staff_qset = CourseStaffRole(course_id).users_with_role()
        instructor_qset = CourseInstructorRole(course_id).users_with_role()
        staff_instructor_qset = (staff_qset | instructor_qset).distinct()
        if to_option == SEND_TO_STAFF:
            return [use_read_replica_if_available(staff_instructor_qset)]

        if to_option == SEND_TO_ALL:
            # We also require students to have activated their accounts to
            # provide verification that the provided email address is valid.
            enrollment_qset = User.objects.filter(
                is_active=True,
                courseenrollment__course_id=course_id,
                courseenrollment__is_active=True)

            # to avoid duplicates, we only want to email unenrolled course staff
            # members here
            unenrolled_staff_qset = staff_instructor_qset.exclude(
                courseenrollment__course_id=course_id,
                courseenrollment__is_active=True)

            # use read_replica if available
            recipient_qsets = [
                use_read_replica_if_available(unenrolled_staff_qset),
                use_read_replica_if_available(enrollment_qset),
            ]
            return recipient_qsets
Пример #4
0
def manage_library_users(request, library_key_string):
    """
    Studio UI for editing the users within a library.

    Uses the /course_team/:library_key/:user_email/ REST API to make changes.
    """
    library_key = CourseKey.from_string(library_key_string)
    if not isinstance(library_key, LibraryLocator):
        raise Http404  # This is not a library
    user_perms = get_user_permissions(request.user, library_key)
    if not user_perms & STUDIO_VIEW_USERS:
        raise PermissionDenied()
    library = modulestore().get_library(library_key)
    if library is None:
        raise Http404

    # Segment all the users explicitly associated with this library, ensuring each user only has one role listed:
    instructors = set(CourseInstructorRole(library_key).users_with_role())
    staff = set(CourseStaffRole(library_key).users_with_role()) - instructors
    users = set(
        LibraryUserRole(library_key).users_with_role()) - instructors - staff

    formatted_users = []
    for user in instructors:
        formatted_users.append(user_with_role(user, 'instructor'))
    for user in staff:
        formatted_users.append(user_with_role(user, 'staff'))
    for user in users:
        formatted_users.append(user_with_role(user, 'library_user'))

    return render_to_response(
        'manage_users_lib.html', {
            'context_library':
            library,
            'users':
            formatted_users,
            'allow_actions':
            bool(user_perms & STUDIO_EDIT_ROLES),
            'library_key':
            unicode(library_key),
            'lib_users_url':
            reverse_library_url('manage_library_users', library_key_string),
            'show_children_previews':
            library.show_children_previews
        })
Пример #5
0
    def setUp(self):
        clear_existing_modulestores()
        self.toy = modulestore().get_course("edX/toy/2012_Fall")

        # Create two accounts
        self.student = '*****@*****.**'
        self.instructor = '*****@*****.**'
        self.password = '******'
        self.create_account('u1', self.student, self.password)
        self.create_account('u2', self.instructor, self.password)
        self.activate_user(self.student)
        self.activate_user(self.instructor)

        CourseStaffRole(self.toy.location).add_users(User.objects.get(email=self.instructor))

        self.logout()
        self.login(self.instructor, self.password)
        self.enroll(self.toy)
Пример #6
0
    def setUp(self):
        """
        Set up tests
        """
        super(TestCoachDashboard, self).setUp()
        # Login with the instructor account
        self.client.login(username=self.coach.username, password="******")

        # adding staff to master course.
        staff = UserFactory()
        allow_access(self.course, staff, 'staff')
        self.assertTrue(CourseStaffRole(self.course.id).has_user(staff))

        # adding instructor to master course.
        instructor = UserFactory()
        allow_access(self.course, instructor, 'instructor')
        self.assertTrue(
            CourseInstructorRole(self.course.id).has_user(instructor))
Пример #7
0
    def test_authorization_no_oauth_staff(self):
        """
        Check authorization for staff users logged in without oauth
        """
        # create a staff user
        staff_user = User.objects.create_user('test_staff_user',
                                              '*****@*****.**',
                                              'test')
        # add staff role to the staff user
        CourseStaffRole(self.master_course_key).add_users(staff_user)

        data = {'display_name': 'CCX Title'}
        # the staff user can perform the request
        self.client.login(username=staff_user.username, password='******')
        resp = self.client.get(self.detail_url)
        self.assertEqual(resp.status_code, status.HTTP_200_OK)
        resp = self.client.patch(self.detail_url, data, format='json')
        self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT)
Пример #8
0
    def test_render_html_view_with_preview_mode_when_user_already_has_cert(
            self):
        """
        test certificate web view should render properly in
        preview mode even if user who is previewing already has a certificate
        generated with different mode.
        """
        self._add_course_certificates(count=1, signatory_count=2)
        CourseStaffRole(self.course.id).add_users(self.user)

        test_url = get_certificate_url(user_id=self.user.id,
                                       course_id=unicode(self.course.id))
        # user has already has certificate generated for 'honor' mode
        # so let's try to preview in 'verified' mode.
        response = self.client.get(test_url + '?preview=verified')
        self.assertNotIn(self.course.display_name, response.content)
        self.assertIn('course_title_0', response.content)
        self.assertIn('Signatory_Title 0', response.content)
Пример #9
0
    def create_staff_context(self):
        """
        Create staff user and course blocks accessible by that user
        """
        # Create a staff user to be able to test visible_to_staff_only
        staff_user = UserFactory.create()
        CourseStaffRole(self.course.location.course_key).add_users(staff_user)

        block_structure = get_course_blocks(
            staff_user,
            self.course.location,
            self.transformers,
        )
        return {
            'request': MagicMock(),
            'block_structure': block_structure,
            'requested_fields': ['type'],
        }
Пример #10
0
def assign_staff_role_to_ccx(ccx_locator, user, master_course_id):
    """
    Check if user has ccx_coach role on master course then assign him staff role on ccx only
    if role is not already assigned. Because of this coach can open dashboard from master course
    as well as ccx.
    :param ccx_locator: CCX key
    :param user: User to whom we want to assign role.
    :param master_course_id: Master course key
    """
    coach_role_on_master_course = CourseCcxCoachRole(master_course_id)
    # check if user has coach role on master course
    if coach_role_on_master_course.has_user(user):
        # Check if user has staff role on ccx.
        role = CourseStaffRole(ccx_locator)
        if not role.has_user(user):
            # assign user the staff role on ccx
            with ccx_course(ccx_locator) as course:
                allow_access(course, user, "staff", send_email=False)
Пример #11
0
    def get(self, request):
        """Displays course Enrollment and staffing course statistics"""

        if not request.user.is_staff:
            raise Http404
        data = []

        courses = self.get_courses()

        for (cdir, course) in courses.items():  # pylint: disable=unused-variable
            datum = [course.display_name, course.id]
            datum += [
                CourseEnrollment.objects.filter(course_id=course.id).count()
            ]
            datum += [
                CourseStaffRole(course.location).users_with_role().count()
            ]
            datum += [
                ','.join([
                    x.username for x in CourseInstructorRole(
                        course.location).users_with_role()
                ])
            ]
            data.append(datum)

        datatable = dict(header=[
            _('Course Name'),
            _('course_id'),
            _('# enrolled'),
            _('# staff'),
            _('instructors')
        ],
                         title=_('Enrollment information for all courses'),
                         data=data)
        context = {
            'datatable': datatable,
            'msg': self.msg,
            'djangopid': os.getpid(),
            'modeflag': {
                'staffing': 'active-section'
            },
            'mitx_version': getattr(settings, 'VERSION_STRING', ''),
        }
        return render_to_response(self.template_name, context)
Пример #12
0
    def test_create_enrollments_and_assign_staff(self):
        """
        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('learner-1', CourseStatuses.ACTIVE,
                                           True),
            self.course_enrollment_request('learner-2', CourseStatuses.ACTIVE,
                                           True),
            self.course_enrollment_request('learner-3', 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)
Пример #13
0
def delete_course_and_groups(course_id, user_id):
    """
    This deletes the courseware associated with a course_id as well as cleaning update_item
    the various user table stuff (groups, permissions, etc.)
    """
    module_store = modulestore()

    with module_store.bulk_write_operations(course_id):
        module_store.delete_course(course_id, user_id)

        print 'removing User permissions from course....'
        # in the django layer, we need to remove all the user permissions groups associated with this course
        try:
            staff_role = CourseStaffRole(course_id)
            staff_role.remove_users(*staff_role.users_with_role())
            instructor_role = CourseInstructorRole(course_id)
            instructor_role.remove_users(*instructor_role.users_with_role())
        except Exception as err:
            log.error("Error in deleting course groups for {0}: {1}".format(course_id, err))
Пример #14
0
    def test_remove_master_course_staff_from_ccx_no_email(self):
        """
        Test remove role of staff of master course on ccx course without
        sending enrollment email.
        """
        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()
        self.assertEqual(len(outbox), 0)
        remove_master_course_staff_from_ccx(self.course,
                                            self.ccx_locator,
                                            self.ccx.display_name,
                                            send_email=False)
        self.assertEqual(len(outbox), 0)
Пример #15
0
    def setUp(self):
        super(TestStaffOnCCX, self).setUp()

        # Create instructor account
        self.client.login(username=self.coach.username, password="******")

        # create an instance of modulestore
        self.mstore = modulestore()

        # adding staff to master course.
        staff = UserFactory()
        allow_access(self.course, staff, 'staff')
        self.assertTrue(CourseStaffRole(self.course.id).has_user(staff))

        # adding instructor to master course.
        instructor = UserFactory()
        allow_access(self.course, instructor, 'instructor')
        self.assertTrue(
            CourseInstructorRole(self.course.id).has_user(instructor))
    def test_add_master_course_staff_to_ccx_idempotent(self):
        """
        Test add staff of master course to ccx course multiple time will
        not result in multiple enrollments.
        """
        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()
        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)

        # run the assignment the first time
        add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name)
        self.assertEqual(len(outbox), len(list_staff_master_course) + len(list_instructor_master_course))
        with ccx_course(self.ccx_locator) as course_ccx:
            list_staff_ccx_course = list_with_level(course_ccx, 'staff')
            list_instructor_ccx_course = list_with_level(course_ccx, 'instructor')
        self.assertEqual(len(list_staff_master_course), len(list_staff_ccx_course))
        for user in list_staff_master_course:
            self.assertIn(user, list_staff_ccx_course)
        self.assertEqual(len(list_instructor_master_course), len(list_instructor_ccx_course))
        for user in list_instructor_master_course:
            self.assertIn(user, list_instructor_ccx_course)

        # run the assignment again
        add_master_course_staff_to_ccx(self.course, self.ccx_locator, self.ccx.display_name)
        # there are no new duplicated email
        self.assertEqual(len(outbox), len(list_staff_master_course) + len(list_instructor_master_course))
        # there are no duplicated staffs
        with ccx_course(self.ccx_locator) as course_ccx:
            list_staff_ccx_course = list_with_level(course_ccx, 'staff')
            list_instructor_ccx_course = list_with_level(course_ccx, 'instructor')
        self.assertEqual(len(list_staff_master_course), len(list_staff_ccx_course))
        for user in list_staff_master_course:
            self.assertIn(user, list_staff_ccx_course)
        self.assertEqual(len(list_instructor_master_course), len(list_instructor_ccx_course))
        for user in list_instructor_master_course:
            self.assertIn(user, list_instructor_ccx_course)
Пример #17
0
def _get_recipient_queryset(user_id, to_option, course_id):
    """
    Returns a query set of email recipients corresponding to the requested to_option category.

    `to_option` is either SEND_TO_MYSELF, SEND_TO_STAFF, or SEND_TO_ALL.

    Recipients who are in more than one category (e.g. enrolled in the course and are staff or self)
    will be properly deduped.
    """
    if to_option not in TO_OPTIONS:
        log.error("Unexpected bulk email TO_OPTION found: %s", to_option)
        raise Exception(
            "Unexpected bulk email TO_OPTION found: {0}".format(to_option))

    if to_option == SEND_TO_MYSELF:
        recipient_qset = User.objects.filter(id=user_id)
    else:
        staff_qset = CourseStaffRole(course_id).users_with_role()
        instructor_qset = CourseInstructorRole(course_id).users_with_role()
        recipient_qset = (staff_qset | instructor_qset).distinct()
        if to_option == SEND_TO_ALL:
            # We also require students to have activated their accounts to
            # provide verification that the provided email address is valid.
            enrollment_qset = User.objects.filter(
                is_active=True,
                courseenrollment__course_id=course_id,
                courseenrollment__is_active=True)
            # Now we do some queryset sidestepping to avoid doing a DISTINCT
            # query across the course staff and the enrolled students, which
            # forces the creation of a temporary table in the db.
            unenrolled_staff_qset = recipient_qset.exclude(
                courseenrollment__course_id=course_id,
                courseenrollment__is_active=True)
            # use read_replica if available:
            unenrolled_staff_qset = use_read_replica_if_available(
                unenrolled_staff_qset)

            unenrolled_staff_ids = [user.id for user in unenrolled_staff_qset]
            recipient_qset = enrollment_qset | User.objects.filter(
                id__in=unenrolled_staff_ids)

    # again, use read_replica if available to lighten the load for large queries
    return use_read_replica_if_available(recipient_qset)
Пример #18
0
    def setUpClass(cls):
        super(TeamAccessTests, cls).setUpClass()
        cls.user_audit = UserFactory.create(username='******')
        cls.user_staff = UserFactory.create(username='******')
        cls.user_masters = UserFactory.create(username='******')
        cls.user_unenrolled = UserFactory.create(username='******')
        cls.users = {
            'user_audit': cls.user_audit,
            'user_staff': cls.user_staff,
            'user_masters': cls.user_masters,
            'user_unenrolled': cls.user_unenrolled,
        }

        for user in (cls.user_audit, cls.user_staff):
            CourseEnrollmentFactory.create(user=user, course_id=COURSE_KEY1)
        CourseEnrollmentFactory.create(user=cls.user_masters,
                                       course_id=COURSE_KEY1,
                                       mode=CourseMode.MASTERS)

        CourseStaffRole(COURSE_KEY1).add_users(cls.user_staff)

        cls.topic_id = 'RANDOM TOPIC'
        cls.team_unprotected_1 = CourseTeamFactory(
            course_id=COURSE_KEY1,
            topic_id=cls.topic_id,
            team_id='team_unprotected_1')
        cls.team_unprotected_2 = CourseTeamFactory(
            course_id=COURSE_KEY1,
            topic_id=cls.topic_id,
            team_id='team_unprotected_2')
        cls.team_unprotected_3 = CourseTeamFactory(
            course_id=COURSE_KEY1,
            topic_id=cls.topic_id,
            team_id='team_unprotected_3')
        cls.team_protected_1 = CourseTeamFactory(course_id=COURSE_KEY1,
                                                 team_id='team_protected_1',
                                                 topic_id=cls.topic_id,
                                                 organization_protected=True)
        cls.team_protected_2 = CourseTeamFactory(course_id=COURSE_KEY1,
                                                 team_id='team_protected_2',
                                                 topic_id=cls.topic_id,
                                                 organization_protected=True)
Пример #19
0
    def setUp(self):
        super(TestEolCourseEmailView, self).setUp()
        # create a course
        self.course = CourseFactory.create(org='mss',
                                           course='999',
                                           display_name='eol course email')

        # Create users, enroll
        self.users = [UserFactory.create() for _ in range(USER_COUNT)]
        for user in self.users:
            CourseEnrollmentFactory.create(user=user, course_id=self.course.id)

        # Patch the comment client user save method so it does not try
        # to create a new cc user when creating a django user
        with patch('student.models.cc.User.save'):
            # Create the student
            self.student = UserFactory(username='******',
                                       password='******',
                                       email='*****@*****.**')
            # Enroll the student in the course
            CourseEnrollmentFactory(user=self.student,
                                    course_id=self.course.id)

            # Create and Enroll staff user
            self.staff_user = UserFactory(username='******',
                                          password='******',
                                          email='*****@*****.**',
                                          is_staff=True)
            CourseEnrollmentFactory(user=self.staff_user,
                                    course_id=self.course.id)
            CourseStaffRole(self.course.id).add_users(self.staff_user)

            # Log the student in
            self.client = Client()
            self.assertTrue(
                self.client.login(username='******', password='******'))

            # Log the user staff in
            self.staff_client = Client()
            self.assertTrue(
                self.staff_client.login(username='******',
                                        password='******'))
Пример #20
0
    def setUp(self):
        """
        Add courses with the end date set to various values
        """
        super(TestCourseIndexArchived, self).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)

        # Make sure we've cached data which could change the query counts
        # depending on test execution order
        WaffleSwitchNamespace(name=COURSE_WAFFLE_NAMESPACE).is_enabled(
            u'enable_global_staff_optimization')
        WaffleSwitchNamespace(
            name=STUDIO_WAFFLE_NAMESPACE).is_enabled(u'enable_policy_page')
        WaffleSwitchNamespace(name=DJANGO_UTILS_NAMESPACE).is_enabled(
            u'enable_memory_middleware')
Пример #21
0
    def test_course_staff_courses_with_claims(self):
        CourseStaffRole(self.course_key).add_users(self.user)

        course_id = unicode(self.course_key)
        nonexistent_course_id = 'some/other/course'

        claims = {
            'staff_courses': {
                'values': [course_id, nonexistent_course_id],
                'essential': True,
            }
        }

        scopes, claims = self.get_id_token_values(scope='openid course_staff', claims=claims)

        self.assertIn('course_staff', scopes)
        self.assertIn('staff_courses', claims)
        self.assertEqual(len(claims['staff_courses']), 1)
        self.assertIn(course_id, claims['staff_courses'])
        self.assertNotIn(nonexistent_course_id, claims['staff_courses'])
Пример #22
0
    def test_access_course_team_users(self):
        """
        Test that members of the course team do not lose access to graded content
        """
        # There are two types of course team members: instructor and staff
        # they have different privileges, but for the purpose of this test the important thing is that they should both
        # have access to all graded content
        instructor = UserFactory.create()
        CourseInstructorRole(self.course.id).add_users(instructor)
        staff = UserFactory.create()
        CourseStaffRole(self.course.id).add_users(staff)

        # assert that all course team members have access to graded content
        for course_team_member in [instructor, staff]:
            self._assert_block_is_gated(
                block=self.blocks_dict['problem'],
                user_id=course_team_member.id,
                course=self.course,
                is_gated=False
            )
Пример #23
0
def _manage_users(request, locator):
    """
    This view will return all CMS users who are editors for the specified course
    """
    old_location = loc_mapper().translate_locator_to_location(locator)

    # check that logged in user has permissions to this item
    if not has_course_access(request.user, locator):
        raise PermissionDenied()

    course_module = modulestore().get_item(old_location)
    instructors = CourseInstructorRole(locator).users_with_role()
    # the page only lists staff and assumes they're a superset of instructors. Do a union to ensure.
    staff = set(CourseStaffRole(locator).users_with_role()).union(instructors)
    return render_to_response('manage_users.html', {
        'context_course': course_module,
        'staff': staff,
        'instructors': instructors,
        'allow_actions': has_course_access(request.user, locator, role=CourseInstructorRole),
    })
Пример #24
0
    def setUp(self):
        self.toy = CourseFactory.create(org='edX',
                                        course='toy',
                                        display_name='2012_Fall')

        # Create two accounts
        self.student = '*****@*****.**'
        self.instructor = '*****@*****.**'
        self.password = '******'
        self.create_account('u1', self.student, self.password)
        self.create_account('u2', self.instructor, self.password)
        self.activate_user(self.student)
        self.activate_user(self.instructor)

        CourseStaffRole(self.toy.id).add_users(
            User.objects.get(email=self.instructor))

        self.logout()
        self.login(self.instructor, self.password)
        self.enroll(self.toy)
Пример #25
0
def has_team_api_access(user, course_key, access_username=None):
    """Returns True if the user has access to the Team API for the course
    given by `course_key`. The user must either be enrolled in the course,
    be course staff, or be global staff.

    Args:
      user (User): The user to check access for.
      course_key (CourseKey): The key to the course which we are checking access to.
      access_username (string): If provided, access_username must match user.username for non staff access.

    Returns:
      bool: True if the user has access, False otherwise.
    """
    if user.is_staff:
        return True
    if CourseStaffRole(course_key).has_user(user):
        return True
    if not access_username or access_username == user.username:
        return CourseEnrollment.is_enrolled(user, course_key)
    return False
Пример #26
0
    def test_staff_csv(self):
        """Download and validate staff CSV"""

        self._setstaff_login()
        self._add_edx4edx()

        def_ms = modulestore()
        course = def_ms.get_course(SlashSeparatedCourseKey('MITx', 'edx4edx', 'edx4edx'))
        CourseStaffRole(course.id).add_users(self.user)

        response = self.client.post(reverse('sysadmin_staffing'),
                                    {'action': 'get_staff_csv', })
        self.assertIn('attachment', response['Content-Disposition'])
        self.assertEqual('text/csv', response['Content-Type'])
        columns = [_('course_id'), _('role'), _('username'),
                   _('email'), _('full_name'), ]
        self.assertIn(','.join('"' + c + '"' for c in columns),
                      response.content)

        self._rm_edx4edx()
Пример #27
0
    def setUp(self):
        """
        Set up a simple course for testing basic grading functionality.
        """
        super(TestRawGradeCSV, self).setUp()

        self.instructor = '*****@*****.**'
        self.student_user2 = self.create_account('u2', self.instructor, self.password)
        self.activate_user(self.instructor)
        CourseStaffRole(self.course.id).add_users(User.objects.get(email=self.instructor))
        self.logout()
        self.login(self.instructor, self.password)
        self.enroll(self.course)

        # set up a simple course with four problems
        self.homework = self.add_graded_section_to_course('homework', late=False, reset=False, showanswer=False)
        self.add_dropdown_to_section(self.homework.location, 'p1', 1)
        self.add_dropdown_to_section(self.homework.location, 'p2', 1)
        self.add_dropdown_to_section(self.homework.location, 'p3', 1)
        self.refresh_course()
Пример #28
0
    def test_enrollment_limit(self):
        """
        Assert that in a course with max student limit set to 1, we can enroll staff and instructor along with
        student. To make sure course full check excludes staff and instructors.
        """
        self.assertEqual(self.course_limited.max_student_enrollments_allowed, 1)
        user1 = UserFactory.create(username="******", email="*****@*****.**", password="******")
        user2 = UserFactory.create(username="******", email="*****@*****.**", password="******")

        # create staff on course.
        staff = UserFactory.create(username="******", email="*****@*****.**", password="******")
        role = CourseStaffRole(self.course_limited.id)
        role.add_users(staff)

        # create instructor on course.
        instructor = UserFactory.create(username="******", email="*****@*****.**", password="******")
        role = CourseInstructorRole(self.course_limited.id)
        role.add_users(instructor)

        CourseEnrollment.enroll(staff, self.course_limited.id, check_access=True)
        CourseEnrollment.enroll(instructor, self.course_limited.id, check_access=True)

        self.assertTrue(
            CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=staff).exists()
        )

        self.assertTrue(
            CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=instructor).exists()
        )

        CourseEnrollment.enroll(user1, self.course_limited.id, check_access=True)
        self.assertTrue(
            CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=user1).exists()
        )

        with self.assertRaises(CourseFullError):
            CourseEnrollment.enroll(user2, self.course_limited.id, check_access=True)

        self.assertFalse(
            CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=user2).exists()
        )
Пример #29
0
 def has_permission(self, request, view):
     """
     This method is assuming that a `master_course_id` parameter
     is available in the request as a GET parameter, a POST parameter
     or it is in the JSON payload included in the request.
     The reason is because this permission class is going
     to check if the user making the request is an instructor
     for the specified course.
     """
     master_course_id = (request.GET.get('master_course_id')
                         or request.POST.get('master_course_id')
                         or request.data.get('master_course_id'))
     if master_course_id is not None:
         try:
             course_key = CourseKey.from_string(master_course_id)
         except InvalidKeyError:
             raise Http404()
         return (hasattr(request, 'user') and
                 (CourseInstructorRole(course_key).has_user(request.user)
                  or CourseStaffRole(course_key).has_user(request.user)))
     return False
Пример #30
0
def get_num_enrolled_in_exclude_admins(course_id, date_for):
    """
    Copied over from CourseEnrollmentManager.num_enrolled_in_exclude_admins method
    and modified to filter on date LT

    """
    course_locator = course_id

    if getattr(course_id, 'ccx', None):
        course_locator = course_id.to_course_locator()

    staff = CourseStaffRole(course_locator).users_with_role()
    admins = CourseInstructorRole(course_locator).users_with_role()
    coaches = CourseCcxCoachRole(course_locator).users_with_role()

    return CourseEnrollment.objects.filter(
        course_id=course_id,
        is_active=1,
        created__lt=as_datetime(next_day(date_for)),
    ).exclude(user__in=staff).exclude(user__in=admins).exclude(
        user__in=coaches).count()