Example #1
0
 def test_enroll_in_course(self):
     user = User.objects.create_user("joe", "*****@*****.**", "password")
     user.save()
     course_id = "course_id"
     self.assertFalse(is_enrolled_in_course(user, course_id))
     enroll_in_course(user, course_id)
     self.assertTrue(is_enrolled_in_course(user, course_id))
Example #2
0
def course_team_user(request, org, course, name, email):
    location = Location('i4x', org, course, 'course', name)
    # check that logged in user has permissions to this item
    if has_access(request.user, location, role=INSTRUCTOR_ROLE_NAME):
        # instructors have full permissions
        pass
    elif has_access(request.user, location, role=STAFF_ROLE_NAME) and email == request.user.email:
        # staff can only affect themselves
        pass
    else:
        msg = {
            "error": _("Insufficient permissions")
        }
        return JsonResponse(msg, 400)

    try:
        user = User.objects.get(email=email)
    except:
        msg = {
            "error": _("Could not find user by email address '{email}'.").format(email=email),
        }
        return JsonResponse(msg, 404)

    # role hierarchy: "instructor" has more permissions than "staff" (in a course)
    roles = ["instructor", "staff"]

    if request.method == "GET":
        # just return info about the user
        msg = {
            "email": user.email,
            "active": user.is_active,
            "role": None,
        }
        # what's the highest role that this user has?
        groupnames = set(g.name for g in user.groups.all())
        for role in roles:
            role_groupname = get_course_groupname_for_role(location, role)
            if role_groupname in groupnames:
                msg["role"] = role
                break
        return JsonResponse(msg)

    # can't modify an inactive user
    if not user.is_active:
        msg = {
            "error": _('User {email} has registered but has not yet activated his/her account.').format(email=email),
        }
        return JsonResponse(msg, 400)

    # make sure that the role groups exist
    groups = {}
    for role in roles:
        groupname = get_course_groupname_for_role(location, role)
        group, __ = Group.objects.get_or_create(name=groupname)
        groups[role] = group

    if request.method == "DELETE":
        # remove all roles in this course from this user: but fail if the user
        # is the last instructor in the course team
        instructors = set(groups["instructor"].user_set.all())
        staff = set(groups["staff"].user_set.all())
        if user in instructors and len(instructors) == 1:
            msg = {
                "error": _("You may not remove the last instructor from a course")
            }
            return JsonResponse(msg, 400)

        if user in instructors:
            user.groups.remove(groups["instructor"])
        if user in staff:
            user.groups.remove(groups["staff"])
        user.save()
        return JsonResponse()

    # all other operations require the requesting user to specify a role
    if request.META.get("CONTENT_TYPE", "").startswith("application/json") and request.body:
        try:
            payload = json.loads(request.body)
        except:
            return JsonResponse({"error": _("malformed JSON")}, 400)
        try:
            role = payload["role"]
        except KeyError:
            return JsonResponse({"error": _("`role` is required")}, 400)
    else:
        if not "role" in request.POST:
            return JsonResponse({"error": _("`role` is required")}, 400)
        role = request.POST["role"]

    if role == "instructor":
        if not has_access(request.user, location, role=INSTRUCTOR_ROLE_NAME):
            msg = {
                "error": _("Only instructors may create other instructors")
            }
            return JsonResponse(msg, 400)
        user.groups.add(groups["instructor"])
        user.save()
        # auto-enroll the course creator in the course so that "View Live" will work.
        enroll_in_course(user, location.course_id)
    elif role == "staff":
        # if we're trying to downgrade a user from "instructor" to "staff",
        # make sure we have at least one other instructor in the course team.
        instructors = set(groups["instructor"].user_set.all())
        if user in instructors:
            if len(instructors) == 1:
                msg = {
                    "error": _("You may not remove the last instructor from a course")
                }
                return JsonResponse(msg, 400)
            user.groups.remove(groups["instructor"])
        user.groups.add(groups["staff"])
        user.save()
        # auto-enroll the course creator in the course so that "View Live" will work.
        enroll_in_course(user, location.course_id)

    return JsonResponse()
Example #3
0
def create_new_course(request):
    """
    Create a new course
    """
    if not is_user_in_creator_group(request.user):
        raise PermissionDenied()

    org = request.POST.get('org')
    number = request.POST.get('number')
    display_name = request.POST.get('display_name')
    run = request.POST.get('run')

    try:
        dest_location = Location('i4x', org, number, 'course', run)
    except InvalidLocationError as error:
        return JsonResponse({
            "ErrMsg": _("Unable to create course '{name}'.\n\n{err}").format(
                name=display_name, err=error.message)})

    # see if the course already exists
    existing_course = None
    try:
        existing_course = modulestore('direct').get_item(dest_location)
    except ItemNotFoundError:
        pass
    if existing_course is not None:
        return JsonResponse(
            {
                'ErrMsg': _('There is already a course defined with the same organization, course number, and course run. Please change either organization or course number to be unique.'),
                'OrgErrMsg': _('Please change either the organization or course number so that it is unique.'),
                'CourseErrMsg': _('Please change either the organization or course number so that it is unique.'),
            }
        )

    course_search_location = ['i4x', dest_location.org, dest_location.course, 'course', None]
    courses = modulestore().get_items(course_search_location)
    if len(courses) > 0:
        return JsonResponse(
            {
                'ErrMsg': _('There is already a course defined with the same organization and course number. Please change at least one field to be unique.'),
                'OrgErrMsg': _('Please change either the organization or course number so that it is unique.'),
                'CourseErrMsg': _('Please change either the organization or course number so that it is unique.'),
            }
        )

    # instantiate the CourseDescriptor and then persist it
    # note: no system to pass
    if display_name is None:
        metadata = {}
    else:
        metadata = {'display_name': display_name}
    modulestore('direct').create_and_save_xmodule(dest_location, metadata=metadata)
    new_course = modulestore('direct').get_item(dest_location)

    # clone a default 'about' overview module as well
    dest_about_location = dest_location.replace(category='about', name='overview')
    overview_template = AboutDescriptor.get_template('overview.yaml')
    modulestore('direct').create_and_save_xmodule(
        dest_about_location,
        system=new_course.system,
        definition_data=overview_template.get('data')
    )

    initialize_course_tabs(new_course)

    create_all_course_groups(request.user, new_course.location)

    # seed the forums
    seed_permissions_roles(new_course.location.course_id)

    # auto-enroll the course creator in the course so that "View Live" will work.
    enroll_in_course(request.user, new_course.location.course_id)

    return JsonResponse({'id': new_course.location.url()})