From 17432b4c818a48b5824f91f7ca7798963243768b Mon Sep 17 00:00:00 2001 From: zemal Date: Thu, 20 Jul 2017 15:52:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0contest=20access=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- account/decorators.py | 7 +++++-- account/urls/user.py | 2 +- account/views/user.py | 14 +++++++++----- contest/tests.py | 25 +++++++++++++++++++++++++ contest/urls/oj.py | 3 ++- contest/views/oj.py | 20 +++++++++++++++++--- problem/views/oj.py | 2 +- 7 files changed, 60 insertions(+), 13 deletions(-) diff --git a/account/decorators.py b/account/decorators.py index 5497565a..1697a50d 100644 --- a/account/decorators.py +++ b/account/decorators.py @@ -4,7 +4,7 @@ from utils.api import JSONResponse from .models import ProblemPermission -from contest.models import Contest, ContestType +from contest.models import Contest, ContestType, ContestStatus class BasePermissionDecorator(object): @@ -80,12 +80,15 @@ def check_contest_permission(func): except Contest.DoesNotExist: return self.error("Contest %s doesn't exist" % contest_id) + if self.contest.status == ContestStatus.CONTEST_NOT_START and user != self.contest.created_by: + return self.error("Contest has not started yet.") + if self.contest.contest_type == ContestType.PASSWORD_PROTECTED_CONTEST: # Anonymous if not user.is_authenticated(): return self.error("Please login in first.") # creator - if request.user == self.contest.created_by: + if user == self.contest.created_by: return func(*args, **kwargs) # password error if ("contests" not in request.session) or (self.contest.id not in request.session["contests"]): diff --git a/account/urls/user.py b/account/urls/user.py index 8ca0adf1..47a601b7 100644 --- a/account/urls/user.py +++ b/account/urls/user.py @@ -4,7 +4,7 @@ from ..views.user import (SSOAPI, AvatarUploadAPI, TwoFactorAuthAPI, UserNameAPI, UserProfileAPI) urlpatterns = [ - url(r"^username/?$", UserNameAPI.as_view(), name="user_name_api"), + # url(r"^username/?$", UserNameAPI.as_view(), name="user_name_api"), url(r"^profile/?$", UserProfileAPI.as_view(), name="user_profile_api"), url(r"^avatar/upload/?$", AvatarUploadAPI.as_view(), name="avatar_upload_api"), url(r"^sso/?$", SSOAPI.as_view(), name="sso_api"), diff --git a/account/views/user.py b/account/views/user.py index fa97a806..9bbbf03f 100644 --- a/account/views/user.py +++ b/account/views/user.py @@ -39,15 +39,19 @@ class UserNameAPI(APIView): class UserProfileAPI(APIView): - @login_required + """ + 判断是否登录, 若登录返回用户信息 + """ + @method_decorator(ensure_csrf_cookie) def get(self, request, **kwargs): - """ - Return user info according username or user_id - """ + user = request.user + if not user.is_authenticated(): + return self.success(0) + username = request.GET.get("username") try: if username: - user = User.objects.get(username=username) + user = User.objects.get(username=username, is_disabled=False) else: user = request.user except User.DoesNotExist: diff --git a/contest/tests.py b/contest/tests.py index 7d94afeb..583035cf 100644 --- a/contest/tests.py +++ b/contest/tests.py @@ -84,6 +84,31 @@ class ContestAPITest(APITestCase): resp = self.client.post(url, {"contest_id": contest_id, "password": DEFAULT_CONTEST_DATA["password"]}) self.assertSuccess(resp) + def test_contest_access(self): + contest_id = self.create_contest().data["data"]["id"] + self.create_user("test", "test123") + url = self.reverse("contest_access_api") + resp = self.client.get(url + "?contest_id=" + str(contest_id)) + self.assertFalse(resp.data["data"]["Access"]) + + password_url = self.reverse("contest_password_api") + resp = self.client.post(password_url, {"contest_id": contest_id, "password": DEFAULT_CONTEST_DATA["password"]}) + self.assertSuccess(resp) + resp = self.client.get(url + "?contest_id=" + str(contest_id)) + self.assertSuccess(resp) + + # def test_get_not_started_contest(self): + # contest_id = self.create_contest().data["data"]["id"] + # resp = self.client.get(self.url + "?id=" + str(contest_id)) + # self.assertSuccess(resp) + # + # self.create_user("test", "1234") + # url = self.reverse("contest_password_api") + # resp = self.client.post(url, {"contest_id": contest_id, "password": DEFAULT_CONTEST_DATA["password"]}) + # self.assertSuccess(resp) + # resp = self.client.get(self.url + "?id=" + str(contest_id)) + # self.assertFailed(resp) + class ContestAnnouncementAPITest(APITestCase): def setUp(self): diff --git a/contest/urls/oj.py b/contest/urls/oj.py index eccb1f5a..42fbdf20 100644 --- a/contest/urls/oj.py +++ b/contest/urls/oj.py @@ -1,11 +1,12 @@ from django.conf.urls import url from ..views.oj import ContestAnnouncementListAPI, ContestAPI -from ..views.oj import ContestPasswordVerifyAPI +from ..views.oj import ContestPasswordVerifyAPI, ContestAccessAPI urlpatterns = [ url(r"^contest/?$", ContestAPI.as_view(), name="contest_api"), url(r"^contest/password/?$", ContestPasswordVerifyAPI.as_view(), name="contest_password_api"), url(r"^contest/announcement/?$", ContestAnnouncementListAPI.as_view(), name="contest_announcement_api"), + url(r"^contest/access/?$", ContestAccessAPI.as_view(), name="contest_access_api"), ] diff --git a/contest/views/oj.py b/contest/views/oj.py index 08daa3e2..74653f05 100644 --- a/contest/views/oj.py +++ b/contest/views/oj.py @@ -1,7 +1,7 @@ from utils.api import APIView, validate_serializer from account.decorators import login_required -from ..models import ContestAnnouncement, Contest +from ..models import ContestAnnouncement, Contest, ContestStatus from ..serializers import ContestAnnouncementSerializer from ..serializers import ContestSerializer, ContestPasswordVerifySerializer @@ -20,13 +20,13 @@ class ContestAnnouncementListAPI(APIView): class ContestAPI(APIView): def get(self, request): - contest_id = request.GET.get("contest_id") + contest_id = request.GET.get("id") if contest_id: try: contest = Contest.objects.get(id=contest_id, visible=True) - return self.success(ContestSerializer(contest).data) except Contest.DoesNotExist: return self.error("Contest doesn't exist.") + return self.success(ContestSerializer(contest).data) contests = Contest.objects.filter(visible=True) keyword = request.GET.get("keyword") @@ -54,3 +54,17 @@ class ContestPasswordVerifyAPI(APIView): # https://docs.djangoproject.com/en/dev/topics/http/sessions/#when-sessions-are-saved request.session.modified = True return self.success(True) + + +class ContestAccessAPI(APIView): + @login_required + def get(self, request): + contest_id = request.GET.get("contest_id") + if not contest_id: + return self.error("Parameter contest_id not exist.") + if "contests" not in request.session: + request.session["contests"] = [] + if int(contest_id) in request.session["contests"]: + return self.success({"Access": True}) + else: + return self.success({"Access": False}) diff --git a/problem/views/oj.py b/problem/views/oj.py index 8565bec8..edc1c1be 100644 --- a/problem/views/oj.py +++ b/problem/views/oj.py @@ -14,7 +14,7 @@ class ProblemTagAPI(APIView): class ProblemAPI(APIView): def get(self, request): # 问题详情页 - problem_id = request.GET.get("id") + problem_id = request.GET.get("problem_id") if problem_id: try: problem = Problem.objects.get(_id=problem_id, visible=True)