From a2332b78cdc5876ed816e80c2a9261b90f2e9c8c Mon Sep 17 00:00:00 2001 From: virusdefender Date: Sat, 30 Jun 2018 14:40:35 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=AF=94=E8=B5=9B=E7=9B=B8=E5=85=B3api?= =?UTF-8?q?=E9=83=BD=E9=9C=80=E8=A6=81=E7=99=BB=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/decorators.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/account/decorators.py b/account/decorators.py index 92f29081..7d896571 100644 --- a/account/decorators.py +++ b/account/decorators.py @@ -79,14 +79,15 @@ def check_contest_permission(check_type="details"): except Contest.DoesNotExist: return self.error("Contest %s doesn't exist" % contest_id) + # Anonymous + if not user.is_authenticated(): + return self.error("Please login first.") + # creator or owner - if user.is_authenticated() and user.is_contest_admin(self.contest): + if user.is_contest_admin(self.contest): return func(*args, **kwargs) if self.contest.contest_type == ContestType.PASSWORD_PROTECTED_CONTEST: - # Anonymous - if not user.is_authenticated(): - return self.error("Please login first.") # password error if self.contest.id not in request.session.get("accessible_contests", []): return self.error("Password is required.") From 4d3a4d1c6eddc22b781ce4de9be3a8f44a1a2769 Mon Sep 17 00:00:00 2001 From: virusdefender Date: Sat, 30 Jun 2018 14:41:00 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E7=B3=BB?= =?UTF-8?q?=E5=88=97=E8=B6=85=E7=BA=A7=E7=AE=A1=E7=90=86=E5=91=98=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E6=93=8D=E4=BD=9C=E5=85=B6=E4=BB=96=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=AF=94=E8=B5=9B=E5=92=8C=E9=A2=98=E7=9B=AE=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/decorators.py | 2 ++ problem/views/admin.py | 68 ++++++++++++++++++++++++++---------------- 2 files changed, 45 insertions(+), 25 deletions(-) diff --git a/account/decorators.py b/account/decorators.py index 7d896571..e57b3312 100644 --- a/account/decorators.py +++ b/account/decorators.py @@ -110,6 +110,8 @@ def ensure_created_by(obj, user): e = APIError(msg=f"{obj.__class__.__name__} does not exist") if not user.is_admin_role(): raise e + if user.is_super_admin(): + return if isinstance(obj, Problem): if not user.can_mgmt_all_problem() and obj.created_by != user: raise e diff --git a/problem/views/admin.py b/problem/views/admin.py index 38cc94a0..31c7f597 100644 --- a/problem/views/admin.py +++ b/problem/views/admin.py @@ -194,24 +194,6 @@ class ProblemBase(APIView): data["total_score"] = total_score data["languages"] = list(data["languages"]) - @problem_permission_required - def delete(self, request): - id = request.GET.get("id") - if not id: - return self.error("Invalid parameter, id is required") - try: - problem = Problem.objects.get(id=id, contest_id__isnull=True) - except Problem.DoesNotExist: - return self.error("Problem does not exists") - ensure_created_by(problem, request.user) - if Submission.objects.filter(problem=problem).exists(): - return self.error("Can't delete the problem as it has submissions") - d = os.path.join(settings.TEST_CASE_DIR, problem.test_case_id) - if os.path.isdir(d): - shutil.rmtree(d, ignore_errors=True) - problem.delete() - return self.success() - class ProblemAPI(ProblemBase): @problem_permission_required @@ -307,6 +289,24 @@ class ProblemAPI(ProblemBase): return self.success() + @problem_permission_required + def delete(self, request): + id = request.GET.get("id") + if not id: + return self.error("Invalid parameter, id is required") + try: + problem = Problem.objects.get(id=id, contest_id__isnull=True) + except Problem.DoesNotExist: + return self.error("Problem does not exists") + ensure_created_by(problem, request.user) + if Submission.objects.filter(problem=problem).exists(): + return self.error("Can't delete the problem as it has submissions") + d = os.path.join(settings.TEST_CASE_DIR, problem.test_case_id) + if os.path.isdir(d): + shutil.rmtree(d, ignore_errors=True) + problem.delete() + return self.success() + class ContestProblemAPI(ProblemBase): @validate_serializer(CreateContestProblemSerializer) @@ -346,7 +346,6 @@ class ContestProblemAPI(ProblemBase): problem.tags.add(tag) return self.success(ProblemAdminSerializer(problem).data) - @problem_permission_required def get(self, request): problem_id = request.GET.get("id") contest_id = request.GET.get("contest_id") @@ -354,15 +353,19 @@ class ContestProblemAPI(ProblemBase): if problem_id: try: problem = Problem.objects.get(id=problem_id) - ensure_created_by(problem, user) + ensure_created_by(problem.contest, user) except Problem.DoesNotExist: return self.error("Problem does not exist") return self.success(ProblemAdminSerializer(problem).data) if not contest_id: return self.error("Contest id is required") - - problems = Problem.objects.filter(contest_id=contest_id).order_by("-create_time") + try: + contest = Contest.objects.get(id=contest_id) + ensure_created_by(contest, user) + except Contest.DoesNotExist: + return self.error("Contest does not exist") + problems = Problem.objects.filter(contest=contest).order_by("-create_time") if user.is_admin(): problems = problems.filter(contest__created_by=user) keyword = request.GET.get("keyword") @@ -371,7 +374,6 @@ class ContestProblemAPI(ProblemBase): return self.success(self.paginate_data(request, problems, ProblemAdminSerializer)) @validate_serializer(EditContestProblemSerializer) - @problem_permission_required def put(self, request): data = request.data user = request.user @@ -388,8 +390,7 @@ class ContestProblemAPI(ProblemBase): problem_id = data.pop("id") try: - problem = Problem.objects.get(id=problem_id) - ensure_created_by(problem, user) + problem = Problem.objects.get(id=problem_id, contest=contest) except Problem.DoesNotExist: return self.error("Problem does not exist") @@ -419,6 +420,23 @@ class ContestProblemAPI(ProblemBase): problem.tags.add(tag) return self.success() + def delete(self, request): + id = request.GET.get("id") + if not id: + return self.error("Invalid parameter, id is required") + try: + problem = Problem.objects.get(id=id, contest_id__isnull=False) + except Problem.DoesNotExist: + return self.error("Problem does not exists") + ensure_created_by(problem.contest, request.user) + if Submission.objects.filter(problem=problem).exists(): + return self.error("Can't delete the problem as it has submissions") + d = os.path.join(settings.TEST_CASE_DIR, problem.test_case_id) + if os.path.isdir(d): + shutil.rmtree(d, ignore_errors=True) + problem.delete() + return self.success() + class MakeContestProblemPublicAPIView(APIView): @validate_serializer(ContestProblemMakePublicSerializer)