示例#1
0
def delete_problem(user: User, problem_id: int) -> int:
    if not user.has_permission('delete:problems'):
        raise ForbiddenActionError(
            "You Don't Have Permission To Delete Problem")

    try:
        prob = Problem.objects.get(pk=problem_id)
    except Problem.DoesNotExist:
        raise NoSuchProblemError()

    if prob.disabled and not user.has_permission('read:disabledProblems'):
        raise NoSuchProblemError()

    prob.delete()
    return problem_id
示例#2
0
def get_contest_problems(user: User, contest_id: int) -> Iterable[Problem]:
    if not user.has_permission('read:problems'):
        raise ForbiddenActionError(
            "You Don't Have Permission To Read Problems")

    user_cid = user.contest.id
    if contest_id != user_cid:
        raise ForbiddenActionError(
            "You Don't Have Permission To Read Problems In This Contest")

    problems_qs = user.contest.problems
    if not user.has_permission('read:disabledProblems'):
        problems_qs = problems_qs.filter(disabled=False)

    return problems_qs.all()
示例#3
0
    def mutate(_self, _info, contest_id, email, password):
        try:
            contest = Contest.objects.get(pk=contest_id)
        except Contest.DoesNotExist:
            raise Exception("No Such Contest")

        try:
            user = User.objects.filter(contest__id=contest.id,
                                       email=email).first()
            if user is None:
                raise User.DoesNotExist()
        except User.DoesNotExist:
            raise Exception("Wrong Email Or Password")

        if user.username is None:
            raise Exception("You haven't sign up yet, please sign up first")

        try:
            password_matched = bcrypt.checkpw(bytes(password, "utf-8"),
                                              bytes(user.password, "utf-8"))
        except Exception:
            raise Exception("Internal Server Error")
        if not password_matched:
            raise Exception("Wrong Email Or Password")

        token = jwt.encode({
            'id': user.id
        },
                           settings.SECRET_KEY,
                           algorithm='HS256').decode("utf-8")
        return SignIn(user=user, token=token)
示例#4
0
def update_permissions(issuer: User, user_id: int, permissions: List[str]) -> User:
    if not issuer.has_permission('update:usersPermissions'):
        raise ForbiddenActionError(
            "You Dont't Have Permission To Update User's Permissions")

    user = get_user_by_id(user_id)
    if user.contest != issuer.contest:
        raise ForbiddenActionError(
            "You Dont't Have Permission To Update This User's Permissions")

    updating_permissions: List[str] = []
    old_permissions = user.permission_codes
    new_permissions = permissions
    for perm in old_permissions:
        if perm not in new_permissions:
            updating_permissions += [perm]
    for perm in new_permissions:
        if perm not in old_permissions:
            updating_permissions += [perm]

    issuer_permissions = issuer.permission_codes
    for perm in updating_permissions:
        if perm not in issuer_permissions:
            raise ForbiddenActionError(
                "You Don't Have Permission To Update User's {}".format(perm))

    user.set_permissions(Permission.objects.filter(code__in=permissions))
    user.save()
    return user
示例#5
0
    def mutate(_self, _info, contest_id, email, reset_password_otc,
               new_password):
        try:
            contest = Contest.objects.get(pk=contest_id)
        except Contest.DoesNotExist:
            raise Exception("No Such Contest")

        try:
            user = User.objects.filter(contest__id=contest.id,
                                       email=email).first()
            if user is None:
                raise User.DoesNotExist()
        except User.DoesNotExist:
            raise Exception("No Such User")

        if user.username is None:
            raise Exception("You haven't signed up yet, please sign up first.")

        if reset_password_otc != user.reset_password_otc:
            raise Exception("Wrong Token")

        try:
            user.password = bcrypt.hashpw(bytes(new_password, "utf-8"),
                                          bcrypt.gensalt()).decode("utf-8")
            user.reset_password_otc = None
        except Exception:
            raise Exception("Internal Server Error")
        user.save()

        return user
示例#6
0
def invite_users(user: User, emails: List[str], permissions: List[str]) -> Iterable[User]:
    if not user.has_permission('invite:users'):
        raise ForbiddenActionError("You Don't Have Permission To Invite Users")

    my_permissions = user.permission_codes
    for perm in permissions:
        if perm not in my_permissions:
            raise ForbiddenActionError(
                "You Don't Have Permission To Give Permission \"{}\"".format(perm))

    current_users = User.objects.filter(
        contest__id=user.contest.id, email__in=emails).count()
    if current_users > 0:
        raise UserAlreadyInvitedError("Some User Already Invited")

    permissions = Permission.objects.filter(code__in=permissions)
    new_users: List[User] = []
    for email in emails:
        signup_otc = "".join([random.choice("0123456789")
                              for _ in range(8)])
        # use constant otc for now
        signup_otc = "00000000"
        new_user = User(email=email,
                        contest=user.contest,
                        signup_otc=signup_otc)
        new_user.full_clean()
        new_user.save()
        new_user.permissions.add(*permissions)
        new_users += [new_user]
    return new_users
示例#7
0
def get_problem_by_id(user: User, problem_id: int) -> Problem:
    if not user.has_permission('read:problems'):
        raise ForbiddenActionError(
            "You Don't Have Permission To Read Problems")

    try:
        problem = Problem.objects.get(pk=problem_id)
    except Problem.DoesNotExist:
        raise NoSuchProblemError()

    # check problem visibility
    user_cid: User = user.contest.id
    problem_cid: int = problem.contest.id
    in_same_contest: bool = problem_cid == user_cid
    can_read: bool = not problem.disabled or user.has_permission(
        'read:disabledProblems')
    if not in_same_contest or not can_read:
        raise NoSuchProblemError()

    return problem
示例#8
0
    def mutate(_self, _info, contest, email):
        if ('start_time' not in contest) and ('finish_time' not in contest):
            contest['start_time'] = datetime.datetime.now() + \
                datetime.timedelta(days=10)
            contest['finish_time'] = contest['start_time'] + \
                datetime.timedelta(hours=5)
        if 'start_time' not in contest:
            contest['start_time'] = contest['finish_time'] - \
                datetime.timedelta(hours=5)
        if 'finish_time' not in contest:
            contest['start_time'] = contest['start_time'] + \
                datetime.timedelta(hours=5)

        new_contest = Contest(**contest)
        new_contest.full_clean()
        new_contest.save()
        new_contest.permitted_languages.add(*Language.objects.all())

        signup_otc = "".join([random.choice("0123456789") for _ in range(8)])
        new_user = User(email=email,
                        contest=new_contest,
                        signup_otc=signup_otc)
        new_user.full_clean()
        new_user.save()
        new_user.permissions.add(*Permission.objects.all())

        return CreateContest(contest=new_contest, admin=new_user)
示例#9
0
    def mutate(root, info, emails, permissions):
        user = info.context.user

        my_permissions = list(
            map(lambda perm: perm.code, user.permissions.all()))
        if 'invite:users' not in my_permissions:
            raise ValueError("You Don't Have Permission To Invite Users")

        for perm in permissions:
            if perm not in my_permissions:
                raise ValueError(
                    "You Don't Have Permission To Give Other User Permission \"{}\""
                    .format(perm))

        current_users = User.objects.filter(contest__id=user.contest.id,
                                            email__in=emails).count()
        if current_users > 0:
            raise ValueError("Some User Already Invited")

        permissions = Permission.objects.filter(code__in=permissions)
        new_users = []
        for email in emails:
            signup_otc = "".join(
                [random.choice("0123456789") for _ in range(8)])
            new_user = User(email=email,
                            contest=user.contest,
                            signup_otc=signup_otc)
            new_user.full_clean()
            new_user.save()
            new_user.permissions.add(*permissions)
            new_users += [new_user]
        return new_users
示例#10
0
def get_submission_by_id(user: User, submission_id: int) -> Submission:
    try:
        submission = Submission.objects.get(pk=submission_id)
    except Submission.DoesNotExist:
        raise NoSuchSubmissionError()

    if submission.contest.id != user.contest.id:
        raise NoSuchSubmissionError()

    if not user.has_permission(
            'read:submissions') and submission.issuer.id != user.id:
        raise NoSuchSubmissionError()

    return submission
示例#11
0
def get_contest_submissions(user: User,
                            contest_id: int) -> Iterable[Submission]:
    my_contest = user.contest
    target_contest = get_contest_by_id(contest_id)
    if my_contest.id != target_contest.id:
        raise ForbiddenActionError(
            "You Don't Have Permission To Read Submission From This Contest")

    submissions_qs = Submission.objects.filter(problem__contest__id=contest_id)
    if not user.has_permission('read:submissions'):
        submissions_qs = submissions_qs.filter(issuer__id=user.id)
    submissions_qs = submissions_qs.order_by('id')

    return submissions_qs.all()
示例#12
0
def create_problem(user: User,
                   short_id: str,
                   name: str,
                   statement: str,
                   disabled: bool,
                   time_limit: int,
                   tolerance: float,
                   memory_limit: int,
                   output_limit: int,
                   tcgen_language_id: Optional[int],
                   tcgen_source_code: Optional[File],
                   solution_language_id: Optional[int],
                   solution_source_code: Optional[File],
                   checker_language_id: Optional[int],
                   checker_source_code: Optional[File]) -> Problem:
    tcgen_language, tcgen_source, \
    solution_language, solution_source, \
    checker_language, checker_source = check_files(user,
                                                   tcgen_language_id,
                                                   tcgen_source_code,
                                                   solution_language_id,
                                                   solution_source_code,
                                                   checker_language_id,
                                                   checker_source_code)

    if not user.has_permission('create:problems'):
        raise ForbiddenActionError(
            "You Don't Have Permission To Create Problem")

    last_order = Problem.objects.filter(
        contest__id=user.contest.id).aggregate(Max('order'))
    new_prob = Problem(short_id=short_id,
                       name=name,
                       statement=statement,
                       disabled=disabled,
                       time_limit=time_limit,
                       tolerance=tolerance,
                       memory_limit=memory_limit,
                       output_limit=output_limit,
                       order=last_order['order__max'] + 1,
                       contest=user.contest,
                       tcgen_language=tcgen_language,
                       tcgen_source=tcgen_source,
                       solution_language=solution_language,
                       solution_source=solution_source,
                       checker_language=checker_language,
                       checker_source=checker_source)
    new_prob.save()
    return new_prob
示例#13
0
def create_contest(email: str,
                   name: str,
                   short_id: str,
                   short_description: str,
                   description: str = 'Just another competitive programming competition',
                   start_time: Optional[datetime.datetime] = None,
                   finish_time: Optional[datetime.datetime] = None,
                   freezed: bool = False,
                   grading_size: int = 1) -> Tuple[Contest, User]:

    if start_time is None and finish_time is None:
        start_time = datetime.datetime.now() + datetime.timedelta(days=10)
        finish_time = start_time + datetime.timedelta(hours=5)
    elif finish_time is not None:
        start_time = finish_time - datetime.timedelta(hours=5)
    elif start_time is not None:
        finish_time = start_time + datetime.timedelta(hours=5)

    if Contest.objects.filter(short_id=short_id).count() > 0:
        raise ContestError('Contest ID Already Taken')

    new_contest = Contest(name=name,
                          short_id=short_id,
                          short_description=short_description,
                          description=description,
                          start_time=start_time,
                          finish_time=finish_time,
                          freezed=freezed,
                          grading_size=grading_size)

    new_contest.full_clean()
    new_contest.save()
    languages = get_all_languages()
    new_contest.permitted_languages.add(*languages)

    signup_otc = "".join([random.choice("0123456789") for _ in range(8)])
    # use constant otc for now
    signup_otc = "00000000"
    new_user = User(email=email,
                    contest=new_contest,
                    signup_otc=signup_otc)
    new_user.full_clean()
    new_user.save()
    permissions = get_all_permissions()
    new_user.permissions.add(*permissions)

    return new_contest, new_user
示例#14
0
    def mutate(_self, _info, contest_id, email, user, signup_code):
        try:
            contest = Contest.objects.get(pk=contest_id)
        except Contest.DoesNotExist:
            raise Exception("No Such Contest")

        try:
            new_user = User.objects.filter(contest__id=contest.id,
                                           email=email).first()
            if new_user is None:
                raise User.DoesNotExist()
        except User.DoesNotExist:
            raise Exception("No Such User")

        if new_user.username is not None:
            raise Exception("User Already Signed Up")

        if new_user.signup_otc != signup_code:
            raise Exception("Wrong Token")

        new_user.name = user.name
        new_user.username = user.username
        try:
            new_user.password = bcrypt.hashpw(bytes(user.password, "utf-8"),
                                              bcrypt.gensalt()).decode("utf-8")
        except Exception:
            raise Exception("Internal Server Error")
        new_user.signup_otc = None
        new_user.reset_password_otc = None
        new_user.full_clean()
        new_user.save()

        token = jwt.encode({
            'id': new_user.id
        },
                           settings.SECRET_KEY,
                           algorithm='HS256').decode("utf-8")
        return SignUp(user=new_user, token=token)
示例#15
0
    def mutate(_self, _info, contest_id, email):
        try:
            contest = Contest.objects.get(pk=contest_id)
        except Contest.DoesNotExist:
            raise Exception("No Such Contest")

        try:
            user = User.objects.filter(contest__id=contest.id,
                                       email=email).first()
            if user is None:
                raise User.DoesNotExist()
        except User.DoesNotExist:
            raise Exception("No Such User")

        if user.username is None:
            raise Exception("You haven't signed up yet, please sign up first.")

        if user.reset_password_otc is None:
            user.reset_password_otc = "".join(
                random.choice("0987654321") for _ in range(8))
            user.save()

        return user
示例#16
0
def update_contest(user: User,
                   name: Optional[str],
                   short_description: Optional[str],
                   description: Optional[str],
                   start_time: Optional[datetime.datetime],
                   finish_time: Optional[datetime.datetime],
                   freezed: Optional[bool],
                   grading_size: Optional[int],
                   permitted_languages: Optional[Iterable[str]]) -> Contest:
    if not user.has_permission('update:contest'):
        raise ForbiddenActionError(
            "You Don't Have Permission To Update Contest")

    updating_contest = user.contest
    if name is not None:
        updating_contest.name = name
    if short_description is not None:
        updating_contest.short_description = short_description
    if description is not None:
        updating_contest.description = description
    if start_time is not None:
        updating_contest.start_time = start_time
    if finish_time is not None:
        updating_contest.finish_time = finish_time
    if freezed is not None:
        updating_contest.freezed = freezed
    if grading_size is not None:
        updating_contest.grading_size = grading_size
    updating_contest.save()

    if permitted_languages is not None:
        langs = Language.objects.filter(id__in=permitted_languages)
        updating_contest.permitted_languages.set(langs)
        updating_contest.save()

    return updating_contest
示例#17
0
def update_problem(user: User,
                   problem_id: int,
                   short_id: Optional[str],
                   name: Optional[str],
                   statement: Optional[str],
                   disabled: Optional[bool],
                   time_limit: Optional[int],
                   tolerance: Optional[float],
                   memory_limit: Optional[int],
                   output_limit: Optional[int],
                   tcgen_language_id: Optional[int],
                   tcgen_source_code: Optional[File],
                   solution_language_id: Optional[int],
                   solution_source_code: Optional[File],
                   checker_language_id: Optional[int],
                   checker_source_code: Optional[File]) -> Problem:
    tcgen_language, tcgen_source, \
    solution_language, solution_source, \
    checker_language, checker_source = check_files(user,
                                                   tcgen_language_id,
                                                   tcgen_source_code,
                                                   solution_language_id,
                                                   solution_source_code,
                                                   checker_language_id,
                                                   checker_source_code)

    if not user.has_permission('update:problems'):
        raise ForbiddenActionError(
            "You Don't Have Permission To Update Problem")

    try:
        prob = Problem.objects.get(pk=problem_id)
    except Problem.DoesNotExist:
        raise NoSuchProblemError()

    permissions = map(lambda user: user.code, user.permissions.all())
    if prob.disabled and 'read:disabledProblems' not in permissions:
        raise ValueError("No Such Problem")

    if short_id is not None:
        prob.short_id = short_id
    if name is not None:
        prob.name = name
    if statement is not None:
        prob.statement = statement
    if disabled is not None:
        prob.disabled = disabled
    if time_limit is not None:
        prob.time_limit = time_limit
    if tolerance is not None:
        prob.tolerance = tolerance
    if memory_limit is not None:
        prob.memory_limit = memory_limit
    if output_limit is not None:
        prob.output_limit = output_limit
    if tcgen_language is not None:
        prob.tcgen_language = tcgen_language
    if tcgen_source is not None:
        prob.tcgen_source = tcgen_source
    if solution_language is not None:
        prob.solution_language = solution_language
    if solution_source is not None:
        prob.solution_source = solution_source
    if checker_language is not None:
        prob.checker_language = checker_language
    if checker_source is not None:
        prob.checker_source = checker_source

    prob.save()
    return prob