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
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()
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)
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
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
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
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
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)
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
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
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()
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
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
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)
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
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
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