Example #1
0
def update_assignment_question_list(req):

    post_data = json.loads(req.body)

    try:
        question_id = post_data["question_id"]
        assignment_identifier = post_data["assignment_identifier"]
    except KeyError:
        return response_400(req, msg=_("There are missing parameters."))

    try:
        assignment = Assignment.objects.get(identifier=assignment_identifier)
    except Assignment.DoesNotExist:
        return response_400(req, msg=_("Some parameters are wrong."))

    # Check object permissions (to be refactored using mixin)
    if req.user in assignment.owner.all() or req.user.is_staff:
        # Check for student answers
        if assignment.answer_set.exclude(user_token__exact="").count() > 0:
            raise PermissionDenied
    else:
        raise PermissionDenied

    try:
        question = Question.objects.get(id=question_id)
    except Question.DoesNotExist:
        return response_400(req, msg=_("Some parameters are wrong."))

    if question in assignment.questions.all():
        assignment.questions.remove(question)
    else:
        assignment.questions.add(question)
    assignment.save()

    return HttpResponse("Success")
Example #2
0
def get_json_params(
    req: HttpRequest,
    args: Optional[List[str]] = None,
    opt_args: Optional[List[str]] = None,
) -> Union[Tuple[List[Any], List[Any]], HttpResponse]:
    if args is None:
        args = []
    if opt_args is None:
        opt_args = []
    try:
        data = json.loads(req.body)
    except ValueError:
        return response_400(
            req,
            msg=_("Wrong data type was sent."),
            logger_msg=("The sent data wasn't in a valid JSON format."),
            log=logger.warning,
        )
    try:
        args = [data[arg] for arg in args]
        opt_args = [data.get(arg) for arg in opt_args]
    except KeyError as e:
        return response_400(
            req,
            msg=_("There are missing parameters."),
            logger_msg=("The arguments {} were missing.".format(", ".join(
                e.args))),
            log=logger.warning,
        )
    return args, opt_args
Example #3
0
def send_student_assignment(req, assignment_hash, teacher, group, assignment):

    try:
        data = json.loads(req.body)
    except ValueError:
        return response_400(req, msg=_("Wrong data type was sent."))

    try:
        email = data["email"]
    except KeyError:
        return response_400(req, msg=_("There are missing parameters."))

    try:
        student = Student.objects.get(student__email=email)
    except Student.DoesNotExist:
        return response_400(
            req, msg=_('There is no student with email "{}".'.format(email)))

    student_assignment, __ = StudentAssignment.objects.get_or_create(
        group_assignment=assignment, student=student)

    err = student_assignment.send_email("new_assignment")

    if err is not None:
        return response_500(req, msg=_(err))

    return HttpResponse()
Example #4
0
def group_details_update(req, group_hash, teacher, group):
    """
    Updates the field of the group using the `name` and `value` given by the
    post request data.

    Parameters
    ----------
    group_hash : str
        Hash of the group
    teacher : Teacher
    group : StudentGroup
        Group corresponding to the hash (returned by `group_access_required`)

    Returns
    -------
    HttpResponse
        Either an empty 200 response if everything worked or an error response
    """

    name, value = validate_update_data(req)
    if isinstance(name, HttpResponse):
        return name

    if name == "name":
        if (name != group.name
                and StudentGroup.objects.filter(name=name).exists()):
            return response_400(req, msg=_("That name already exists."))
        group.name = value
        group.save()
        logger.info("Group %d's name was changed to %s.", group.pk, value)

    elif name == "title":
        group.title = value
        group.save()
        logger.info("Group %d's title was changed to %s.", group.pk, value)

    elif name == "teacher":
        try:
            teacher = Teacher.objects.get(user__username=value)
        except Teacher.DoesNotExist:
            return response_400(
                req,
                msg=_("There is no teacher with username {}.".format(teacher)),
            )
        group.teacher.add(teacher)
        group.save()
        logger.info("Teacher %d was added to group %d.", value, group.pk)

    elif name == "student_id_needed":
        group.student_id_needed = value
        group.save()
        logger.info("Student id needed was set to %s for group %d.", value,
                    group.pk)

    else:
        return response_400(req, msg=_("Wrong data type was sent."))

    return HttpResponse(content_type="text/plain")
Example #5
0
def signup_through_link(request, group_hash):

    # Call logout to ensure a clean session
    logout(request)

    group = StudentGroup.get(group_hash)

    if group is None:
        return response_404(
            request,
            msg=_("The group couldn't be found. Bear in mind that the URL "
                  "is case-sensitive."),
        )

    if request.method == "POST":

        form = EmailForm(request.POST)
        if not form.is_valid():
            return response_400(
                request, msg=_("There was a problem with the values sent."))

        student, created = Student.get_or_create(form.cleaned_data["email"])

        if student is None:
            return response_400(
                request,
                msg=_("There already exists a user with this username. Try a "
                      "different email address."),
            )

        if created:
            student.join_group(group, mail_type="confirmation")
        else:
            student.join_group(group, mail_type="new_group")

        return TemplateResponse(
            request,
            "registration/sign_up_student_done.html",
            context={
                "student": student,
                "group": group
            },
        )

    form = EmailForm()
    tos = Tos.objects.filter(role="student").latest("created").text

    return TemplateResponse(
        request,
        "registration/sign_up_student.html",
        context={
            "form": form,
            "group": group,
            "tos": tos
        },
    )
Example #6
0
def validate_update_data(req):
    try:
        data = json.loads(req.body)
    except ValueError:
        return response_400(req, msg=_("Wrong data type was sent."))

    try:
        name = data["name"]
        value = data["value"]
    except KeyError:
        return response_400(req, msg=_("There are missing parameters."))

    return name, value
Example #7
0
def remove_criterion(req):
    """
    REmoves the given criterion to the quality with the given parameters. The
    request must have parameters:
        quality : int
            Primary key of the quality
        criterion : str
            Name of the criterion

    Returns
    -------
    HttpResponse
        Either an empty HttpResponse or an error response
    """
    try:
        data = json.loads(req.body)
    except ValueError:
        return response_400(
            req,
            msg=_("Wrong data type was sent."),
            logger_msg=("The sent data wasn't in a valid JSON format."),
            log=logger.warning,
        )
    try:
        quality_pk = data["quality"]
        criterion_name = data["criterion"]
    except KeyError as e:
        return response_400(
            req,
            msg=_("There are missing parameters."),
            logger_msg=("The arguments {} were missing.".format(", ".join(
                e.args))),
            log=logger.warning,
        )

    try:
        quality = Quality.objects.get(pk=quality_pk)
    except Quality.DoesNotExist:
        return response_400(
            req,
            msg=_("Some of the parameters were wrong."),
            logger_msg=(
                "There isn't any quality with key {}.".format(quality_pk)),
            log=logger.warning,
        )

    quality.remove_criterion(criterion_name)

    logger.info("Criterion %s was removed from quality %d.", criterion_name,
                quality_pk)
    return HttpResponse()
Example #8
0
def evaluate_rationale(req):
    try:
        data = json.loads(req.body)
    except ValueError:
        return response_400(
            req,
            msg=_("Wrong data type was sent."),
            logger_msg=("The sent data wasn't in a valid JSON format."),
            log=logger.warning,
        )
    try:
        answer_pk = data["answer"]
        quality_pk = data["quality"]
    except KeyError as e:
        return response_400(
            req,
            msg=_("There are missing parameters."),
            logger_msg=(
                "The arguments {} were missing.".format(", ".join(e.args))
            ),
            log=logger.warning,
        )

    try:
        answer = Answer.objects.get(pk=answer_pk)
    except Answer.DoesNotExist:
        return response_400(
            req,
            msg=_("Some of the parameters were wrong."),
            logger_msg=(
                "There isn't any answer with key {}.".format(answer_pk)
            ),
            log=logger.warning,
        )

    try:
        quality = Quality.objects.get(pk=quality_pk)
        quality_, evaluation = quality.evaluate(answer)
        return JsonResponse({"quality": quality_, "evaluation": evaluation})
    except Quality.DoesNotExist:
        return response_400(
            req,
            msg=_("Some of the parameters were wrong."),
            logger_msg=(
                "There isn't any quality with key {}.".format(quality_pk)
            ),
            log=logger.warning,
        )
Example #9
0
def send_signin_link(req):
    try:
        email = req.POST["email"].lower()
    except KeyError as e:
        return response_400(
            req,
            msg=_("There are missing parameters."),
            logger_msg=("The arguments '%s' were missing.", ",".join(e.args)),
            log=logger.warning,
        )

    student = Student.objects.filter(student__email=email)

    if not student:
        student, created = Student.get_or_create(email)
        logger.info("Student created with email {}.".format(email))

    elif len(student) == 1:
        student = student[0]

    else:
        username, __ = get_student_username_and_password(email)
        student = student.filter(student__username=username).first()

    if student:
        err = student.send_email(mail_type="signin", request=req)
        if err is None:
            context = {"error": False}
        else:
            context = {"error": True}

    return render(req, "peerinst/student/login_confirmation.html", context)
Example #10
0
def get_student_reputation(req):
    """
    Returns the student information along with the convincing rationales
    criterion.

    Parameters
    ----------
    req : HttpRequest
        Request with:
            parameters:
                id: int
                    Student pk

    Returns
    -------
    Either
        JSONResponse
            Response with json data:
                {
                    email : str
                        Student email
                    last_login : str
                        Date of last login in isoformat
                    popularity : float
                        Value of the convincing rationales criterion

                }
        HttpResponse
            Error response
    """
    args = get_json_params(req, args=["id"])
    if isinstance(args, HttpResponse):
        return args
    (id_,), _ = args

    try:
        student = Student.objects.get(pk=id_)
    except Student.DoesNotExist:
        return response_400(
            req,
            msg=_("The student couldn't be found."),
            logger_msg=(
                "The student with pk {} couldn't be found.".format(id_)
            ),
            log=logger.warning,
        )
    criteria = {
        c.name: student.evaluate_reputation(c.name)
        for c in ReputationType.objects.get(type="student").criteria.all()
    }

    return JsonResponse(
        {
            "email": student.student.email,
            "last_login": student.student.last_login.isoformat()
            if student.student.last_login is not None
            else None,
            "criteria": criteria,
        }
    )
Example #11
0
def get_teacher_information(req):
    args = get_query_string_params(req, args=["id"])
    if isinstance(args, HttpResponse):
        return args
    (id_, ), _ = args

    try:
        teacher = Teacher.objects.get(pk=id_)
    except Teacher.DoesNotExist:
        return response_400(
            req,
            msg=translate("There is no teacher with that id"),
            logger_msg=("Teacher with pk {} couldn't be found.".format(id_)),
            log=logger.warning,
        )

    if teacher.reputation is None:
        teacher.reputation = Reputation.create(teacher)

    _, reputations = teacher.reputation.evaluate()

    data = {
        "username":
        teacher.user.username,
        "last_login":
        teacher.user.last_login.strftime("%Y-%m-%d %H:%M:%S")
        if teacher.user.last_login is not None else None,
        "reputations": [{
            "name": reputation["name"],
            "reputation": reputation["reputation"],
        } for reputation in reputations],
    }
    return JsonResponse(data)
Example #12
0
def student_reputation(req):
    args = get_json_params(req, args=["id"])
    if isinstance(args, HttpResponse):
        return args
    (student_id, ), __ = args

    if req.user.student.pk != student_id:
        return response_403(
            req,
            msg=_("You don't have access to this resource."),
            logger_msg=(
                "Access to reputation of student {} from student {}.".format(
                    student_id, req.user.student.pk)),
            log=logger.warning,
        )

    try:
        student = Student.objects.get(pk=student_id)
    except Student.DoesNotExist:
        return response_400(
            req,
            msg=_("This student doesn't exist."),
            logger_msg=(
                "Tried to obtain student with pk {}".format(student_id)),
            log=logger.warning,
        )

    if student.reputation is None:
        student.reputation = Reputation.create(student)
        student.save()

    reputation, reputations = student.reputation.evaluate()

    data = {"reputation": reputation, "reputations": reputations}
    return JsonResponse(data, status=200)
Example #13
0
def get_groups_activity(req: HttpRequest, discipline: str) -> HttpResponse:
    try:
        discipline = Discipline.objects.get(title=discipline)
    except Discipline.DoesNotExist:
        return response_400(
            req,
            f"There is no discipline {discipline}.",
            "A request to get group activity for non existing "
            f"discipline {discipline} was made.",
            logger.warning,
            use_template=False,
        )

    groups = [
        group
        for group in StudentGroup.objects.iterator()
        if group.teacher.count()
        and discipline in group.teacher.first().disciplines.all()
    ]

    data = {
        "activity": [
            {
                "name": group.title,
                "teacher": group.teacher.last().user.username,
                "n_students": group.studentgroupmembership_set.count(),
            }
            for group in groups
        ]
    }

    return JsonResponse(data)
Example #14
0
def verify_question(req, type_, question_pk):
    """
    Verifies if the question exists and the user is allowed to change the
    question, returning it if that's the case and an error response if not.

    Parameters
    ----------
    req : HttpRequest
        Request
    type_ : str
        Which use type it the quality for
    question_pk : int
        Primary key for the question

    Returns
    -------
    Either
        Quality
            Quality corresponding to the question
        HttpResponse
            400 or 403 error response
    """
    return response_400(
        req,
        msg=_("Some parameters are wrong"),
        logger_msg=(
            "An access to {} was tried with a question primary key.".format(
                req.path)),
        log=logger.warning,
    )
Example #15
0
def teacher_reputation(req):
    args = get_json_params(req, args=["id"])
    if isinstance(args, HttpResponse):
        return args
    (teacher_id, ), __ = args

    try:
        teacher = Teacher.objects.get(pk=teacher_id)
    except (Teacher.DoesNotExist, AttributeError):
        return response_400(
            req,
            msg=_("This teacher doesn't exist."),
            logger_msg=(
                "Tried to obtain teacher with pk {}".format(teacher_id)),
            log=logger.warning,
        )

    if teacher.reputation is None:
        teacher.reputation = Reputation.create(teacher)
        teacher.save()

    reputation, reputations = teacher.reputation.evaluate()

    data = {"reputation": reputation, "reputations": reputations}

    return JsonResponse(data, status=200)
Example #16
0
def remove_notification(req, student):
    """
    Removes the notification with the pk given as post value.

    Parameters
    ----------
    req : HttpRequest
        Request with post parameters:
            notification_pk : str
                Primary key of the notification
    student : Student
        Returned by @student_required (not used)

    Returns
    -------
    HttpResponse
        Empty 200 response if no errors or error response
    """
    try:
        data = json.loads(req.body)
    except ValueError:
        return response_400(
            req,
            msg=_("Wrong data type was sent."),
            logger_msg=("The sent data wasn't in a valid JSON format."),
            log=logger.warning,
        )

    try:
        notification_pk = data["notification_pk"]
    except KeyError as e:
        return response_400(
            req,
            msg=_("There are missing parameters."),
            logger_msg=("The arguments '%s' were missing.", ",".join(e.args)),
            log=logger.warning,
        )

    try:
        StudentNotification.objects.get(pk=notification_pk).delete()
    except StudentNotification.DoesNotExist:
        pass

    return HttpResponse()
Example #17
0
def group_assignment_update(req, assignment_hash, teacher, group, assignment):

    name, value = validate_update_data(req)
    if isinstance(name, HttpResponse):
        return name

    err = assignment.update(name, value)

    if err is not None:
        return response_400(req, msg=_(err))

    return HttpResponse(content_type="text/plain")
Example #18
0
def verify_teacher(req, type_):
    """
    Verifies if the teacher exists , returning it if that's the case and an
    error response if not.

    Parameters
    ----------
    req : HttpRequest
        Request
    type_ : str
        Which use type it the quality for

    Returns
    -------
    Either
        Quality
            Quality corresponding to the group
        HttpResponse
            400 or 403 error response
    """
    try:
        teacher = Teacher.objects.get(user=req.user)
    except (Teacher.DoesNotExist, AttributeError):
        return response_403(
            req,
            msg=_("You don't have access to this resource."),
            logger_msg=("Access to {} from user {}.".format(
                req.path,
                req.user.pk if hasattr(req, "user")
                and isinstance(req.user, User) else "anonymous",
            )),
            log=logger.warning,
        )

    if teacher.quality is None:
        quality_type = QualityType.objects.get(type="teacher")
        try:
            quality_use_type = QualityUseType.objects.get(type=type_)
        except QualityUseType.DoesNotExist:
            return response_400(
                req,
                msg=_("Some parameters are wrong"),
                logger_msg=("An access to {} was tried with the wrong ".format(
                    req.path) + "quality use type{}.".format(type_)),
                log=logger.warning,
            )

        teacher.quality = Quality.objects.create(
            quality_type=quality_type, quality_use_type=quality_use_type)
        teacher.save()

    return teacher.quality
Example #19
0
def flag_question(req, teacher):
    args = get_json_params(req, args=["id", "reason"])
    if isinstance(args, HttpResponse):
        return args
    (question_id, reason), _ = args

    try:
        question = Question.objects.get(id=question_id)
    except Question.DoesNotExist:
        return response_400(
            req,
            msg=translate("The question couldn't be found."),
            logger_msg=("The question with pk {} couldn't be found.".format(
                question_id)),
            log=logger.warning,
        )

    try:
        flag_reason = QuestionFlagReason.objects.get(title=reason)
    except Question.DoesNotExist:
        return response_400(
            req,
            msg=translate("The flag reason couldn't be found."),
            logger_msg=(
                "The question flag reason with title {} ".format(reason) +
                "couldn't be found."),
            log=logger.warning,
        )

    flag = QuestionFlag.objects.create(question=question,
                                       user=teacher.user,
                                       flag=True)
    flag.flag_reason.add(flag_reason)
    logger.info("Question flagged!")

    return HttpResponse("")
Example #20
0
def test_response_400__default_message(rf, caplog):
    logger = logging.getLogger("test")
    req = rf.get("/test")
    req.user = AnonymousUser()

    resp = response_400(req,
                        msg="test1",
                        log=logger.warning,
                        use_template=True)

    assert isinstance(resp, TemplateResponse)
    assert resp.status_code == 400
    assert len(caplog.records) == 1
    assert (caplog.records[0].message ==
            "400 error for user AnonymousUser on path /test.")
Example #21
0
def test_response_400(rf, caplog):
    logger = logging.getLogger("test")
    req = rf.get("/test")

    resp = response_400(
        req,
        msg="test1",
        logger_msg="test2",
        log=logger.warning,
        use_template=True,
    )

    assert isinstance(resp, TemplateResponse)
    assert resp.status_code == 400
    assert len(caplog.records) == 1
    assert caplog.records[0].message == "test2"
Example #22
0
def get_query_string_params(req, args=None, opt_args=None):
    if args is None:
        args = []
    if opt_args is None:
        opt_args = []
    try:
        args = [req.GET[arg] for arg in args]
        opt_args = [req.GET.get(arg) for arg in opt_args]
    except KeyError as e:
        return response_400(
            req,
            msg=_("There are missing parameters."),
            logger_msg=("The arguments {} were missing.".format(", ".join(
                e.args))),
            log=logger.warning,
        )
    return args, opt_args
Example #23
0
def reputation(req):
    args = get_json_params(req, args=["reputation_type"])
    if isinstance(args, HttpResponse):
        return args
    (reputation_type, ), __ = args

    if reputation_type == "teacher":
        return teacher_reputation(req)
    if reputation_type == "student":
        return student_reputation(req)
    else:
        return response_400(
            req,
            msg=_("This isn't a supported reputation type."),
            logger_msg=("The sent data used reputation type {} ".format(
                reputation_type) + "which isn't supported."),
            log=logger.warning,
        )
Example #24
0
def get_query_string_params(
    req: HttpRequest,
    args: Optional[List[str]] = None,
    opt_args: Optional[List[str]] = None,
) -> Union[Tuple[List[Any], List[Any]], HttpResponse]:
    if args is None:
        args = []
    if opt_args is None:
        opt_args = []
    try:
        args = [req.GET[arg] for arg in args]
        opt_args = [req.GET.get(arg) for arg in opt_args]
    except KeyError as e:
        return response_400(
            req,
            msg=_("There are missing parameters."),
            logger_msg=("The arguments {} were missing.".format(", ".join(
                e.args))),
            log=logger.warning,
        )
    return args, opt_args
Example #25
0
def unsubscribe_from_thread(req, teacher):
    """
    Unsubscribes the `teacher` from a thread (won't appear in the messages).

    Parameters
    ----------
    req : HttpRequest
        Request with:
            parameters:
                id: int
                    Thread primary key
    teacher : Teacher
        Teacher instance returned by `teacher_required`

    Returns
    -------
    HttpResponse
        Error response or empty 200 response
    """
    args = get_json_params(req, args=["id"])
    if isinstance(args, HttpResponse):
        return args
    (id_, ), _ = args
    try:
        thread = ForumThread.objects.get(pk=id_)
    except ForumThread.DoesNotExist:
        return response_400(
            req,
            msg=translate("The thread couldn't be found."),
            logger_msg=(
                "The thread with pk {} couldn't be found.".format(id_)),
            log=logger.warning,
        )

    thread.subscriptions.filter(user=teacher.user).delete()

    return HttpResponse("")
Example #26
0
def validate_rationale(req):
    try:
        data = json.loads(req.body)
    except ValueError:
        return response_400(
            req,
            msg=_("Wrong data type was sent."),
            logger_msg=("The sent data wasn't in a valid JSON format."),
            log=logger.warning,
        )
    try:
        rationale = data["rationale"]
        quality_pk = data.get("quality")
    except KeyError as e:
        return response_400(
            req,
            msg=_("There are missing parameters."),
            logger_msg=("The arguments {} were missing.".format(", ".join(
                e.args))),
            log=logger.warning,
        )

    global_quality = Quality.objects.get(quality_type__type="global",
                                         quality_use_type__type="validation")

    global_quality_, global_evaluation = global_quality.evaluate(rationale)

    failed = [
        {
            "name": c["full_name"],
            "description": c["description"]
        } for c in global_evaluation
        if c["quality"]["quality"] < c["quality"]["threshold"] or
        (c["quality"]["quality"] < 1 and c["versions"][c["version"] -
                                                       1]["binary_threshold"])
    ]
    if failed:
        RejectedAnswer.add(global_quality, rationale, global_evaluation)

    if quality_pk is not None:
        try:
            quality = Quality.objects.get(pk=quality_pk)
            quality_, evaluation = quality.evaluate(rationale)
            failed = failed + [{
                "name": c["full_name"],
                "description": c["description"]
            } for c in evaluation if (
                c["quality"]["quality"] < c["quality"]["threshold"] or
                (c["quality"]["quality"] < 1
                 and c["versions"][c["version"] - 1]["binary_threshold"])
            ) and c["full_name"] not in list(map(itemgetter("name"), failed))]
            if failed:
                RejectedAnswer.add(quality, rationale, evaluation)
        except Quality.DoesNotExist:
            return response_400(
                req,
                msg=_("Some of the parameters were wrong."),
                logger_msg=(
                    "There isn't any quality with key {}.".format(quality_pk)),
                log=logger.warning,
            )

    failed = {
        "error_msg":
        ugettext(
            "That does not seem like a clear explanation of your reasoning:"),
        "failed":
        failed,
    }
    return JsonResponse(failed)
Example #27
0
    def wrapper(req, *args, **kwargs):
        group_hash = kwargs.get("group_hash", None)
        assignment_hash = kwargs.get("assignment_hash", None)
        return_assignment = assignment_hash is not None

        if group_hash is None and assignment_hash is None:
            return response_403(
                req,
                msg=_("You don't have access to this resource."),
                logger_msg=(
                    "Access to {} without a group or assignment hash.".format(
                        req.path)),
                log=logger.warning,
            )

        try:
            teacher = Teacher.objects.get(user=req.user)
        except Teacher.DoesNotExist:
            return response_403(
                req,
                msg=_("You don't have access to this resource."),
                logger_msg=("Access to {} with a non teacher user.".format(
                    req.path)),
                log=logger.warning,
            )

        if assignment_hash is not None:
            assignment = StudentGroupAssignment.get(assignment_hash)
            if assignment is None:
                return response_400(
                    req,
                    msg=_('There is no assignment with hash "{}".'.format(
                        assignment_hash)),
                    logger_msg=(
                        "Access to {} with a invalid assignment hash.".format(
                            req.path)),
                    log=logger.warning,
                )
            group = assignment.group
        else:
            group = StudentGroup.get(group_hash)
            if group is None:
                return response_400(
                    req,
                    msg=_('There is no group with hash "{}".'.format(
                        group_hash)),
                    logger_msg=(
                        "Access to {} with a invalid group hash.".format(
                            req.path)),
                    log=logger.warning,
                )

        if teacher not in group.teacher.all():
            return response_403(
                req,
                msg=_("You don't have access to this resource. You must be "
                      "registered as a teacher for the group {}.".format(
                          group.name)),
                logger_msg=(
                    "Invalid access to group {} from teacher {}.".format(
                        group.pk, teacher.pk)),
                log=logger.warning,
            )

        if return_assignment:
            return fct(req,
                       *args,
                       teacher=teacher,
                       group=group,
                       assignment=assignment,
                       **kwargs)
        else:
            return fct(req, *args, teacher=teacher, group=group, **kwargs)
Example #28
0
def verify_assignment(req, type_, assignment_pk):
    """
    Verifies if the assignment exists and the user is allowed to change the
    assignment, returning it if that's the case and an error response if not.

    Parameters
    ----------
    req : HttpRequest
        Request
    type_ : str
        Which use type it the quality for
    assignment_pk : int
        Primary key for the assignment

    Returns
    -------
    Either
        Quality
            Quality corresponding to the assignment
        HttpResponse
            400 or 403 error response
    """
    try:
        assignment = StudentGroupAssignment.objects.get(pk=assignment_pk)
    except StudentGroupAssignment.DoesNotExist:
        return response_400(
            req,
            msg=_("Some parameters are wrong"),
            logger_msg=(
                "An access to {} was tried with the wrong ".format(req.path) +
                "assignment primary key {}.".format(assignment_pk)),
            log=logger.warning,
        )

    try:
        teacher = Teacher.objects.get(user=req.user)
    except Teacher.DoesNotExist:
        return response_403(
            req,
            msg=_("You don't have access to this resource."),
            logger_msg=("Access to {} from user {}.".format(
                req.path, req.user.pk)),
            log=logger.warning,
        )

    if not assignment.group.teacher.filter(pk=teacher.pk).exists():
        return response_403(
            req,
            msg=_("You don't have access to this resource."),
            logger_msg=("Access to {} from user {}.".format(
                req.path, req.user.pk)),
            log=logger.warning,
        )

    if assignment.quality is None:
        quality_type = QualityType.objects.get(type="studentgroupassignment")
        try:
            quality_use_type = QualityUseType.objects.get(type=type_)
        except QualityUseType.DoesNotExist:
            return response_400(
                req,
                msg=_("Some parameters are wrong"),
                logger_msg=("An access to {} was tried with the wrong ".format(
                    req.path) + "quality use type{}.".format(type_)),
                log=logger.warning,
            )

        assignment.quality = Quality.objects.create(
            quality_type=quality_type, quality_use_type=quality_use_type)
        assignment.save()

    return assignment.quality
Example #29
0
def index(req):
    """
    Returns the main page where it's possible to edit the quality.
    Possible query arguments are:
        assignment : int
            Primary key for a StudentGroupAssignment. If no Quality is
            associated with it, will be created
        next : str
            Page to return to once the edition is done. If not given, will go
            to /welcome
    If no query string is given, an error will be returned

    Returns
    -------
    HttpResponse
        Either a TemplateResponse for edition or an error response
    """
    try:
        type_ = req.GET["type"]
    except MultiValueDictKeyError:
        return response_400(
            req,
            msg=_("Some parameters are missing"),
            logger_msg=(
                "An access to {} was tried without a ".format(req.path) +
                "primary key in the query string indicating what the "
                "quality is for."),
            log=logger.error,
        )

    question_pk = req.GET.get("question")
    assignment_pk = req.GET.get("assignment")
    group_pk = req.GET.get("group")
    for_teacher = req.GET.get("teacher")
    next_ = req.GET.get("next")

    if question_pk is not None:
        quality = verify_question(req, type_, question_pk)
    elif assignment_pk is not None:
        quality = verify_assignment(req, type_, assignment_pk)
    elif group_pk is not None:
        quality = verify_group(req, type_, group_pk)
    elif for_teacher is not None:
        quality = verify_teacher(req, type_)
    else:
        return response_400(
            req,
            msg=_("Some parameters are missing"),
            logger_msg=(
                "An access to {} was tried without a ".format(req.path) +
                "primary key in the query string indicating what the "
                "quality is for."),
            log=logger.error,
        )

    if isinstance(quality, HttpResponse):
        return quality

    data = {
        "quality": dict(quality),
        "next": next_,
        "available": quality.available,
        "criterions":
        [dict(criterion) for criterion in quality.criterions.all()],
        "urls": {
            "add_criterion": reverse("quality:add-criterion"),
            "update_criterion": reverse("quality:update-criterion"),
            "remove_criterion": reverse("quality:remove-criterion"),
        },
    }

    return render(
        req,
        "quality/edit/index.html",
        {"data": json.dumps(data, cls=LazyEncoder)},
    )
Example #30
0
def update_criterion(req):
    """
    Mofieds the criterion for the quality. The request must have parameters:
        quality : int
            Primary key of the quality
        criterion : str
            Name of the criterion
        field : str
            Name of the field to update
        value : Any
            New value for the field

    Returns
    -------
    HttpResponse
        Either a JsonResponse with the criterion data or an error response
    """
    try:
        data = json.loads(req.body)
    except ValueError:
        return response_400(
            req,
            msg=_("Wrong data type was sent."),
            logger_msg=("The sent data wasn't in a valid JSON format."),
            log=logger.warning,
        )
    try:
        quality_pk = data["quality"]
        criterion_name = data["criterion"]
        field = data["field"]
        value = data["value"]
    except KeyError as e:
        return response_400(
            req,
            msg=_("There are missing parameters."),
            logger_msg=("The arguments {} were missing.".format(", ".join(
                e.args))),
            log=logger.warning,
        )

    try:
        quality = Quality.objects.get(pk=quality_pk)
    except Quality.DoesNotExist:
        return response_400(
            req,
            msg=_("Some of the parameters were wrong."),
            logger_msg=(
                "There isn't any quality with key {}.".format(quality_pk)),
            log=logger.warning,
        )

    try:
        criterion, old_value, value = quality.update_criterion(
            criterion_name, field, value)
    except (AttributeError, KeyError, UsesCriterion.DoesNotExist) as e:
        return response_400(
            req,
            msg=_("There was an error updating the criterion."),
            logger_msg=str(e),
            log=logger.warning,
        )

    logger.info(
        "Field %s for criterion %s in quality %d updated from %s to %s.",
        field,
        criterion_name,
        quality_pk,
        old_value,
        value,
    )

    return JsonResponse(dict(criterion))