Exemple #1
0
def get_new_course_response(lti_params, role):
    """Generate course information for the teacher to setup the course with.

    This only works when the lti user is a teacher of that course.
    """
    if 'Teacher' not in role:
        return response.success({
            'params': {
                'state': LTI_STATES.LACKING_PERMISSION_TO_SETUP_COURSE.value,
                'lti_cName': lti_params['custom_course_name'],
                'lti_aName': lti_params['custom_assignment_title'],
            }
        })

    try:
        return response.success({
            'params': {
                'state': LTI_STATES.NEW_COURSE.value,
                'lti_cName': lti_params['custom_course_name'],
                'lti_abbr': lti_params.get('context_label', ''),
                'lti_cID': lti_params['custom_course_id'],
                'lti_course_start': lti_params['custom_course_start'],
                'lti_aName': lti_params['custom_assignment_title'],
                'lti_aID': lti_params['custom_assignment_id'],
                'lti_aUnlock': lti_params['custom_assignment_unlock'],
                'lti_aDue': lti_params['custom_assignment_due'],
                'lti_aLock': lti_params['custom_assignment_lock'],
                'lti_points_possible': lti_params['custom_assignment_points'],
                'lti_aPublished': lti_params['custom_assignment_publish'],
            }
        })
    except KeyError as err:
        raise VLEMissingRequiredKey(err.args[0])
Exemple #2
0
    def destroy(self, request, *args, **kwargs):
        """Delete an existing assignment from a course.

        Arguments:
        request -- request data
            course_id -- the course ID of course this assignment belongs to
        pk -- assignment ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the assignment or course does not exist
            unauthorized -- when the user is not logged in
            forbidden -- when the user cannot delete the assignment
        On success:
            success -- with a message that the course was deleted

        """
        assignment_id, = utils.required_typed_params(kwargs, (int, 'pk'))
        course_id, = utils.required_typed_params(request.query_params, (int, 'course_id'))
        assignment = Assignment.objects.get(pk=assignment_id)
        course = Course.objects.get(pk=course_id)

        request.user.check_permission('can_delete_assignment', course)

        assignment.courses.remove(course)
        assignment.save()

        # If the assignment is only connected to one course, delete it completely
        if assignment.courses.count() == 0:
            assignment.delete()
            return response.success(description='Successfully deleted the assignment.')
        else:
            return response.success(description='Successfully removed the assignment from {}.'.format(str(course)))
Exemple #3
0
def get_new_assignment_response(lti_params, course, role):
    """Generate assignment information for the teacher to setup the assignment with.

    This only works when the lti user is a teacher of that assignment.
    """
    if 'Teacher' not in role:
        return response.success({
            'params': {
                'state':
                LTI_STATES.LACKING_PERMISSION_TO_SETUP_ASSIGNMENT.value,
                'lti_cName': lti_params['custom_course_name'],
                'lti_aName': lti_params['custom_assignment_title'],
            }
        })

    try:
        return response.success({
            'params': {
                'state': LTI_STATES.NEW_ASSIGN.value,
                'cID': course.pk,
                'lti_aName': lti_params['custom_assignment_title'],
                'lti_aID': lti_params['custom_assignment_id'],
                'lti_aUnlock': lti_params['custom_assignment_unlock'],
                'lti_aDue': lti_params['custom_assignment_due'],
                'lti_aLock': lti_params['custom_assignment_lock'],
                'lti_points_possible': lti_params['custom_assignment_points'],
                'lti_aPublished': lti_params['custom_assignment_publish'],
            }
        })
    except KeyError as err:
        raise VLEMissingRequiredKey(err.args[0])
Exemple #4
0
    def retrieve(self, request, pk=0):
        """Get the permissions of a user connected to a course / assignment.

        Arguments:
        request -- the request that was sent
            course_id -- course ID
            assignment_id -- assignment ID
        pk -- user ID (0 = logged in user)

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course is not found
            forbidden -- when the user is not in the course
        On success:
            success -- with a list of the permissions

        """
        if int(pk) == 0:
            pk = request.user.id
        user = User.objects.get(pk=pk)

        # Return course permissions if course_id is set
        try:
            course_id, = utils.required_typed_params(request.query_params,
                                                     (int, 'course_id'))
            course = Course.objects.get(pk=course_id)

            request.user.check_participation(course)

            if user != request.user:
                # TODO: P Is this the right permission
                request.user.check_permission('can_edit_course_roles', course)

            return response.success({
                'role':
                permissions.serialize_course_permissions(request.user, course)
            })
        # Return assignment permissions if assignment_id is set
        except (VLEMissingRequiredKey, VLEParamWrongType):
            assignment_id, = utils.required_typed_params(
                request.query_params, (int, 'assignment_id'))
            assignment = Assignment.objects.get(pk=assignment_id)

            request.user.check_can_view(assignment)

            if user != request.user:
                # TODO: P Add a permission for this
                request.user.check_permission('can_view_all_journals', course)

            return response.success({
                'role':
                permissions.serialize_assignment_permissions(
                    request.user, assignment)
            })
Exemple #5
0
    def destroy(self, request, *args, **kwargs):
        """Delete an existing assignment from a course.

        Arguments:
        request -- request data
            course_id -- the course ID of course this assignment belongs to
        pk -- assignment ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the assignment or course does not exist
            unauthorized -- when the user is not logged in
            forbidden -- when the user cannot delete the assignment
        On success:
            success -- with a message that the course was deleted

        """
        assignment_id, = utils.required_typed_params(kwargs, (int, 'pk'))
        course_id, = utils.required_typed_params(request.query_params,
                                                 (int, 'course_id'))
        assignment = Assignment.objects.get(pk=assignment_id)
        course = Course.objects.get(pk=course_id)

        request.user.check_permission('can_delete_assignment', course)

        intersecting_assignment_lti_id = assignment.get_course_lti_id(course)
        if intersecting_assignment_lti_id:
            if assignment.active_lti_id == intersecting_assignment_lti_id and len(
                    assignment.lti_id_set) > 1:
                return response.bad_request(
                    'This assignment cannot be removed from this course, since it is'
                    + ' currently configured for grade passback to the LMS')
            course.assignment_lti_id_set.remove(intersecting_assignment_lti_id)
            assignment.lti_id_set.remove(intersecting_assignment_lti_id)
            course.save()

        assignment.courses.remove(course)
        assignment.save()

        if assignment.active_lti_id is not None and assignment.active_lti_id in course.assignment_lti_id_set:
            course.assignment_lti_id_set.remove(assignment.active_lti_id)
            course.save()

        # If the assignment is only connected to one course, delete it completely
        if assignment.courses.count() == 0:
            assignment.delete()
            return response.success(
                description='Successfully deleted the assignment.')
        else:
            return response.success(
                description='Successfully removed the assignment from {}.'.
                format(str(course)))
Exemple #6
0
    def unenrolled(self, request):
        """Get all users that are not in the given course.

        Arguments:
        request -- request data
            course_id -- course ID
            unenrolled_query -- query that needs to match with the unenrolled users

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exist
            forbidden -- when the user is not in the course
            forbidden -- when the user is unauthorized to view its participants
        On success:
            success -- list of all the users and their role
        """
        course_id, unenrolled_query = utils.required_params(
            request.query_params, 'course_id', 'unenrolled_query')
        if ' ' in unenrolled_query:
            first_name = unenrolled_query.split(' ', 1)[0]
            last_name = unenrolled_query.split(' ', 1)[1]

        course = Course.objects.get(pk=course_id)
        request.user.check_permission('can_add_course_users', course)

        ids_in_course = course.participation_set.all().values('user__id')
        users = User.objects.all().exclude(id__in=ids_in_course)

        if len(unenrolled_query) < 5:
            user = users.filter(username=unenrolled_query)
            if user:
                return response.success(
                    {'participants': UserSerializer(user, many=True).data})
            else:
                return response.success({'participants': []})

        found_users = users.filter(
            Q(username__contains=unenrolled_query)
            | Q(first_name__contains=unenrolled_query)
            | Q(last_name__contains=unenrolled_query))

        if ' ' in unenrolled_query:
            found_users = found_users | users.filter(
                first_name__contains=first_name, last_name__contains=last_name)

        return response.success(
            {'participants': UserSerializer(found_users, many=True).data})
Exemple #7
0
    def linkable(self, request):
        """Get linkable courses.

        Gets all courses that the current user either participates in or is allowed to edit the course details of.
        A user can then link this course to Canvas.

        Arguments:
        request -- request data

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exist
            forbidden -- when the user is not in the course
        On success:
            success -- with a message that the course was deleted
        """
        if not (request.user.is_teacher or request.user.is_superuser):
            return response.forbidden(
                "You are not allowed to get linkable courses.")

        unlinked_courses = Course.objects.filter(
            participation__user=request.user.id,
            participation__role__can_edit_course_details=True)
        serializer = serialize.CourseSerializer(unlinked_courses, many=True)
        data = serializer.data
        for i, course in enumerate(data):
            data[i]['lti_couples'] = len(
                Lti_ids.objects.filter(course=course['id']))
        return response.success({'courses': data})
Exemple #8
0
    def copyable(self, request, pk):
        """Get all assignments that a user can copy a format from, except for the current assignment.

        Arguments:
        pk -- assignment ID

        Returns a list of tuples consisting of courses and copyable assignments."""
        courses = Course.objects.filter(
            participation__user=request.user.id,
            participation__role__can_edit_assignment=True)

        copyable = []
        for course in courses:
            assignments = Assignment.objects.filter(courses=course).exclude(
                pk=pk)
            if assignments:
                copyable.append({
                    'course':
                    CourseSerializer(course).data,
                    'assignments':
                    AssignmentDetailsSerializer(assignments,
                                                context={
                                                    'user': request.user
                                                },
                                                many=True).data
                })
        return response.success({'data': copyable})
Exemple #9
0
    def destroy(self, request, *args, **kwargs):
        """Delete an existing course group.

        Arguments:
        request -- request data
            group_name -- name of the course
        pk -- course ID

        Returns:
        On failure:
            not found -- when the course does not exists
            unauthorized -- when the user is not logged in
            forbidden -- when the user is not in the course
        On success:
            success -- with a message that the course group was deleted
        """
        course_id, = utils.required_typed_params(kwargs, (int, 'pk'))
        name, = utils.required_typed_params(request.query_params, (str, 'group_name'))

        course = Course.objects.get(pk=course_id)

        request.user.check_permission('can_delete_course_user_group', course)

        group = Group.objects.get(name=name, course=course)
        group.delete()
        return response.success(description='Successfully deleted course group.')
Exemple #10
0
    def list(self, request):
        """Get the assignments from a course for the user.

        Arguments:
        request -- request data
            course_id -- course ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exist
            forbidden -- when the user is not part of the course
        On succes:
            success -- with the assignment data

        """
        try:
            course_id, = utils.optional_typed_params(request.query_params, (int, 'course_id'))
            course = Course.objects.get(pk=course_id)
            request.user.check_participation(course)
            courses = [course]
        except VLEParamWrongType:
            course = None
            courses = request.user.participations.all()

        query = Assignment.objects.filter(courses__in=courses).distinct()
        viewable = [assignment for assignment in query if request.user.can_view(assignment)]
        serializer = AssignmentSerializer(viewable, many=True, context={'user': request.user, 'course': course})

        data = serializer.data
        for i, assignment in enumerate(data):
            data[i]['lti_couples'] = len(Lti_ids.objects.filter(assignment=assignment['id']))
        return response.success({'assignments': data})
Exemple #11
0
    def destroy(self, request, *args, **kwargs):
        """Delete an existing comment from an entry.

        Arguments:
        request -- request data
        pk -- comment ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the comment or author does not exist
            forbidden -- when the user cannot delete the assignment
        On success:
            success -- with a message that the comment was deleted

        """
        comment_id, = utils.required_typed_params(kwargs, (int, 'pk'))
        comment = Comment.objects.get(pk=comment_id)
        journal = comment.entry.node.journal

        request.user.check_can_view(journal)

        if not (request.user.is_superuser or request.user.id == comment.author.id):
            return response.forbidden(description='You are not allowed to delete this comment.')

        comment.delete()
        return response.success(description='Successfully deleted comment.')
Exemple #12
0
def send_feedback(request):
    """Send an email with feedback to the developers.

    Arguments:
    request -- the request that was sent.
        topic -- the topic of the feedback.
        type -- the type of feedback.
        feedback -- the actual feedback.
        browser -- the browser of the user who sends the feedback.
        files -- potential files as attachments.

    Returns:
    On failure:
        bad request -- when required keys are missing or file sizes too big.
        unauthorized -- when the user is not logged in.
    On success:
        success -- with a description.
    """
    request.user.check_verified_email()
    utils.required_params(request.POST, 'topic', 'feedback', 'ftype',
                          'user_agent')

    files = request.FILES.getlist('files')
    validators.validate_email_files(files)
    email_handling.send_email_feedback(request.user, files, **request.POST)
    return response.success(
        description='Feedback was successfully received, thank you!')
Exemple #13
0
    def partial_update(self, request, *args, **kwargs):
        """Update an existing course group.

        Arguments:
        request -- request data
            name -- group name
        pk -- group ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exists
            forbidden -- when the user is not in the course
            unauthorized -- when the user is unauthorized to edit the course
            bad_request -- when there is invalid data in the request
        On success:
            success -- with the new course data
        """
        name, = utils.required_params(request.data, 'name')

        group_id, = utils.required_typed_params(kwargs, (int, 'pk'))
        group = Group.objects.get(pk=group_id)
        course = group.course

        request.user.check_permission('can_edit_course_user_group', course)

        if not name:
            return response.bad_request('Group name is not allowed to be empty.')

        serializer = GroupSerializer(group, data={'name': name}, partial=True)
        if not serializer.is_valid():
            return response.bad_request()

        serializer.save()
        return response.success({'group': serializer.data})
Exemple #14
0
    def list(self, request):
        """Get the groups from a course for the user.

        Arguments:
        request -- request data
            course_id -- course ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exists
            forbidden -- when the user is not part of the course
        On success:
            success -- with the group data

        """
        course_id, = utils.required_typed_params(request.query_params, (int, 'course_id'))

        course = Course.objects.get(pk=course_id)

        check_can_view_groups(request.user, course)

        queryset = Group.objects.filter(course=course)
        serializer = GroupSerializer(queryset, many=True, context={'user': request.user, 'course': course})

        return response.success({'groups': serializer.data})
Exemple #15
0
def names(request, course_id, assignment_id, journal_id):
    """Get names of course, assignment, journal.

    Arguments:
    request -- the request that was sent
        course_id -- optionally the course id
        assignment_id -- optionally the assignment id
        journal_id -- optionally the journal id

    Returns a json string containing the names of the set fields.
    course_id populates 'course', assignment_id populates 'assignment', tID populates
    'template' and journal_id populates 'journal' with the users' name.
    """
    result = {}
    if course_id:
        course = Course.objects.get(pk=course_id)
        request.user.check_participation(course)
        result['course'] = course.name

    if assignment_id:
        assignment = Assignment.objects.get(pk=assignment_id)
        request.user.check_can_view(assignment)
        result['assignment'] = assignment.name

    if journal_id:
        journal = Journal.objects.get(pk=journal_id)
        request.user.check_can_view(journal)
        result[
            'journal'] = journal.user.first_name + " " + journal.user.last_name

    return response.success({'names': result})
Exemple #16
0
def forgot_password(request):
    """Handles a forgot password request.

    Arguments:
        username -- User claimed username.
        email -- User claimed email.
        token -- Django stateless token, invalidated after password change or after a set time (by default three days).

    Generates a recovery token if a matching user can be found by either the prodived username or email.
    """
    username, email = utils.optional_params(request.data, 'username', 'email')

    # We are retrieving the username based on either the username or email
    try:
        user = User.objects.get(username=username)
        email = 'your recovery address'
    except User.DoesNotExist:
        if email is None or email == '':
            return response.not_found('Invalid email address provided.')
        user = User.objects.get(email=email)

    if not user.email:
        return response.bad_request(
            description='The provided account has no known email address.')

    send_password_recovery_link.delay(user.pk)
    return response.success(
        description='An email was sent to {}, please check your inbox for further instructions.'.format(email))
Exemple #17
0
def send_feedback(request):
    """Send an email with feedback to the developers.

    Arguments:
    request -- the request that was sent.
        topic -- the topic of the feedback.
        type -- the type of feedback.
        feedback -- the actual feedback.
        browser -- the browser of the user who sends the feedback.
        files -- potential files as attachments, currently only one file is processed.

    Returns:
    On failure:
        bad request -- when required keys are missing or file sizes too big.
        unauthorized -- when the user is not logged in.
    On success:
        success -- with a description.
    """
    request.user.check_verified_email()
    topic, ftype, feedback, user_agent, url = \
        utils.required_params(request.data, 'topic', 'ftype', 'feedback', 'user_agent', 'url')

    if request.FILES:
        files = request.FILES.getlist('files')
        validators.validate_email_files(files)
        if request.user.feedback_file:
            request.user.feedback_file.delete()
        request.user.feedback_file = files[0]
        request.user.save()
        send_email_feedback.delay(
            request.user.pk, topic, ftype, feedback, user_agent, url, file_content_type=files[0].content_type)
    else:
        send_email_feedback.delay(request.user.pk, topic, ftype, feedback, user_agent, url)

    return response.success(description='Thank you for contacting support, we\'ll get back to you as soon as possible!')
Exemple #18
0
    def retrieve(self, request, pk):
        """Get the user data of the requested user.

        Arguments:
        request -- request data
        pk -- user ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the user doesn't exists
        On success:
            success -- with the user data
        """
        if int(pk) == 0:
            pk = request.user.id

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

        if request.user == user or request.user.is_superuser:
            serializer = OwnUserSerializer(user, many=False)
        elif permissions.is_user_supervisor_of(request.user, user):
            serializer = UserSerializer(user, many=False)
        else:
            return response.forbidden('You are not allowed to view this users information.')

        return response.success({'user': serializer.data})
Exemple #19
0
    def password(self, request):
        """Change the password of a user.

        Arguments:
        request -- request data
            new_password -- new password of the user
            old_password -- current password of the user

        Returns
        On failure:
            unauthorized -- when the user is not logged in
            bad request -- when the password is invalid
        On success:
            success -- with a success description
        """
        new_password, old_password = utils.required_params(request.data, 'new_password', 'old_password')

        if not request.user.check_password(old_password):
            return response.bad_request('Wrong password.')

        if validators.validate_password(new_password):
            return response.bad_request(validators.validate_password(new_password))

        request.user.set_password(new_password)
        request.user.save()
        return response.success(description='Successfully changed the password.')
Exemple #20
0
    def partial_update(self, request, *args, **kwargs):
        """Update an existing course.

        Arguments:
        request -- request data
            data -- the new data for the course
        pk -- course ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exist
            forbidden -- when the user is not in the course
            unauthorized -- when the user is unauthorized to edit the course
            bad_request -- when there is invalid data in the request
        On success:
            success -- with the new course data
        """
        course_id, = utils.required_typed_params(kwargs, (int, 'pk'))
        course = Course.objects.get(pk=course_id)

        request.user.check_permission('can_edit_course_details', course)

        data = request.data
        if 'lti_id' in data:
            factory.make_lti_ids(lti_id=data['lti_id'],
                                 for_model=Lti_ids.COURSE,
                                 course=course)

        serializer = self.serializer_class(course, data=data, partial=True)
        if not serializer.is_valid():
            response.bad_request()
        serializer.save()
        return response.success({'course': serializer.data})
Exemple #21
0
    def partial_update(self, request, *args, **kwargs):
        """Update the preferences of a user.

        Arguments:
        request -- request data
        pk -- user ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            forbidden -- when the user is not superuser or pk is not the same as the logged in user
            not found -- when the user doesnt exist
            bad request -- when the data is invalid
        On success:
            success -- with the updated preferences
        """
        pk, = utils.required_typed_params(kwargs, (int, 'pk'))
        if not (request.user.pk == pk or request.user.is_superuser):
            return response.forbidden('You are not allowed to change this users preferences.')

        preferences = Preferences.objects.get(user=pk)
        serializer = PreferencesSerializer(preferences, data=request.data, partial=True)

        if not serializer.is_valid():
            return response.bad_request('Invalid preference data provided.')

        serializer.save()

        return response.success({'preferences': serializer.data})
Exemple #22
0
    def list(self, request):
        """Get the comments belonging to an entry.

        Arguments:
        request -- request data
            entry_id -- entry ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exist
            forbidden -- when its not their own journal, or the user is not allowed to grade that journal
        On succes:
            success -- with a list of the comments belonging to the entry

        """
        entry_id, = utils.required_params(request.query_params, "entry_id")

        entry = Entry.objects.get(pk=entry_id)
        journal = entry.node.journal
        assignment = journal.assignment

        request.user.check_can_view(journal)

        if request.user.has_permission('can_grade', assignment):
            comments = Comment.objects.filter(entry=entry)
        else:
            comments = Comment.objects.filter(entry=entry, published=True)

        serializer = CommentSerializer(comments, many=True)
        return response.success({'comments': serializer.data})
Exemple #23
0
def recover_password(request):
    """Handles a reset password request.

    Arguments:
        username -- User claimed username.
        recovery_token -- Django stateless token, invalidated after password change or after a set time
            (by default three days).
        new_password -- The new user desired password.

    Updates password if the recovery_token is valid.
    """
    username, recovery_token, new_password = utils.required_params(
        request.data, 'username', 'recovery_token', 'new_password')

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

    recovery_token, = utils.required_params(request.data, 'recovery_token')
    token_generator = PasswordResetTokenGenerator()
    if not token_generator.check_token(user, recovery_token):
        return response.bad_request('Invalid recovery token.')

    validators.validate_password(new_password)

    user.set_password(new_password)
    user.save()

    return response.success(
        description='Successfully changed the password, you can now log in.')
Exemple #24
0
    def destroy(self, request, pk):
        """Delete course role.

        Arguments:
        request -- request data
            name -- role name
        pk -- course ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            forbidden -- when the user is not in the course
            forbidden -- when the user is unauthorized to edit its roles
        On success:
            success -- newly created course

        """
        name, = utils.required_typed_params(request.query_params,
                                            (str, 'name'))
        course = Course.objects.get(pk=pk)

        # Users can only delete course roles with can_edit_course_roles
        request.user.check_permission('can_edit_course_roles', course)

        if name in ['Student', 'TA', 'Teacher']:
            return response.bad_request(
                'Default roles "Student", "TA" and "Teacher" cannot be deleted.'
            )

        Role.objects.get(name=name, course=pk).delete()
        return response.success(
            description='Successfully deleted role from course.')
Exemple #25
0
    def upcoming(self, request):
        """Get upcoming deadlines for the requested user.

        Arguments:
        request -- request data
            course_id -- course ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exist
        On success:
            success -- upcoming assignments

        """
        try:
            course_id, = utils.required_typed_params(request.query_params, (int, 'course_id'))
            course = Course.objects.get(pk=course_id)
            courses = [course]
        except (VLEMissingRequiredKey, VLEParamWrongType):
            course = None
            courses = request.user.participations.all()

        now = timezone.now()
        query = Assignment.objects.filter(
            Q(lock_date__gt=now) | Q(lock_date=None), courses__in=courses
        ).distinct()
        viewable = [assignment for assignment in query if request.user.can_view(assignment)]
        upcoming = AssignmentSerializer(viewable, context={'user': request.user, 'course': course}, many=True).data

        return response.success({'upcoming': upcoming})
Exemple #26
0
    def partial_update(self, request, *args, **kwargs):
        """Update instance details.

        Arguments:
        request -- request data
            data -- the new data for the journal

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            forbidden -- User not allowed to edit instance
            bad_request -- when there is invalid data in the request
        On success:
            success -- with the new instance details
        """
        if not request.user.is_superuser:
            return response.forbidden(
                'You are not allowed to edit instance details.')

        try:
            instance = Instance.objects.get(pk=1)
        except Instance.DoesNotExist:
            instance = factory.make_instance()

        req_data = request.data
        serializer = InstanceSerializer(instance, data=req_data, partial=True)
        if not serializer.is_valid():
            response.bad_request()
        serializer.save()

        return response.success({'instance': serializer.data})
Exemple #27
0
    def list(self, request):
        """Get course roles.

        Arguments:
        request -- request data
            course_id -- course ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exist
            forbidden -- when the user is not in the course
            forbidden -- when the user is unauthorized to edit its roles
        On success:
            success -- list of all the roles in the course

        """
        course_id, = utils.required_typed_params(request.query_params,
                                                 (int, 'course_id'))
        course = Course.objects.get(pk=course_id)

        # TODO: P Is this the right permission
        request.user.check_permission('can_edit_course_roles', course)

        roles = Role.objects.filter(course=course)
        serializer = RoleSerializer(roles, many=True)
        return response.success({'roles': serializer.data})
Exemple #28
0
    def retrieve(self, request, pk=None):
        """Retrieve a comment.

        Arguments:
        request -- request data
        pk -- assignment ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not_found -- could not find the course with the given id
            forbidden -- not allowed to retrieve assignments in this course

        On success:
            succes -- with the comment data

        """
        comment = Comment.objects.get(pk=pk)
        journal = comment.entry.node.journal

        request.user.check_can_view(journal)

        serializer = CommentSerializer(comment)

        return response.success({'comment': serializer.data})
Exemple #29
0
    def list(self, request):
        """Get all users and their roles for a given course.

        Arguments:
        request -- request data
            course_id -- course ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the course does not exist
            forbidden -- when the user is not in the course
            forbidden -- when the user is unauthorized to view its participants
        On success:
            success -- list of all the users and their role
        """
        course_id, = utils.required_params(request.query_params, "course_id")

        course = Course.objects.get(pk=course_id)

        request.user.check_permission('can_view_course_users', course)

        users = UserSerializer(course.users,
                               context={
                                   'course': course
                               },
                               many=True).data
        return response.success({'participants': users})
Exemple #30
0
    def list(self, request):
        """Get the student submitted journals of one assignment from a course.

        Arguments:
        request -- request data
            course_id -- course ID
            assignment_id -- assignment ID

        Returns:
        On failure:
            unauthorized -- when the user is not logged in
            not found -- when the assignment does not exist
            forbidden -- when the user has no permission to view the journals of the assignment
        On succes:
            success -- with journals and stats about the journals

        """
        assignment_id, course_id = utils.required_typed_params(
            request.query_params, (int, 'assignment_id'), (int, 'course_id'))
        assignment = Assignment.objects.get(pk=assignment_id)
        course = Course.objects.get(pk=course_id)

        request.user.check_permission('can_view_all_journals', assignment)
        request.user.check_can_view(assignment)

        users = course.participation_set.filter(
            role__can_have_journal=True).values('user')
        queryset = assignment.journal_set.filter(user__in=users)
        journals = JournalSerializer(queryset, many=True).data

        return response.success({'journals': journals})