admin submit invisible problem

This commit is contained in:
Tree Saengja 2022-03-21 11:02:49 +07:00
parent 88896772dd
commit 9560f15c4d

View File

@ -4,6 +4,7 @@ from account.decorators import login_required, check_contest_permission
from contest.models import ContestStatus, ContestRuleType from contest.models import ContestStatus, ContestRuleType
from judge.tasks import judge_task from judge.tasks import judge_task
from options.options import SysOptions from options.options import SysOptions
# from judge.dispatcher import JudgeDispatcher # from judge.dispatcher import JudgeDispatcher
from problem.models import Problem, ProblemRuleType from problem.models import Problem, ProblemRuleType
from utils.api import APIView, validate_serializer from utils.api import APIView, validate_serializer
@ -11,8 +12,11 @@ from utils.cache import cache
from utils.captcha import Captcha from utils.captcha import Captcha
from utils.throttling import TokenBucket from utils.throttling import TokenBucket
from ..models import Submission from ..models import Submission
from ..serializers import (CreateSubmissionSerializer, SubmissionModelSerializer, from ..serializers import (
ShareSubmissionSerializer) CreateSubmissionSerializer,
SubmissionModelSerializer,
ShareSubmissionSerializer,
)
from ..serializers import SubmissionSafeModelSerializer, SubmissionListSerializer from ..serializers import SubmissionSafeModelSerializer, SubmissionListSerializer
@ -22,8 +26,9 @@ class SubmissionAPI(APIView):
auth_method = getattr(request, "auth_method", "") auth_method = getattr(request, "auth_method", "")
if auth_method == "api_key": if auth_method == "api_key":
return return
user_bucket = TokenBucket(key=str(request.user.id), user_bucket = TokenBucket(
redis_conn=cache, **SysOptions.throttling["user"]) key=str(request.user.id), redis_conn=cache, **SysOptions.throttling["user"]
)
can_consume, wait = user_bucket.consume() can_consume, wait = user_bucket.consume()
if not can_consume: if not can_consume:
return "Please wait %d seconds" % (int(wait)) return "Please wait %d seconds" % (int(wait))
@ -42,7 +47,10 @@ class SubmissionAPI(APIView):
if not request.user.is_contest_admin(contest): if not request.user.is_contest_admin(contest):
user_ip = ipaddress.ip_address(request.session.get("ip")) user_ip = ipaddress.ip_address(request.session.get("ip"))
if contest.allowed_ip_ranges: if contest.allowed_ip_ranges:
if not any(user_ip in ipaddress.ip_network(cidr, strict=False) for cidr in contest.allowed_ip_ranges): if not any(
user_ip in ipaddress.ip_network(cidr, strict=False)
for cidr in contest.allowed_ip_ranges
):
return self.error("Your IP is not allowed in this contest") return self.error("Your IP is not allowed in this contest")
@validate_serializer(CreateSubmissionSerializer) @validate_serializer(CreateSubmissionSerializer)
@ -66,18 +74,29 @@ class SubmissionAPI(APIView):
return self.error(error) return self.error(error)
try: try:
problem = Problem.objects.get(id=data["problem_id"], contest_id=data.get("contest_id"), visible=True) if request.user.is_admin_role:
problem = Problem.objects.get(
id=data["problem_id"], contest_id=data.get("contest_id")
)
else:
problem = Problem.objects.get(
id=data["problem_id"],
contest_id=data.get("contest_id"),
visible=True,
)
except Problem.DoesNotExist: except Problem.DoesNotExist:
return self.error("Problem not exist") return self.error("Problem not exist")
if data["language"] not in problem.languages: if data["language"] not in problem.languages:
return self.error(f"{data['language']} is now allowed in the problem") return self.error(f"{data['language']} is now allowed in the problem")
submission = Submission.objects.create(user_id=request.user.id, submission = Submission.objects.create(
username=request.user.username, user_id=request.user.id,
language=data["language"], username=request.user.username,
code=data["code"], language=data["language"],
problem_id=problem.id, code=data["code"],
ip=request.session["ip"], problem_id=problem.id,
contest_id=data.get("contest_id")) ip=request.session["ip"],
contest_id=data.get("contest_id"),
)
# use this for debug # use this for debug
# JudgeDispatcher(submission.id, problem.id).judge() # JudgeDispatcher(submission.id, problem.id).judge()
judge_task.send(submission.id, problem.id) judge_task.send(submission.id, problem.id)
@ -92,18 +111,25 @@ class SubmissionAPI(APIView):
if not submission_id: if not submission_id:
return self.error("Parameter id doesn't exist") return self.error("Parameter id doesn't exist")
try: try:
submission = Submission.objects.select_related("problem").get(id=submission_id) submission = Submission.objects.select_related("problem").get(
id=submission_id
)
except Submission.DoesNotExist: except Submission.DoesNotExist:
return self.error("Submission doesn't exist") return self.error("Submission doesn't exist")
if not submission.check_user_permission(request.user): if not submission.check_user_permission(request.user):
return self.error("No permission for this submission") return self.error("No permission for this submission")
if submission.problem.rule_type == ProblemRuleType.OI or request.user.is_admin_role(): if (
submission.problem.rule_type == ProblemRuleType.OI
or request.user.is_admin_role()
):
submission_data = SubmissionModelSerializer(submission).data submission_data = SubmissionModelSerializer(submission).data
else: else:
submission_data = SubmissionSafeModelSerializer(submission).data submission_data = SubmissionSafeModelSerializer(submission).data
# 是否有权限取消共享 # 是否有权限取消共享
submission_data["can_unshare"] = submission.check_user_permission(request.user, check_share=False) submission_data["can_unshare"] = submission.check_user_permission(
request.user, check_share=False
)
return self.success(submission_data) return self.success(submission_data)
@validate_serializer(ShareSubmissionSerializer) @validate_serializer(ShareSubmissionSerializer)
@ -113,12 +139,17 @@ class SubmissionAPI(APIView):
share submission share submission
""" """
try: try:
submission = Submission.objects.select_related("problem").get(id=request.data["id"]) submission = Submission.objects.select_related("problem").get(
id=request.data["id"]
)
except Submission.DoesNotExist: except Submission.DoesNotExist:
return self.error("Submission doesn't exist") return self.error("Submission doesn't exist")
if not submission.check_user_permission(request.user, check_share=False): if not submission.check_user_permission(request.user, check_share=False):
return self.error("No permission to share the submission") return self.error("No permission to share the submission")
if submission.contest and submission.contest.status == ContestStatus.CONTEST_UNDERWAY: if (
submission.contest
and submission.contest.status == ContestStatus.CONTEST_UNDERWAY
):
return self.error("Can not share submission now") return self.error("Can not share submission now")
submission.shared = request.data["shared"] submission.shared = request.data["shared"]
submission.save(update_fields=["shared"]) submission.save(update_fields=["shared"])
@ -132,14 +163,18 @@ class SubmissionListAPI(APIView):
if request.GET.get("contest_id"): if request.GET.get("contest_id"):
return self.error("Parameter error") return self.error("Parameter error")
submissions = Submission.objects.filter(contest_id__isnull=True).select_related("problem__created_by") submissions = Submission.objects.filter(contest_id__isnull=True).select_related(
"problem__created_by"
)
problem_id = request.GET.get("problem_id") problem_id = request.GET.get("problem_id")
myself = request.GET.get("myself") myself = request.GET.get("myself")
result = request.GET.get("result") result = request.GET.get("result")
username = request.GET.get("username") username = request.GET.get("username")
if problem_id: if problem_id:
try: try:
problem = Problem.objects.get(_id=problem_id, contest_id__isnull=True, visible=True) problem = Problem.objects.get(
_id=problem_id, contest_id__isnull=True, visible=True
)
except Problem.DoesNotExist: except Problem.DoesNotExist:
return self.error("Problem doesn't exist") return self.error("Problem doesn't exist")
submissions = submissions.filter(problem=problem) submissions = submissions.filter(problem=problem)
@ -150,7 +185,9 @@ class SubmissionListAPI(APIView):
if result: if result:
submissions = submissions.filter(result=result) submissions = submissions.filter(result=result)
data = self.paginate_data(request, submissions) data = self.paginate_data(request, submissions)
data["results"] = SubmissionListSerializer(data["results"], many=True, user=request.user).data data["results"] = SubmissionListSerializer(
data["results"], many=True, user=request.user
).data
return self.success(data) return self.success(data)
@ -161,14 +198,18 @@ class ContestSubmissionListAPI(APIView):
return self.error("Limit is needed") return self.error("Limit is needed")
contest = self.contest contest = self.contest
submissions = Submission.objects.filter(contest_id=contest.id).select_related("problem__created_by") submissions = Submission.objects.filter(contest_id=contest.id).select_related(
"problem__created_by"
)
problem_id = request.GET.get("problem_id") problem_id = request.GET.get("problem_id")
myself = request.GET.get("myself") myself = request.GET.get("myself")
result = request.GET.get("result") result = request.GET.get("result")
username = request.GET.get("username") username = request.GET.get("username")
if problem_id: if problem_id:
try: try:
problem = Problem.objects.get(_id=problem_id, contest_id=contest.id, visible=True) problem = Problem.objects.get(
_id=problem_id, contest_id=contest.id, visible=True
)
except Problem.DoesNotExist: except Problem.DoesNotExist:
return self.error("Problem doesn't exist") return self.error("Problem doesn't exist")
submissions = submissions.filter(problem=problem) submissions = submissions.filter(problem=problem)
@ -186,11 +227,15 @@ class ContestSubmissionListAPI(APIView):
# 封榜的时候只能看到自己的提交 # 封榜的时候只能看到自己的提交
if contest.rule_type == ContestRuleType.ACM: if contest.rule_type == ContestRuleType.ACM:
if not contest.real_time_rank and not request.user.is_contest_admin(contest): if not contest.real_time_rank and not request.user.is_contest_admin(
contest
):
submissions = submissions.filter(user_id=request.user.id) submissions = submissions.filter(user_id=request.user.id)
data = self.paginate_data(request, submissions) data = self.paginate_data(request, submissions)
data["results"] = SubmissionListSerializer(data["results"], many=True, user=request.user).data data["results"] = SubmissionListSerializer(
data["results"], many=True, user=request.user
).data
return self.success(data) return self.success(data)
@ -198,6 +243,9 @@ class SubmissionExistsAPI(APIView):
def get(self, request): def get(self, request):
if not request.GET.get("problem_id"): if not request.GET.get("problem_id"):
return self.error("Parameter error, problem_id is required") return self.error("Parameter error, problem_id is required")
return self.success(request.user.is_authenticated and return self.success(
Submission.objects.filter(problem_id=request.GET["problem_id"], request.user.is_authenticated
user_id=request.user.id).exists()) and Submission.objects.filter(
problem_id=request.GET["problem_id"], user_id=request.user.id
).exists()
)