Esempio n. 1
0
    def test_libraries_on_index(self):
        """
        Test that the library tab is present.
        """
        def _assert_library_tab_present(response):
            """
            Asserts there's a library tab.
            """
            parsed_html = lxml.html.fromstring(response.content)
            library_tab = parsed_html.find_class('react-library-listing')
            self.assertEqual(len(library_tab), 1)

        # Add a library:
        lib1 = LibraryFactory.create()  # lint-amnesty, pylint: disable=unused-variable

        index_url = '/home/'
        index_response = self.client.get(index_url, {},
                                         HTTP_ACCEPT='text/html')
        _assert_library_tab_present(index_response)

        # Make sure libraries are visible to non-staff users too
        self.client.logout()
        non_staff_user, non_staff_userpassword = self.create_non_staff_user()
        lib2 = LibraryFactory.create(user_id=non_staff_user.id)
        LibraryUserRole(lib2.location.library_key).add_users(non_staff_user)
        self.client.login(username=non_staff_user.username,
                          password=non_staff_userpassword)
        index_response = self.client.get(index_url, {},
                                         HTTP_ACCEPT='text/html')
        _assert_library_tab_present(index_response)
Esempio n. 2
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
Esempio n. 3
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':
            str(library_key),
            'lib_users_url':
            reverse_library_url('manage_library_users', library_key_string),
            'show_children_previews':
            library.show_children_previews
        })
Esempio n. 4
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

    # mcdaniel dec-2020: all approved course creators receive all_perms to the course templates.
    if str(course_key)[-8:] == 'Template':
        log.info(
            'common.djangoapps.student.auth.get_user_permissions() - template found. granting all_perms on: {course_key}'
            .format(course_key=course_key))
        return all_perms

    # 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
    def test_read_only_role(self, use_org_level_role):
        """
        Test the read-only role (LibraryUserRole and its org-level equivalent)
        """
        # As staff user, add a block to self.library:
        block = self._add_simple_content_block()

        # Login as a non_staff_user:
        self._login_as_non_staff_user()
        self.assertFalse(self._can_access_library(self.library))

        block_url = reverse_usage_url('xblock_handler', block.location)

        def can_read_block():
            """ Check if studio lets us view the XBlock in the library """
            response = self.client.get_json(block_url)
            self.assertIn(response.status_code,
                          (200, 403))  # 400 would be ambiguous
            return response.status_code == 200

        def can_edit_block():
            """ Check if studio lets us edit the XBlock in the library """
            response = self.client.ajax_post(block_url)
            self.assertIn(response.status_code,
                          (200, 403))  # 400 would be ambiguous
            return response.status_code == 200

        def can_delete_block():
            """ Check if studio lets us delete the XBlock in the library """
            response = self.client.delete(block_url)
            self.assertIn(response.status_code,
                          (200, 403))  # 400 would be ambiguous
            return response.status_code == 200

        def can_copy_block():
            """ Check if studio lets us duplicate the XBlock in the library """
            response = self.client.ajax_post(
                reverse_url('xblock_handler'), {
                    'parent_locator': str(self.library.location),
                    'duplicate_source_locator': str(block.location),
                })
            self.assertIn(response.status_code,
                          (200, 403))  # 400 would be ambiguous
            return response.status_code == 200

        def can_create_block():
            """ Check if studio lets us make a new XBlock in the library """
            response = self.client.ajax_post(
                reverse_url('xblock_handler'), {
                    'parent_locator': str(self.library.location),
                    'category': 'html',
                })
            self.assertIn(response.status_code,
                          (200, 403))  # 400 would be ambiguous
            return response.status_code == 200

        # Check that we do not have read or write access to block:
        self.assertFalse(can_read_block())
        self.assertFalse(can_edit_block())
        self.assertFalse(can_delete_block())
        self.assertFalse(can_copy_block())
        self.assertFalse(can_create_block())

        # Give non_staff_user read-only permission:
        if use_org_level_role:
            OrgLibraryUserRole(self.lib_key.org).add_users(self.non_staff_user)
        else:
            LibraryUserRole(self.lib_key).add_users(self.non_staff_user)

        self.assertTrue(self._can_access_library(self.library))
        self.assertTrue(can_read_block())
        self.assertFalse(can_edit_block())
        self.assertFalse(can_delete_block())
        self.assertFalse(can_copy_block())
        self.assertFalse(can_create_block())