Ejemplo n.º 1
0
    def setUp(self):
        """
        Set up tests
        """
        super().setUp()
        # add some info about the course for easy access
        self.master_course_key = self.course.location.course_key
        self.master_course_key_str = str(self.master_course_key)
        # OAUTH2 setup
        # create a specific user for the application
        self.app_user = app_user = UserFactory(
            username='******',
            email='*****@*****.**',
            password=USER_PASSWORD
        )

        # add staff role to the app user
        CourseStaffRole(self.master_course_key).add_users(app_user)

        # adding instructor to master course.
        instructor = UserFactory()
        allow_access(self.course, instructor, 'instructor')

        self.auth = self.prepare_auth_token(app_user)

        self.course.enable_ccx = True
        self.mstore.update_item(self.course, self.coach.id)
        # making the master course chapters easily available
        self.master_course_chapters = courses.get_course_chapter_ids(self.master_course_key)
Ejemplo n.º 2
0
def change_existing_ccx_coaches_to_staff(apps, schema_editor):
    """
    Modify all coaches of CCX courses so that they have the staff role on the
    CCX course they coach, but retain the CCX Coach role on the parent course.

    Arguments:
        apps (Applications): Apps in edX platform.
        schema_editor (SchemaEditor): For editing database schema (unused)

    """
    CustomCourseForEdX = apps.get_model('ccx', 'CustomCourseForEdX')
    db_alias = schema_editor.connection.alias
    if not db_alias == 'default':
        # This migration is not intended to run against the student_module_history database and
        # will fail if it does. Ensure that it'll only run against the default database.
        return
    list_ccx = CustomCourseForEdX.objects.using(db_alias).all()
    for ccx in list_ccx:
        ccx_locator = CCXLocator.from_course_locator(ccx.course_id,
                                                     six.text_type(ccx.id))
        try:
            course = get_course_by_id(ccx_locator)
        except Http404:
            log.error('Could not migrate access for CCX course: %s',
                      six.text_type(ccx_locator))
        else:
            coach = User.objects.get(id=ccx.coach.id)
            allow_access(course, coach, 'staff', send_email=False)
            revoke_access(course, coach, 'ccx_coach', send_email=False)
            log.info(
                'The CCX coach of CCX %s has been switched from "CCX Coach" to "Staff".',
                six.text_type(ccx_locator))
def create_users(course_key,
                 user_data,
                 enrollment_mode=None,
                 course_staff=False,
                 activate=False):
    """Create users, enrolling them in course_key if it's not None"""
    for single_user_data in user_data:
        account_creation_form = AccountCreationForm(data=single_user_data,
                                                    tos_required=False)

        (user, _, _) = do_create_account(account_creation_form)

        if activate:
            user.is_active = True
            user.save()

        if course_key is not None:
            CourseEnrollment.enroll(user, course_key, mode=enrollment_mode)
            if course_staff:
                course = modulestore().get_course(course_key, depth=1)
                allow_access(course, user, 'staff', send_email=False)

        if course_key and course_staff:
            print(f'Created user {user.username} as course staff')
        else:
            print(f'Created user {user.username}')
Ejemplo n.º 4
0
def revert_ccx_staff_to_coaches(apps, schema_editor):
    """
    Modify all staff on CCX courses so that they no longer have the staff role
    on the course that they coach.

    Arguments:
        apps (Applications): Apps in edX platform.
        schema_editor (SchemaEditor): For editing database schema (unused)

    """
    CustomCourseForEdX = apps.get_model('ccx', 'CustomCourseForEdX')
    db_alias = schema_editor.connection.alias
    if not db_alias == 'default':
        return
    list_ccx = CustomCourseForEdX.objects.using(db_alias).all()
    for ccx in list_ccx:
        ccx_locator = CCXLocator.from_course_locator(ccx.course_id,
                                                     six.text_type(ccx.id))
        try:
            course = get_course_by_id(ccx_locator)
        except Http404:
            log.error('Could not migrate access for CCX course: %s',
                      six.text_type(ccx_locator))
        else:
            coach = User.objects.get(id=ccx.coach.id)
            allow_access(course, coach, 'ccx_coach', send_email=False)
            revoke_access(course, coach, 'staff', send_email=False)
            log.info(
                'The CCX coach of CCX %s has been switched from "Staff" to "CCX Coach".',
                six.text_type(ccx_locator))
 def setUp(self):
     super(TestInstructorAccessRevoke, self).setUp()
     self.staff = [UserFactory.create() for _ in xrange(4)]
     for user in self.staff:
         allow_access(self.course, user, 'staff')
     self.beta_testers = [UserFactory.create() for _ in xrange(4)]
     for user in self.beta_testers:
         allow_access(self.course, user, 'beta')
Ejemplo n.º 6
0
 def setUp(self):
     super(TestInstructorAccessRevoke, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
     self.staff = [UserFactory.create() for _ in range(4)]
     for user in self.staff:
         allow_access(self.course, user, 'staff')
     self.beta_testers = [UserFactory.create() for _ in range(4)]
     for user in self.beta_testers:
         allow_access(self.course, user, 'beta')
 def setUp(self):
     super(TestInstructorAccessList, self).setUp()
     self.instructors = [UserFactory.create() for _ in xrange(4)]
     for user in self.instructors:
         allow_access(self.course, user, 'instructor')
     self.beta_testers = [UserFactory.create() for _ in xrange(4)]
     for user in self.beta_testers:
         allow_access(self.course, user, 'beta')
Ejemplo n.º 8
0
    def setUp(self):
        super().setUp()
        self.course = course = CourseFactory.create(enable_ccx=True)

        # Create a course outline
        self.mooc_start = start = datetime.datetime(
            2010, 5, 12, 2, 42, tzinfo=UTC
        )
        self.mooc_due = due = datetime.datetime(
            2010, 7, 7, 0, 0, tzinfo=UTC
        )

        self.chapters = [
            ItemFactory.create(start=start, parent=course) for _ in range(2)
        ]
        self.sequentials = flatten([
            [
                ItemFactory.create(parent=chapter) for _ in range(2)
            ] for chapter in self.chapters
        ])
        self.verticals = flatten([
            [
                ItemFactory.create(
                    start=start, due=due, parent=sequential, graded=True, format='Homework', category='vertical'
                ) for _ in range(2)
            ] for sequential in self.sequentials
        ])

        # Trying to wrap the whole thing in a bulk operation fails because it
        # doesn't find the parents. But we can at least wrap this part...
        with self.store.bulk_operations(course.id, emit_signals=False):
            blocks = flatten([  # pylint: disable=unused-variable
                [
                    ItemFactory.create(parent=vertical) for _ in range(2)
                ] for vertical in self.verticals
            ])

        # Create instructor account
        self.coach = UserFactory.create()
        # create an instance of modulestore
        self.mstore = modulestore()

        # 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')
        assert CourseStaffRole(self.course.id).has_user(staff)

        # adding instructor to master course.
        instructor = UserFactory()
        allow_access(self.course, instructor, 'instructor')
        assert CourseInstructorRole(self.course.id).has_user(instructor)

        assert modulestore().has_course(self.course.id)
Ejemplo n.º 9
0
    def test_is_user_staff(self):
        """
        Test to assert that the user is staff or not
        """
        result = self.service.is_course_staff(self.student, unicode(self.course.id))
        self.assertFalse(result)

        # allow staff access to the student
        allow_access(self.course, self.student, "staff")
        result = self.service.is_course_staff(self.student, unicode(self.course.id))
        self.assertTrue(result)
Ejemplo n.º 10
0
    def test_ccx_tab_visibility_for_staff_ccx_course(self):
        """
        Staff can access coach dashboard on ccx course.
        """
        self.make_coach()
        ccx = self.make_ccx()
        ccx_key = CCXLocator.from_course_locator(self.course.id, str(ccx.id))
        staff = self.make_staff()

        with ccx_course(ccx_key) as course_ccx:
            allow_access(course_ccx, staff, 'staff')
            assert self.check_ccx_tab(course_ccx, staff)
Ejemplo n.º 11
0
    def test_ccx_tab_visibility_for_instructor_ccx_course(self):
        """
        Instructor can access coach dashboard on ccx course.
        """
        self.make_coach()
        ccx = self.make_ccx()
        ccx_key = CCXLocator.from_course_locator(self.course.id, str(ccx.id))
        instructor = self.make_instructor()

        with ccx_course(ccx_key) as course_ccx:
            allow_access(course_ccx, instructor, 'instructor')
            assert self.check_ccx_tab(course_ccx, instructor)
    def test_is_user_staff(self):
        """
        Test to assert that the user is staff or not
        """
        result = self.service.is_course_staff(self.student,
                                              str(self.course.id))
        assert not result

        # allow staff access to the student
        allow_access(self.course, self.student, 'staff')
        result = self.service.is_course_staff(self.student,
                                              str(self.course.id))
        assert result
Ejemplo n.º 13
0
    def test_is_user_staff(self):
        """
        Test to assert that the user is staff or not
        """
        result = self.service.is_course_staff(self.student,
                                              six.text_type(self.course.id))
        self.assertFalse(result)

        # allow staff access to the student
        allow_access(self.course, self.student, 'staff')
        result = self.service.is_course_staff(self.student,
                                              six.text_type(self.course.id))
        self.assertTrue(result)
Ejemplo n.º 14
0
def create_users(
    course_key,
    user_data,
    enrollment_mode=None,
    course_staff=False,
    activate=False,
    ignore_user_already_exists=False,
):
    """Create users, enrolling them in course_key if it's not None"""
    for single_user_data in user_data:
        account_creation_form = AccountCreationForm(
            data=single_user_data,
            tos_required=False
        )

        user_already_exists = False
        try:
            (user, _, _) = do_create_account(account_creation_form)
        except (ValidationError, AccountValidationError) as account_creation_error:
            # It would be convenient if we just had the AccountValidationError raised, because we include a
            # helpful error code in there, but we also do form validation on account_creation_form and those
            # are pretty opaque.
            try:
                # Check to see if there's a user with our username. If the username and email match our input,
                # we're good, it's the same user, probably. If the email doesn't match, just to be safe we will
                # continue to fail.
                user = User.objects.get(username=single_user_data['username'])
                if user.email == single_user_data['email'] and ignore_user_already_exists:
                    user_already_exists = True
                    print(f'Test user {user.username} already exists. Continuing to attempt to enroll.')
                else:
                    raise account_creation_error
            except User.DoesNotExist:
                # If a user with the username doesn't exist the error was probably something else, so reraise
                raise account_creation_error  # pylint: disable=raise-missing-from

        if activate:
            user.is_active = True
            user.save()

        if course_key is not None:
            CourseEnrollment.enroll(user, course_key, mode=enrollment_mode)
            if course_staff:
                course = modulestore().get_course(course_key, depth=1)
                allow_access(course, user, 'staff', send_email=False)

        if course_key and course_staff and not user_already_exists:
            print(f'Created user {user.username} as course staff')
        elif not user_already_exists:
            print(f'Created user {user.username}')
Ejemplo n.º 15
0
    def setUp(self):
        """
        Set up tests
        """
        super().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')
        assert CourseStaffRole(self.course.id).has_user(staff)

        # adding instructor to master course.
        instructor = UserFactory()
        allow_access(self.course, instructor, 'instructor')
        assert CourseInstructorRole(self.course.id).has_user(instructor)
Ejemplo n.º 16
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 them 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)
Ejemplo n.º 17
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)
Ejemplo n.º 18
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))
Ejemplo n.º 19
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_allow_noneuser(self):
     user = None
     with pytest.raises(Exception):
         allow_access(self.course, user, 'staff')
 def test_allow_badlevel(self):
     user = UserFactory()
     with pytest.raises(ValueError):
         allow_access(self.course, user, 'robot-not-a-level')
 def test_allow_beta(self):
     """ Test allow beta against list beta. """
     user = UserFactory()
     allow_access(self.course, user, 'beta')
     self.assertTrue(CourseBetaTesterRole(self.course.id).has_user(user))
Ejemplo n.º 23
0
 def test_allow_badlevel(self):
     user = UserFactory()
     allow_access(self.course, user, 'robot-not-a-level')
Ejemplo n.º 24
0
 def test_allow_noneuser(self):
     user = None
     allow_access(self.course, user, 'staff')
Ejemplo n.º 25
0
def add_master_course_staff_to_ccx(master_course, ccx_key, display_name, send_email=True):
    """
    Add staff and instructor roles on ccx to all the staff and instructors members of master course.

    Arguments:
        master_course (CourseDescriptorWithMixins): Master course instance.
        ccx_key (CCXLocator): CCX course key.
        display_name (str): ccx display name for email.
        send_email (bool): flag to switch on or off email to the users on access grant.

    """
    list_staff = list_with_level(master_course, 'staff')
    list_instructor = list_with_level(master_course, 'instructor')

    with ccx_course(ccx_key) as course_ccx:
        email_params = get_email_params(course_ccx, auto_enroll=True, course_key=ccx_key, display_name=display_name)
        list_staff_ccx = list_with_level(course_ccx, 'staff')
        list_instructor_ccx = list_with_level(course_ccx, 'instructor')
        for staff in list_staff:
            # this call should be idempotent
            if staff not in list_staff_ccx:
                try:
                    # Enroll the staff in the ccx
                    enroll_email(
                        course_id=ccx_key,
                        student_email=staff.email,
                        auto_enroll=True,
                        email_students=send_email,
                        email_params=email_params,
                    )

                    # allow 'staff' access on ccx to staff of master course
                    allow_access(course_ccx, staff, 'staff')
                except CourseEnrollmentException:
                    log.warning(
                        "Unable to enroll staff %s to course with id %s",
                        staff.email,
                        ccx_key
                    )
                    continue
                except SMTPException:
                    continue

        for instructor in list_instructor:
            # this call should be idempotent
            if instructor not in list_instructor_ccx:
                try:
                    # Enroll the instructor in the ccx
                    enroll_email(
                        course_id=ccx_key,
                        student_email=instructor.email,
                        auto_enroll=True,
                        email_students=send_email,
                        email_params=email_params,
                    )

                    # allow 'instructor' access on ccx to instructor of master course
                    allow_access(course_ccx, instructor, 'instructor')
                except CourseEnrollmentException:
                    log.warning(
                        "Unable to enroll instructor %s to course with id %s",
                        instructor.email,
                        ccx_key
                    )
                    continue
                except SMTPException:
                    continue
 def test_allow_twice(self):
     user = UserFactory()
     allow_access(self.course, user, 'staff')
     allow_access(self.course, user, 'staff')
     self.assertTrue(CourseStaffRole(self.course.id).has_user(user))
Ejemplo n.º 27
0
def add_master_course_staff_to_ccx(master_course,
                                   ccx_key,
                                   display_name,
                                   send_email=True):
    """
    Add staff and instructor roles on ccx to all the staff and instructors members of master course.

    Arguments:
        master_course (CourseBlockWithMixins): Master course instance.
        ccx_key (CCXLocator): CCX course key.
        display_name (str): ccx display name for email.
        send_email (bool): flag to switch on or off email to the users on access grant.

    """
    list_staff = list_with_level(master_course.id, 'staff')
    list_instructor = list_with_level(master_course.id, 'instructor')

    with ccx_course(ccx_key) as course_ccx:
        email_params = get_email_params(course_ccx,
                                        auto_enroll=True,
                                        course_key=ccx_key,
                                        display_name=display_name)
        list_staff_ccx = list_with_level(course_ccx.id, 'staff')
        list_instructor_ccx = list_with_level(course_ccx.id, 'instructor')
        for staff in list_staff:
            # this call should be idempotent
            if staff not in list_staff_ccx:
                try:
                    # Enroll the staff in the ccx
                    enroll_email(
                        course_id=ccx_key,
                        student_email=staff.email,
                        auto_enroll=True,
                        email_students=send_email,
                        email_params=email_params,
                    )

                    # allow 'staff' access on ccx to staff of master course
                    allow_access(course_ccx, staff, 'staff')
                except CourseEnrollmentException:
                    log.warning(
                        "Unable to enroll staff %s to course with id %s",
                        staff.email, ccx_key)
                    continue
                except SMTPException:
                    continue

        for instructor in list_instructor:
            # this call should be idempotent
            if instructor not in list_instructor_ccx:
                try:
                    # Enroll the instructor in the ccx
                    enroll_email(
                        course_id=ccx_key,
                        student_email=instructor.email,
                        auto_enroll=True,
                        email_students=send_email,
                        email_params=email_params,
                    )

                    # allow 'instructor' access on ccx to instructor of master course
                    allow_access(course_ccx, instructor, 'instructor')
                except CourseEnrollmentException:
                    log.warning(
                        "Unable to enroll instructor %s to course with id %s",
                        instructor.email, ccx_key)
                    continue
                except SMTPException:
                    continue
 def test_allow_ccx_coach(self):
     user = UserFactory()
     allow_access(self.course, user, 'ccx_coach')
     self.assertTrue(CourseCcxCoachRole(self.course.id).has_user(user))