コード例 #1
0
ファイル: test_access.py プロジェクト: Codeyelp/edx-platform
 def test_allow(self):
     user = UserFactory()
     allow_access(self.course, user, 'staff')
     group = Group.objects.get(
         name=get_access_group_name(self.course, 'staff')
     )
     self.assertIn(user, group.user_set.all())
コード例 #2
0
def modify_access(request, course_id):
    """
    Modify staff/instructor access of other user.
    Requires instructor access.

    NOTE: instructors cannot remove their own instructor access.

    Query parameters:
    unique_student_identifer is the target user's username or email
    rolename is one of ['instructor', 'staff', 'beta']
    action is one of ['allow', 'revoke']
    """
    course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    course = get_course_with_access(request.user, "instructor", course_id, depth=None)
    try:
        user = get_student_from_identifier(request.GET.get("unique_student_identifier"))
    except User.DoesNotExist:
        response_payload = {
            "unique_student_identifier": request.GET.get("unique_student_identifier"),
            "userDoesNotExist": True,
        }
        return JsonResponse(response_payload)

    # Check that user is active, because add_users
    # in common/djangoapps/student/roles.py fails
    # silently when we try to add an inactive user.
    if not user.is_active:
        response_payload = {"unique_student_identifier": user.username, "inactiveUser": True}
        return JsonResponse(response_payload)

    rolename = request.GET.get("rolename")
    action = request.GET.get("action")

    if not rolename in ["instructor", "staff", "beta"]:
        return HttpResponseBadRequest(strip_tags("unknown rolename '{}'".format(rolename)))

    # disallow instructors from removing their own instructor access.
    if rolename == "instructor" and user == request.user and action != "allow":
        response_payload = {
            "unique_student_identifier": user.username,
            "rolename": rolename,
            "action": action,
            "removingSelfAsInstructor": True,
        }
        return JsonResponse(response_payload)

    if action == "allow":
        allow_access(course, user, rolename)
    elif action == "revoke":
        revoke_access(course, user, rolename)
    else:
        return HttpResponseBadRequest(strip_tags("unrecognized action '{}'".format(action)))

    response_payload = {
        "unique_student_identifier": user.username,
        "rolename": rolename,
        "action": action,
        "success": "yes",
    }
    return JsonResponse(response_payload)
コード例 #3
0
 def test_allow(self):
     user = UserFactory()
     allow_access(self.course, user, 'staff')
     group = Group.objects.get(
         name=get_access_group_name(self.course, 'staff')
     )
     self.assertIn(user, group.user_set.all())
コード例 #4
0
ファイル: api.py プロジェクト: ktisha/edx-platform
def bulk_beta_modify_access(request, course_id):
    """
    Enroll or unenroll users in beta testing program.

    Query parameters:
    - emails is string containing a list of emails separated by anything split_input_list can handle.
    - action is one of ['add', 'remove']
    """
    action = request.GET.get('action')
    emails_raw = request.GET.get('emails')
    emails = _split_input_list(emails_raw)
    email_students = request.GET.get('email_students') in ['true', 'True', True]
    results = []
    rolename = 'beta'
    course = get_course_by_id(course_id)

    email_params = {}
    if email_students:
        email_params = get_email_params(course, auto_enroll=False)

    for email in emails:
        try:
            error = False
            user_does_not_exist = False
            user = User.objects.get(email=email)

            if action == 'add':
                allow_access(course, user, rolename)
            elif action == 'remove':
                revoke_access(course, user, rolename)
            else:
                return HttpResponseBadRequest(strip_tags(
                    "Unrecognized action '{}'".format(action)
                ))
        except User.DoesNotExist:
            error = True
            user_does_not_exist = True
        # catch and log any unexpected exceptions
        # so that one error doesn't cause a 500.
        except Exception as exc:  # pylint: disable=broad-except
            log.exception("Error while #{}ing student")
            log.exception(exc)
            error = True
        else:
            # If no exception thrown, see if we should send an email
            if email_students:
                send_beta_role_email(action, user, email_params)
        finally:
            # Tabulate the action result of this email address
            results.append({
                'email': email,
                'error': error,
                'userDoesNotExist': user_does_not_exist
            })

    response_payload = {
        'action': action,
        'results': results,
    }
    return JsonResponse(response_payload)
コード例 #5
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,
                                                     unicode(ccx.id))
        with ccx_course(ccx_locator) as course:
            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".',
                unicode(ccx_locator))
コード例 #6
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)
            )
コード例 #7
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)
            )
コード例 #8
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,
                                                     unicode(ccx.id))
        with ccx_course(ccx_locator) as course:
            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".',
                unicode(ccx_locator))
コード例 #9
0
def bulk_beta_modify_access(request, course_id):
    """
    Enroll or unenroll users in beta testing program.

    Query parameters:
    - identifiers is string containing a list of emails and/or usernames separated by
      anything split_input_list can handle.
    - action is one of ['add', 'remove']
    """
    action = request.GET.get("action")
    identifiers_raw = request.GET.get("identifiers")
    identifiers = _split_input_list(identifiers_raw)
    email_students = request.GET.get("email_students") in ["true", "True", True]
    auto_enroll = request.GET.get("auto_enroll") in ["true", "True", True]
    results = []
    rolename = "beta"
    course = get_course_by_id(course_id)

    email_params = {}
    if email_students:
        email_params = get_email_params(course, auto_enroll=auto_enroll)

    for identifier in identifiers:
        try:
            error = False
            user_does_not_exist = False
            user = get_student_from_identifier(identifier)

            if action == "add":
                allow_access(course, user, rolename)
            elif action == "remove":
                revoke_access(course, user, rolename)
            else:
                return HttpResponseBadRequest(strip_tags("Unrecognized action '{}'".format(action)))
        except User.DoesNotExist:
            error = True
            user_does_not_exist = True
        # catch and log any unexpected exceptions
        # so that one error doesn't cause a 500.
        except Exception as exc:  # pylint: disable=broad-except
            log.exception("Error while #{}ing student")
            log.exception(exc)
            error = True
        else:
            # If no exception thrown, see if we should send an email
            if email_students:
                send_beta_role_email(action, user, email_params)
            # See if we should autoenroll the student
            if auto_enroll:
                # Check if student is already enrolled
                if not CourseEnrollment.is_enrolled(user, course_id):
                    CourseEnrollment.enroll(user, course_id)

        finally:
            # Tabulate the action result of this email address
            results.append({"identifier": identifier, "error": error, "userDoesNotExist": user_does_not_exist})

    response_payload = {"action": action, "results": results}
    return JsonResponse(response_payload)
コード例 #10
0
ファイル: factories.py プロジェクト: neurolit/edx-platform
def StaffFactory(course):  # pylint: disable=invalid-name
    """
    Given a course object, returns a User object with staff
    permissions for `course`.
    """
    user = StudentUserFactory.create(last_name="Staff")
    allow_access(course, user, "staff")
    return user
コード例 #11
0
 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')
コード例 #12
0
ファイル: test_access.py プロジェクト: chauhanhardik/populo
 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')
コード例 #13
0
ファイル: test_access.py プロジェクト: chauhanhardik/populo
 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')
コード例 #14
0
 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')
コード例 #15
0
    def setUp(self):
        self.course = CourseFactory.create()

        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')
コード例 #16
0
    def setUp(self):
        self.course = CourseFactory.create()

        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")
コード例 #17
0
ファイル: test_access.py プロジェクト: Codeyelp/edx-platform
    def setUp(self):
        self.course = CourseFactory.create()

        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')
コード例 #18
0
ファイル: test_views.py プロジェクト: Fadykhallaf/learnlink
    def setUp(self):
        super(TestCoachDashboardSchedule, self).setUp()
        self.course = course = CourseFactory.create()

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

        self.chapters = [
            ItemFactory.create(start=start, parent=course) for _ in xrange(2)
        ]
        self.sequentials = flatten([
            [
                ItemFactory.create(parent=chapter) for _ in xrange(2)
            ] for chapter in self.chapters
        ])
        self.verticals = flatten([
            [
                ItemFactory.create(
                    start=start, due=due, parent=sequential, graded=True, format='Homework', category=u'vertical'
                ) for _ in xrange(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 xrange(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')
        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))

        self.assertTrue(modulestore().has_course(self.course.id))
コード例 #19
0
    def setUp(self):
        super(TestCoachDashboardSchedule, self).setUp()
        self.course = course = CourseFactory.create()

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

        self.chapters = [
            ItemFactory.create(start=start, parent=course) for _ in xrange(2)
        ]
        self.sequentials = flatten([
            [
                ItemFactory.create(parent=chapter) for _ in xrange(2)
            ] for chapter in self.chapters
        ])
        self.verticals = flatten([
            [
                ItemFactory.create(
                    start=start, due=due, parent=sequential, graded=True, format='Homework', category=u'vertical'
                ) for _ in xrange(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 xrange(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')
        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))

        self.assertTrue(modulestore().has_course(self.course.id))
コード例 #20
0
    def setUp(self):
        self.instructor = AdminFactory.create()
        self.course = CourseFactory.create()
        self.client.login(username=self.instructor.username, password='******')

        self.other_instructor = UserFactory()
        allow_access(self.course, self.other_instructor, 'instructor')
        self.other_staff = UserFactory()
        allow_access(self.course, self.other_staff, 'staff')
        self.other_user = UserFactory()
コード例 #21
0
ファイル: test_api.py プロジェクト: LukeLu1263/edx-platform
    def setUp(self):
        self.instructor = AdminFactory.create()
        self.course = CourseFactory.create()
        self.client.login(username=self.instructor.username, password='******')

        self.other_instructor = UserFactory()
        allow_access(self.course, self.other_instructor, 'instructor')
        self.other_staff = UserFactory()
        allow_access(self.course, self.other_staff, 'staff')
        self.other_user = UserFactory()
コード例 #22
0
def add_affiliate_course_enrollments(sender, instance, created, **kwargs):
    'Allow all affiliate staff and instructors access to this course.'
    # do this only for new CCX courses
    if not created:
        return

    from courseware.courses import get_course_by_id

    course = get_course_by_id(instance.ccx_course_id)
    for membership in instance.affiliate.memberships.exclude(role='ccx_coach'):
        allow_access(course, membership.member, membership.role, False)
コード例 #23
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, unicode(ccx.id))
        instructor = self.make_instructor()

        with ccx_course(ccx_key) as course_ccx:
            allow_access(course_ccx, instructor, 'instructor')
            self.assertTrue(self.check_ccx_tab(course_ccx, instructor))
コード例 #24
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, unicode(ccx.id))
        staff = self.make_staff()

        with ccx_course(ccx_key) as course_ccx:
            allow_access(course_ccx, staff, 'staff')
            self.assertTrue(self.check_ccx_tab(course_ccx, staff))
コード例 #25
0
def i_am_staff_member_for_the_course(step, course_number):
    # Create the course
    create_course(step, course_number)
    course = get_course_by_id(course_id(course_number))

    # Create the user
    world.create_user('robot', 'test')
    user = User.objects.get(username='******')

    # Add user as a course staff.
    allow_access(course, user, "staff")

    world.log_in(username='******', password='******')
コード例 #26
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)
コード例 #27
0
def modify_access(request, course_id):
    """
    Modify staff/instructor access of other user.
    Requires instructor access.

    NOTE: instructors cannot remove their own instructor access.

    Query parameters:
    email is the target users email
    rolename is one of ['instructor', 'staff', 'beta']
    action is one of ['allow', 'revoke']
    """
    course = get_course_with_access(
        request.user, course_id, 'instructor', depth=None
    )

    email = strip_if_string(request.GET.get('email'))
    rolename = request.GET.get('rolename')
    action = request.GET.get('action')

    if not rolename in ['instructor', 'staff', 'beta']:
        return HttpResponseBadRequest(
            "unknown rolename '{}'".format(rolename)
        )

    user = User.objects.get(email=email)

    # disallow instructors from removing their own instructor access.
    if rolename == 'instructor' and user == request.user and action != 'allow':
        return HttpResponseBadRequest(
            "An instructor cannot remove their own instructor access."
        )

    if action == 'allow':
        allow_access(course, user, rolename)
    elif action == 'revoke':
        revoke_access(course, user, rolename)
    else:
        return HttpResponseBadRequest("unrecognized action '{}'".format(action))

    response_payload = {
        'email': email,
        'rolename': rolename,
        'action': action,
        'success': 'yes',
    }
    return JsonResponse(response_payload)
コード例 #28
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))
コード例 #29
0
ファイル: utils.py プロジェクト: Endika/edx-platform
def assign_coach_role_to_ccx(ccx_locator, user, master_course_id):
    """
    Check if user has ccx_coach role on master course then assign him coach 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 coach role on ccx.
        role = CourseCcxCoachRole(ccx_locator)
        if not role.has_user(user):
            # assign user role coach on ccx
            with ccx_course(ccx_locator) as course:
                allow_access(course, user, "ccx_coach", send_email=False)
コード例 #30
0
ファイル: utils.py プロジェクト: Endika/edx-platform
def add_master_course_staff_to_ccx(master_course, ccx_key, display_name):
    """
    Added staff role on ccx to all the staff 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
    """
    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)
        for staff in list_staff:
            # allow 'staff' access on ccx to staff of master course
            allow_access(course_ccx, staff, 'staff')

            # Enroll the staff in the ccx
            enroll_email(
                course_id=ccx_key,
                student_email=staff.email,
                auto_enroll=True,
                email_students=True,
                email_params=email_params,
            )

        for instructor in list_instructor:
            # allow 'instructor' access on ccx to instructor of master course
            allow_access(course_ccx, instructor, 'instructor')

            # Enroll the instructor in the ccx
            enroll_email(
                course_id=ccx_key,
                student_email=instructor.email,
                auto_enroll=True,
                email_students=True,
                email_params=email_params,
            )
コード例 #31
0
    def setUp(self):
        """
        Set up tests
        """
        super(CcxRestApiTest, self).setUp()
        # add some info about the course for easy access
        self.master_course_key = self.course.location.course_key
        self.master_course_key_str = unicode(self.master_course_key)
        # OAUTH2 setup
        # create a specific user for the application
        app_user = UserFactory(username='******', email='*****@*****.**', 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')

        # create an oauth client app entry
        self.app_client = Client.objects.create(
            user=app_user,
            name='test client',
            url='http://localhost//',
            redirect_uri='http://localhost//',
            client_type=CONFIDENTIAL
        )
        # create an authorization code
        self.app_grant = Grant.objects.create(
            user=app_user,
            client=self.app_client,
            redirect_uri='http://localhost//'
        )
        self.course.enable_ccx = True
        self.mstore.update_item(self.course, self.coach.id)
        self.auth = self.get_auth_token()
        # making the master course chapters easily available
        self.master_course_chapters = get_course_chapters(self.master_course_key)
コード例 #32
0
def add_affiliate_course_enrollments(sender, instance, **kwargs):  # pylint: disable=unused-argument
    """
    Allow staff or instructor level access to affiliate member into
    all affiliate courses if they are staff or instructor member.
    """
    if not instance.role == AffiliateMembership.CCX_COACH:
        for ccx in instance.affiliate.courses:
            ccx_locator = CCXLocator.from_course_locator(ccx.course_id, ccx.id)
            course = get_course_by_id(ccx_locator)

            try:
                with transaction.atomic():
                    allow_access(course, instance.member, instance.role, False)
            except IntegrityError:
                LOG.error('IntegrityError: Allow access failed.')

    # FastTrac main course and Facilitator Guide course
    course_overviews = CourseOverview.objects.exclude(id__startswith='ccx-')

    # Program Director and Course Manager needs to be a CCX coach on FastTrac course
    if instance.role in AffiliateMembership.STAFF_ROLES:
        for course_overview in course_overviews:
            course_id = course_overview.id
            course = get_course_by_id(course_id)

            try:
                with transaction.atomic():
                    allow_access(course, instance.member, AffiliateMembership.CCX_COACH, False)
            except IntegrityError:
                LOG.error('IntegrityError: CCX coach failed.')

    elif instance.role == AffiliateMembership.CCX_COACH:
        for course_overview in course_overviews:
            course_id = course_overview.id

            enroll_email(course_id, instance.member.email, auto_enroll=True)
コード例 #33
0
ファイル: api.py プロジェクト: superChrome/edx-platform
def bulk_beta_modify_access(request, course_id):
    """
    Enroll or unenroll users in beta testing program.

    Query parameters:
    - identifiers is string containing a list of emails and/or usernames separated by
      anything split_input_list can handle.
    - action is one of ['add', 'remove']
    """
    action = request.GET.get('action')
    identifiers_raw = request.GET.get('identifiers')
    identifiers = _split_input_list(identifiers_raw)
    email_students = request.GET.get('email_students') in [
        'true', 'True', True
    ]
    auto_enroll = request.GET.get('auto_enroll') in ['true', 'True', True]
    results = []
    rolename = 'beta'
    course = get_course_by_id(course_id)

    email_params = {}
    if email_students:
        email_params = get_email_params(course, auto_enroll=auto_enroll)

    for identifier in identifiers:
        try:
            error = False
            user_does_not_exist = False
            user = get_student_from_identifier(identifier)

            if action == 'add':
                allow_access(course, user, rolename)
            elif action == 'remove':
                revoke_access(course, user, rolename)
            else:
                return HttpResponseBadRequest(
                    strip_tags("Unrecognized action '{}'".format(action)))
        except User.DoesNotExist:
            error = True
            user_does_not_exist = True
        # catch and log any unexpected exceptions
        # so that one error doesn't cause a 500.
        except Exception as exc:  # pylint: disable=broad-except
            log.exception("Error while #{}ing student")
            log.exception(exc)
            error = True
        else:
            # If no exception thrown, see if we should send an email
            if email_students:
                send_beta_role_email(action, user, email_params)
            # See if we should autoenroll the student
            if auto_enroll:
                # Check if student is already enrolled
                if not CourseEnrollment.is_enrolled(user, course_id):
                    CourseEnrollment.enroll(user, course_id)

        finally:
            # Tabulate the action result of this email address
            results.append({
                'identifier': identifier,
                'error': error,
                'userDoesNotExist': user_does_not_exist
            })

    response_payload = {
        'action': action,
        'results': results,
    }
    return JsonResponse(response_payload)
コード例 #34
0
 def test_allow_badlevel(self):
     user = UserFactory()
     allow_access(self.course, user, 'robot-not-a-level')
     group = Group.objects.get(name=get_access_group_name(self.course, 'robot-not-a-level'))
     self.assertIn(user, group.user_set.all())
コード例 #35
0
 def test_allow_ccx_coach(self):
     user = UserFactory()
     allow_access(self.course, user, 'ccx_coach')
     self.assertTrue(CourseCcxCoachRole(self.course.id).has_user(user))
コード例 #36
0
 def test_allow_noneuser(self):
     user = None
     allow_access(self.course, user, 'staff')
コード例 #37
0
 def test_allow_badlevel(self):
     user = UserFactory()
     allow_access(self.course, user, 'robot-not-a-level')
コード例 #38
0
 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))
コード例 #39
0
 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))
コード例 #40
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
コード例 #41
0
 def test_allow_noneuser(self):
     user = None
     allow_access(self.course, user, 'staff')
     group = Group.objects.get(name=get_access_group_name(self.course, 'staff'))
     self.assertIn(user, group.user_set.all())
コード例 #42
0
ファイル: api.py プロジェクト: superChrome/edx-platform
def modify_access(request, course_id):
    """
    Modify staff/instructor access of other user.
    Requires instructor access.

    NOTE: instructors cannot remove their own instructor access.

    Query parameters:
    unique_student_identifer is the target user's username or email
    rolename is one of ['instructor', 'staff', 'beta']
    action is one of ['allow', 'revoke']
    """
    course = get_course_with_access(request.user,
                                    course_id,
                                    'instructor',
                                    depth=None)
    try:
        user = get_student_from_identifier(
            request.GET.get('unique_student_identifier'))
    except User.DoesNotExist:
        response_payload = {
            'unique_student_identifier':
            request.GET.get('unique_student_identifier'),
            'userDoesNotExist':
            True,
        }
        return JsonResponse(response_payload)

    # Check that user is active, because add_users
    # in common/djangoapps/student/roles.py fails
    # silently when we try to add an inactive user.
    if not user.is_active:
        response_payload = {
            'unique_student_identifier': user.username,
            'inactiveUser': True,
        }
        return JsonResponse(response_payload)

    rolename = request.GET.get('rolename')
    action = request.GET.get('action')

    if not rolename in ['instructor', 'staff', 'beta']:
        return HttpResponseBadRequest(
            strip_tags("unknown rolename '{}'".format(rolename)))

    # disallow instructors from removing their own instructor access.
    if rolename == 'instructor' and user == request.user and action != 'allow':
        response_payload = {
            'unique_student_identifier': user.username,
            'rolename': rolename,
            'action': action,
            'removingSelfAsInstructor': True,
        }
        return JsonResponse(response_payload)

    if action == 'allow':
        allow_access(course, user, rolename)
    elif action == 'revoke':
        revoke_access(course, user, rolename)
    else:
        return HttpResponseBadRequest(
            strip_tags("unrecognized action '{}'".format(action)))

    response_payload = {
        'unique_student_identifier': user.username,
        'rolename': rolename,
        'action': action,
        'success': 'yes',
    }
    return JsonResponse(response_payload)