Exemple #1
0
    def get(self, contest_id: int, problem_id: int, run_id: int):
        contest_visibility = db.session.query(Contest.protocol_visibility) \
            .filter_by(id=contest_id).join(Statement) \
            .join(StatementProblem) \
            .filter(StatementProblem.problem_id == problem_id) \
            .one_or_none()

        if contest_visibility is None:
            raise BadRequest('Неправильный ID протокола или задачи')

        contest_visibility = contest_visibility and contest_visibility[0]

        if contest_visibility is ContestProtocolVisibility.INVISIBLE:
            raise NotFound('Просмотр протокола для этой посылки недоступен')

        context, status = internal_rmatics.get_full_run_protocol(run_id, current_user.id)

        if status > 299:
            return jsonify(context, status_code=status)

        # TODO: NFRMTCS-192: нужен контекст,
        # TODO: чтобы нельзя было смотреть любой протокол, найдя открытый воркшоп
        protocol = self._remove_fields_from_full_protocol(context)

        if contest_visibility is ContestProtocolVisibility.FIRST_BAD_TEST:
            protocol = self._remove_all_after_bad_test(protocol)

        return jsonify(protocol, status_code=status)
Exemple #2
0
    def get(self, course_module_id):
        course_module = db.session.query(CourseModule) \
            .filter(CourseModule.id == course_module_id) \
            .filter(CourseModule.visible == 1) \
            .one_or_none()

        if course_module is None:
            raise NotFound(f'Cannot find course module id #{course_module_id}')

        contest = course_module.instance

        if not isinstance(contest, Statement):
            raise BadRequest('This resource is not implemented yet')

        problems_statement_problems = db.session.query(Problem, StatementProblem) \
            .join(StatementProblem, StatementProblem.problem_id == Problem.id) \
            .filter(StatementProblem.statement_id == contest.id) \
            .filter(StatementProblem.hidden == 0) \
            .options(Load(Problem).load_only('id', 'name')) \
            .options(Load(StatementProblem).load_only('rank'))

        problems = []
        # Yes it is ugly but I think its better than rewrite query
        for problem, sp in problems_statement_problems.all():
            problem.rank = sp.rank
            problems.append(problem)

        contest.problems = problems

        contest_schema = ContestSchema()

        response = contest_schema.dump(contest)

        return jsonify(response.data)
    def get(self, workshop_id):
        # Get first as only one WorkshopConnection may exist due to unique constraints
        workshop_connection: WorkshopConnection = db.session.query(WorkshopConnection) \
            .filter(WorkshopConnection.workshop_id == workshop_id,
                    WorkshopConnection.user_id == current_user.id,
                    # Allow view workshops only for user with ACCEPTED (students)
                    # or PROMOTED (teacher or workshop owners) status
                    WorkshopConnection.status.in_((WorkshopConnectionStatus.ACCEPTED,
                                                   WorkshopConnectionStatus.PROMOTED)),
                    # Workshop should be active and visible
                    WorkShop.status == WorkshopStatus.ONGOING) \
            .options(joinedload(WorkshopConnection.workshop)
                     .joinedload(WorkShop.contests)
                     .joinedload(Contest.statement)) \
            .one_or_none()

        if workshop_connection is None:
            raise NotFound(f'Сбор с id #{workshop_id} не найден')

        workshop_serializer: WorkshopSchema = WorkshopSchema(exclude=[
            'contests.statement.problems',
        ])
        response: MarshalResult = workshop_serializer.dump(workshop_connection.workshop)

        return jsonify(response.data)
    def post(self):
        args = parser.parse(self.post_args, request)

        # prevent equal-None filter query
        email, username = args.get('email'), args.get('username')
        if not any((email, username)):
            raise BadRequest()

        user_q = db.session.query(User)
        if email is not None:
            user_q = user_q.filter(User.email == email)
        elif username is not None:
            user_q = user_q.filter(User.username == username)
        user = user_q.one_or_none()

        # if user not found or user has no valid email
        if user is None or user.email is None or user.email == '':
            raise BadRequest(
                'Запрос не выполнен. Или пользователь с такими  '
                'данными не найден, или у найденого пользователя нет email')

        payload = {'user_id': user.id}
        token = tokenizer.pack(payload)

        text = f"Ссылка для сброса пароля: {current_app.config.get('APP_URL')}/auth/change-password?token={token}"
        msg = Message('Сброс пароля', to=user.email, text=text)
        try:
            gmail.send(msg)
        except Exception as e:  # TODO: handle smtplib errors
            current_app.logger.exception(
                'Unable to send reset password message to', user.email)

        return jsonify({})
    def get(self, workshop_id):
        args = parser.parse(self.get_args, request, error_status_code=400)

        if not self._ensure_permissions(workshop_id):
            raise NotFound(
                f'Результаты сбора #{workshop_id} не найдены или у пользователя нет приглашения на него'
            )

        monitor: WorkshopMonitor = db.session.query(WorkshopMonitor) \
            .filter(WorkshopMonitor.workshop_id == workshop_id) \
            .first_or_404()

        if not current_user.is_teacher and monitor.is_disabled_for_students():
            raise NotFound(
                f'Результаты сбора #{workshop_id} не найдены или у пользователя нет приглашения на него'
            )

        contests = self._get_contests(workshop_id)

        users = self._get_users(monitor, args.get('group_id'))
        user_ids = [user.id for user in users]

        results = []
        for contest in contests:
            raw_data = self._get_raw_data_by_contest(monitor, user_ids,
                                                     contest)
            data = self._prepare_data(monitor, contest, raw_data)
            results.append({'contest_id': contest.id, 'results': data})

        monitor_data = MonitorData(contests, users, results, monitor.type.name)

        data = monitor_schema.dump(monitor_data)

        return jsonify(data.data)
    def post(self):

        args = parser.parse(self.post_args, request)

        username, password = args['username'], args['password']

        user = db.session.query(User) \
            .filter(User.username == username) \
            .filter(User.deleted.isnot(True)) \
            .options(joinedload(User.roles)) \
            .one_or_none()

        if user is None:
            raise exc.NotFound('User with this username does not exist')

        is_password_valid = User.check_password(user.password_md5, password)
        if not is_password_valid:
            current_app.logger.warning(f'user_email={args["username"]} '
                                       f'has failed to log in')
            raise exc.Forbidden('Invalid password')

        current_app.logger.debug(f'user_email={args["username"]} has logged in')

        token = generate_refresh_token(user)
        refresh_token = RefreshToken(token=token, user_id=user.id)
        db.session.add(refresh_token)
        db.session.commit()

        user_serializer = UserAuthSerializer()
        user.refresh_token = token
        user_data = user_serializer.dump(user)

        return jsonify(user_data.data)
Exemple #7
0
    def get(self, run_id: int):
        user_id = g.user['id']
        context, status = internal_rmatics.get_full_run_protocol(
            run_id, user_id)

        protocol = self._remove_fields_from_full_protocol(context)

        return jsonify(protocol, status_code=status)
    def post(self):
        args = parser.parse(self.post_args, request)

        db.session.query(RefreshToken).filter_by(
            user_id=current_user.id, token=args.get('refresh_token')).delete()
        db.session.commit()

        current_app.logger.debug(f'user_id={current_user.id} has logged out')

        return jsonify({}, 200)
    def post(self):
        args = parser.parse(self.post_args, request)
        user = db.session.query(User). \
            filter_by(id=g.payload.get('user_id')). \
            one_or_none()

        if user:
            user.password_md5 = User.hash_password(args.get('password'))
            db.session.commit()

        return jsonify({})
Exemple #10
0
    def post(self, problem_id):
        user_id = g.user['id']
        args = parser.parse(self.post_args, request)
        file = parser.parse_files(request, 'file', 'file')

        content, status = internal_rmatics.send_submit(file,
                                                       user_id,
                                                       problem_id,
                                                       args['statement_id'],
                                                       args['lang_id'])
        return jsonify(content, status_code=status)
Exemple #11
0
    def get(self, problem_id):
        problem = db.session.query(Problem) \
            .options(joinedload(Problem.ejudge_problem)) \
            .get(problem_id)
        if problem is None:
            raise NotFound(f'Problem with id #{problem_id} is not found')

        problem_serializer = ProblemSchema()

        response = problem_serializer.dump(problem)

        return jsonify(response.data)
    def get(self, contest_id, problem_id):
        check_contest_availability(
            contest_id,
            NotFound(f'Задача с id #{problem_id} не найдена '
                     'или у вас недостаточно прав для ее просмотра'))

        args = parser.parse(self.get_args, request, error_status_code=400)

        # set current authorized user to args
        args['user_id'] = current_user.id

        content, status = internal_rmatics.get_runs_filter(
            problem_id, contest_id, args)
        return jsonify(content, status_code=status)
Exemple #13
0
    def get(self, run_id):
        """
        Returns List[Comment] for current authorized user for requested run_id
        """

        # if provided run_id not not found, return []
        comments = db.session.query(Comment) \
            .filter(Comment.py_run_id == run_id,
                    Comment.user_id == current_user.id) \
            .options(joinedload(Comment.author_user)) \
            .order_by(Comment.date.desc()) \
            .all()

        comment_schema = CommentSchema(many=True)
        response = comment_schema.dump(comments)

        return jsonify(response.data)
    def get(self, contest_id, problem_id):
        check_contest_availability(
            contest_id,
            NotFound(f'Задача с id #{problem_id} не найдена '
                     'или у вас недостаточно прав для ее просмотра'))

        problem = db.session.query(EjudgeProblem).filter_by(
            id=problem_id).one_or_none()
        if problem is None:
            raise NotFound(f'Задача с id #{problem_id} не найдена '
                           'или у вас недостаточно прав для ее просмотра')

        problem_serializer = ProblemSchema()

        response = problem_serializer.dump(problem)

        return jsonify(response.data)
    def post(self):
        args = parser.parse(self.post_args, request)
        token = args.get('refresh_token')

        user = self._validate_token(token)
        if user is None:
            current_app.logger.warning(f'Someone has sent invalid refresh token')
            raise exc.Forbidden('Refresh token has been expired')

        excludes = ('refresh_token',)
        serializer = UserAuthSerializer(exclude=excludes)
        user_data = serializer.dump(user)

        current_app.logger.debug(f'user_id={user.id} '
                                 f'user_email={user.email} token has '
                                 f'been refreshed')

        return jsonify(user_data.data)
    def post(self, contest_id, problem_id):
        cc = check_contest_availability(
            contest_id,
            NotFound(f'Задача с id #{problem_id} не найдена '
                     'или у вас недостаточно прав для ее просмотра'))
        args = parser.parse(self.post_args, request)
        check_contest_languages(
            cc.contest, args.get('lang_id'),
            Forbidden('На выбранном языке нельзя решать '
                      'задачи из этого контеста. Пожалуйста, '
                      'используйте другой язык'))
        file = request.files.get('file')
        if file is None:
            raise BadRequest('Файл решения не предоставлен')

        content, status = internal_rmatics.send_submit(file, current_user.id,
                                                       problem_id, contest_id,
                                                       args['lang_id'])
        return jsonify(content, status_code=status)
    def get(self, contest_id):
        contest: Contest = db.session.query(Contest) \
            .options(joinedload(Contest.languages)) \
            .options(joinedload(Contest.statement)) \
            .options(joinedload(Contest.workshop)) \
            .get(contest_id)

        if contest is None:
            raise NotFound(
                f'Не удалость найти модуль контеста с ID #{contest_id}')

        user_id = current_user.id
        self._check_workshop_permissions(user_id, contest.workshop)

        cc, is_created = get_or_create(ContestConnection,
                                       user_id=user_id,
                                       contest_id=contest.id)

        if not current_user.is_teacher and not contest.is_available(cc):
            raise Forbidden('Контест не найден или не открыт')

        contest.statement.problems = self._load_problems(contest.statement_id)
        if not contest.languages:
            contest.languages = db.session.query(Language).all()

        cc.contest = contest

        cc_schema = ContestConnectionSchema()

        response = cc_schema.dump(cc)

        if is_created is True:
            # Allow modify contest object without
            # saving changes
            db.session.expunge(contest)

            db.session.commit()

        return jsonify(response.data)
    def post(self, workshop_id: int):
        args = parser.parse(self.post_args, request)

        workshop = db.session.query(WorkShop) \
            .filter_by(id=workshop_id,
                       status=WorkshopStatus.ONGOING,
                       access_token=args.get('token')) \
            .one_or_none()

        if workshop is None:
            raise NotFound(f'Сбор не найден')

        wc, is_created = get_or_create(WorkshopConnection,
                                       user_id=current_user.id,
                                       workshop_id=workshop_id)

        wc_schema = WorkshopConnectionSchema()
        response = wc_schema.dump(wc)

        if is_created is True:
            db.session.commit()

        return jsonify(response.data)
Exemple #19
0
 def get(self, problem_id):
     args = parser.parse(self.get_args, request, error_status_code=400)
     content, status = internal_rmatics.get_runs_filter(problem_id, args, is_admin=False)
     return jsonify(content, status_code=status)
Exemple #20
0
    def get(self, run_id):
        user_id = g.user['id']
        context, status = internal_rmatics.get_run_source(run_id, user_id)

        return jsonify(context, status_code=status)
def jsonify_http_exception(exception: HTTPException):
    """Convert raised werkzeug.exceptons.* into JSON.

    Additional doc: http://flask.pocoo.org/snippets/83/
    """
    return jsonify(exception.description, exception.code)
def jsonify_unknown_exception(exception: Exception):
    """Convert any other exception to JSON."""
    current_app.logger.exception('Unhandled exception has been raised!')
    return jsonify(DEFAULT_MESSAGE, 500)
Exemple #23
0
 def get(self, run_id):
     context, status = internal_rmatics.get_run_source(run_id, current_user.id)
     if status == 404:
         raise NotFound('Посылка не найдена')
     return jsonify(context, status_code=status)