mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-09-21 00:13:18 +00:00
用户名不区分大小写;
修复更新problem时的一些问题
This commit is contained in:
parent
b86ebf0ed7
commit
70f52b6f27
@ -20,7 +20,7 @@ class UserManager(models.Manager):
|
|||||||
use_in_migrations = True
|
use_in_migrations = True
|
||||||
|
|
||||||
def get_by_natural_key(self, username):
|
def get_by_natural_key(self, username):
|
||||||
return self.get(**{self.model.USERNAME_FIELD: username})
|
return self.get(**{f"{self.model.USERNAME_FIELD}__iexact": username})
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractBaseUser):
|
class User(AbstractBaseUser):
|
||||||
|
@ -198,7 +198,7 @@ class UsernameOrEmailCheck(APIView):
|
|||||||
if data.get("username"):
|
if data.get("username"):
|
||||||
result["username"] = User.objects.filter(username=data["username"]).exists()
|
result["username"] = User.objects.filter(username=data["username"]).exists()
|
||||||
if data.get("email"):
|
if data.get("email"):
|
||||||
result["email"] = User.objects.filter(email=data["email"]).exists()
|
result["email"] = User.objects.filter(email=data["email"].lower()).exists()
|
||||||
return self.success(result)
|
return self.success(result)
|
||||||
|
|
||||||
|
|
||||||
@ -218,9 +218,9 @@ class UserRegisterAPI(APIView):
|
|||||||
return self.error("Invalid captcha")
|
return self.error("Invalid captcha")
|
||||||
if User.objects.filter(username=data["username"]).exists():
|
if User.objects.filter(username=data["username"]).exists():
|
||||||
return self.error("Username already exists")
|
return self.error("Username already exists")
|
||||||
|
data["email"] = data["email"].lower()
|
||||||
if User.objects.filter(email=data["email"]).exists():
|
if User.objects.filter(email=data["email"]).exists():
|
||||||
return self.error("Email already exists")
|
return self.error("Email already exists")
|
||||||
|
|
||||||
user = User.objects.create(username=data["username"], email=data["email"])
|
user = User.objects.create(username=data["username"], email=data["email"])
|
||||||
user.set_password(data["password"])
|
user.set_password(data["password"])
|
||||||
user.save()
|
user.save()
|
||||||
@ -240,6 +240,7 @@ class UserChangeEmailAPI(APIView):
|
|||||||
return self.error("tfa_required")
|
return self.error("tfa_required")
|
||||||
if not OtpAuth(user.tfa_token).valid_totp(data["tfa_code"]):
|
if not OtpAuth(user.tfa_token).valid_totp(data["tfa_code"]):
|
||||||
return self.error("Invalid two factor verification code")
|
return self.error("Invalid two factor verification code")
|
||||||
|
data["new_email"] = data["new_email"].lower()
|
||||||
if User.objects.filter(email=data["new_email"]).exists():
|
if User.objects.filter(email=data["new_email"]).exists():
|
||||||
return self.error("The email is owned by other account")
|
return self.error("The email is owned by other account")
|
||||||
user.email = data["new_email"]
|
user.email = data["new_email"]
|
||||||
@ -280,7 +281,7 @@ class ApplyResetPasswordAPI(APIView):
|
|||||||
if not captcha.check(data["captcha"]):
|
if not captcha.check(data["captcha"]):
|
||||||
return self.error("Invalid captcha")
|
return self.error("Invalid captcha")
|
||||||
try:
|
try:
|
||||||
user = User.objects.get(email=data["email"])
|
user = User.objects.get(email__iexact=data["email"])
|
||||||
except User.DoesNotExist:
|
except User.DoesNotExist:
|
||||||
return self.error("User does not exist")
|
return self.error("User does not exist")
|
||||||
if user.reset_password_token_expire_time and 0 < int(
|
if user.reset_password_token_expire_time and 0 < int(
|
||||||
|
@ -118,7 +118,9 @@ LOGGING = {
|
|||||||
'disable_existing_loggers': False,
|
'disable_existing_loggers': False,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'standard': {
|
'standard': {
|
||||||
'format': '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'}
|
'format': '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s',
|
||||||
|
'datefmt': '%Y-%m-%d %H:%M:%S'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
'handlers': {
|
'handlers': {
|
||||||
'django_error': {
|
'django_error': {
|
||||||
@ -145,11 +147,6 @@ LOGGING = {
|
|||||||
'level': 'WARNING',
|
'level': 'WARNING',
|
||||||
'propagate': True,
|
'propagate': True,
|
||||||
},
|
},
|
||||||
'django.server': {
|
|
||||||
'handlers': ['django_error', 'console'],
|
|
||||||
'level': 'ERROR',
|
|
||||||
'propagate': True,
|
|
||||||
},
|
|
||||||
'django.db.backends': {
|
'django.db.backends': {
|
||||||
'handlers': ['django_error', 'console'],
|
'handlers': ['django_error', 'console'],
|
||||||
'level': 'WARNING',
|
'level': 'WARNING',
|
||||||
|
@ -39,7 +39,7 @@ class CreateOrEditProblemSerializer(serializers.Serializer):
|
|||||||
input_description = serializers.CharField()
|
input_description = serializers.CharField()
|
||||||
output_description = serializers.CharField()
|
output_description = serializers.CharField()
|
||||||
samples = serializers.ListField(child=CreateSampleSerializer(), allow_empty=False)
|
samples = serializers.ListField(child=CreateSampleSerializer(), allow_empty=False)
|
||||||
test_case_id = serializers.CharField(min_length=32, max_length=32)
|
test_case_id = serializers.CharField(max_length=32)
|
||||||
test_case_score = serializers.ListField(child=CreateTestCaseScoreSerializer(), allow_empty=False)
|
test_case_score = serializers.ListField(child=CreateTestCaseScoreSerializer(), allow_empty=False)
|
||||||
time_limit = serializers.IntegerField(min_value=1, max_value=1000 * 60)
|
time_limit = serializers.IntegerField(min_value=1, max_value=1000 * 60)
|
||||||
memory_limit = serializers.IntegerField(min_value=1, max_value=1024)
|
memory_limit = serializers.IntegerField(min_value=1, max_value=1024)
|
||||||
@ -68,6 +68,11 @@ class CreateContestProblemSerializer(CreateOrEditProblemSerializer):
|
|||||||
contest_id = serializers.IntegerField()
|
contest_id = serializers.IntegerField()
|
||||||
|
|
||||||
|
|
||||||
|
class EditContestProblemSerializer(CreateOrEditProblemSerializer):
|
||||||
|
id = serializers.IntegerField()
|
||||||
|
contest_id = serializers.IntegerField()
|
||||||
|
|
||||||
|
|
||||||
class TagSerializer(serializers.ModelSerializer):
|
class TagSerializer(serializers.ModelSerializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ProblemTag
|
model = ProblemTag
|
||||||
|
@ -12,7 +12,7 @@ from utils.shortcuts import rand_str
|
|||||||
|
|
||||||
from ..models import Problem, ProblemRuleType, ProblemTag
|
from ..models import Problem, ProblemRuleType, ProblemTag
|
||||||
from ..serializers import (CreateContestProblemSerializer, ContestProblemAdminSerializer,
|
from ..serializers import (CreateContestProblemSerializer, ContestProblemAdminSerializer,
|
||||||
CreateProblemSerializer, EditProblemSerializer,
|
CreateProblemSerializer, EditProblemSerializer, EditContestProblemSerializer,
|
||||||
ProblemAdminSerializer, TestCaseUploadForm)
|
ProblemAdminSerializer, TestCaseUploadForm)
|
||||||
|
|
||||||
|
|
||||||
@ -109,26 +109,14 @@ class TestCaseUploadAPI(CSRFExemptAPIView):
|
|||||||
return self.success({"id": test_case_id, "info": ret, "hint": hint, "spj": spj})
|
return self.success({"id": test_case_id, "info": ret, "hint": hint, "spj": spj})
|
||||||
|
|
||||||
|
|
||||||
class ProblemAPI(APIView):
|
class ProblemBase(APIView):
|
||||||
@validate_serializer(CreateProblemSerializer)
|
def common_checks(self, request):
|
||||||
@problem_permission_required
|
|
||||||
def post(self, request):
|
|
||||||
data = request.data
|
data = request.data
|
||||||
|
|
||||||
_id = data["_id"]
|
|
||||||
if _id:
|
|
||||||
try:
|
|
||||||
Problem.objects.get(_id=_id)
|
|
||||||
return self.error("Display ID already exists")
|
|
||||||
except Problem.DoesNotExist:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
data["_id"] = rand_str(8)
|
|
||||||
|
|
||||||
if data["spj"]:
|
if data["spj"]:
|
||||||
if not data["spj_language"] or not data["spj_code"]:
|
if not data["spj_language"] or not data["spj_code"]:
|
||||||
return self.error("Invalid spj")
|
return "Invalid spj"
|
||||||
data["spj_version"] = hashlib.md5((data["spj_language"] + ":" + data["spj_code"]).encode("utf-8")).hexdigest()
|
data["spj_version"] = hashlib.md5(
|
||||||
|
(data["spj_language"] + ":" + data["spj_code"]).encode("utf-8")).hexdigest()
|
||||||
else:
|
else:
|
||||||
data["spj_language"] = None
|
data["spj_language"] = None
|
||||||
data["spj_code"] = None
|
data["spj_code"] = None
|
||||||
@ -136,21 +124,33 @@ class ProblemAPI(APIView):
|
|||||||
total_score = 0
|
total_score = 0
|
||||||
for item in data["test_case_score"]:
|
for item in data["test_case_score"]:
|
||||||
if item["score"] <= 0:
|
if item["score"] <= 0:
|
||||||
return self.error("Invalid score")
|
return "Invalid score"
|
||||||
else:
|
else:
|
||||||
total_score += item["score"]
|
total_score += item["score"]
|
||||||
data["total_score"] = total_score
|
data["total_score"] = total_score
|
||||||
# todo check filename and score info
|
|
||||||
data["created_by"] = request.user
|
data["created_by"] = request.user
|
||||||
tags = data.pop("tags")
|
|
||||||
|
|
||||||
data["languages"] = list(data["languages"])
|
data["languages"] = list(data["languages"])
|
||||||
|
|
||||||
problem = Problem.objects.create(**data)
|
|
||||||
|
|
||||||
|
class ProblemAPI(ProblemBase):
|
||||||
|
@validate_serializer(CreateProblemSerializer)
|
||||||
|
@problem_permission_required
|
||||||
|
def post(self, request):
|
||||||
|
data = request.data
|
||||||
|
|
||||||
|
_id = data["_id"]
|
||||||
if not _id:
|
if not _id:
|
||||||
problem._id = str(problem.id)
|
return self.error("Display ID is required")
|
||||||
problem.save()
|
if Problem.objects.filter(_id=_id, contest_id__isnull=True).exists():
|
||||||
|
return self.error("Display ID already exists")
|
||||||
|
|
||||||
|
error_info = self.common_checks(request)
|
||||||
|
if error_info:
|
||||||
|
return self.error(error_info)
|
||||||
|
|
||||||
|
# todo check filename and score info
|
||||||
|
tags = data.pop("tags")
|
||||||
|
problem = Problem.objects.create(**data)
|
||||||
|
|
||||||
for item in tags:
|
for item in tags:
|
||||||
try:
|
try:
|
||||||
@ -196,31 +196,14 @@ class ProblemAPI(APIView):
|
|||||||
return self.error("Problem does not exist")
|
return self.error("Problem does not exist")
|
||||||
|
|
||||||
_id = data["_id"]
|
_id = data["_id"]
|
||||||
if _id:
|
if not _id:
|
||||||
try:
|
return self.error("Display ID is required")
|
||||||
Problem.objects.exclude(id=problem_id).get(_id=_id)
|
if Problem.objects.exclude(id=problem_id).filter(_id=_id, contest_id__isnull=True).exists():
|
||||||
return self.error("Display ID already exists")
|
return self.error("Display ID already exists")
|
||||||
except Problem.DoesNotExist:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
data["_id"] = str(problem_id)
|
|
||||||
|
|
||||||
if data["spj"]:
|
error_info = self.common_checks(request)
|
||||||
if not data["spj_language"] or not data["spj_code"]:
|
if error_info:
|
||||||
return self.error("Invalid spj")
|
return self.error(error_info)
|
||||||
data["spj_version"] = hashlib.md5((data["spj_language"] + ":" + data["spj_code"]).encode("utf-8")).hexdigest()
|
|
||||||
else:
|
|
||||||
data["spj_language"] = None
|
|
||||||
data["spj_code"] = None
|
|
||||||
|
|
||||||
if data["rule_type"] == ProblemRuleType.OI:
|
|
||||||
total_score = 0
|
|
||||||
for item in data["test_case_score"]:
|
|
||||||
if item["score"] <= 0:
|
|
||||||
return self.error("Invalid score")
|
|
||||||
else:
|
|
||||||
total_score += item["score"]
|
|
||||||
data["total_score"] = total_score
|
|
||||||
# todo check filename and score info
|
# todo check filename and score info
|
||||||
tags = data.pop("tags")
|
tags = data.pop("tags")
|
||||||
data["languages"] = list(data["languages"])
|
data["languages"] = list(data["languages"])
|
||||||
@ -240,11 +223,11 @@ class ProblemAPI(APIView):
|
|||||||
return self.success()
|
return self.success()
|
||||||
|
|
||||||
|
|
||||||
class ContestProblemAPI(APIView):
|
class ContestProblemAPI(ProblemBase):
|
||||||
@validate_serializer(CreateContestProblemSerializer)
|
@validate_serializer(CreateContestProblemSerializer)
|
||||||
|
@problem_permission_required
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
data = request.data
|
data = request.data
|
||||||
|
|
||||||
try:
|
try:
|
||||||
contest = Contest.objects.get(id=data.pop("contest_id"))
|
contest = Contest.objects.get(id=data.pop("contest_id"))
|
||||||
if request.user.is_admin() and contest.created_by != request.user:
|
if request.user.is_admin() and contest.created_by != request.user:
|
||||||
@ -257,30 +240,18 @@ class ContestProblemAPI(APIView):
|
|||||||
|
|
||||||
_id = data["_id"]
|
_id = data["_id"]
|
||||||
if not _id:
|
if not _id:
|
||||||
return self.error("Display id is required for contest problem")
|
return self.error("Display ID is required")
|
||||||
|
|
||||||
if Problem.objects.filter(_id=_id, contest=contest).exists():
|
if Problem.objects.filter(_id=_id, contest=contest).exists():
|
||||||
return self.error("Duplicate Display id")
|
return self.error("Duplicate Display id")
|
||||||
|
|
||||||
if data["spj"]:
|
error_info = self.common_checks(request)
|
||||||
if not data["spj_language"] or not data["spj_code"]:
|
if error_info:
|
||||||
return self.error("Invalid spj")
|
return self.error(error_info)
|
||||||
data["spj_version"] = hashlib.md5((data["spj_language"] + ":" + data["spj_code"]).encode("utf-8")).hexdigest()
|
|
||||||
else:
|
|
||||||
data["spj_language"] = None
|
|
||||||
data["spj_code"] = None
|
|
||||||
|
|
||||||
if data["rule_type"] == ProblemRuleType.OI:
|
|
||||||
for item in data["test_case_score"]:
|
|
||||||
if item["score"] <= 0:
|
|
||||||
return self.error("Invalid score")
|
|
||||||
# todo check filename and score info
|
# todo check filename and score info
|
||||||
|
|
||||||
data["created_by"] = request.user
|
|
||||||
data["contest"] = contest
|
data["contest"] = contest
|
||||||
tags = data.pop("tags")
|
tags = data.pop("tags")
|
||||||
data["languages"] = list(data["languages"])
|
|
||||||
|
|
||||||
problem = Problem.objects.create(**data)
|
problem = Problem.objects.create(**data)
|
||||||
|
|
||||||
for item in tags:
|
for item in tags:
|
||||||
@ -291,6 +262,7 @@ class ContestProblemAPI(APIView):
|
|||||||
problem.tags.add(tag)
|
problem.tags.add(tag)
|
||||||
return self.success(ContestProblemAdminSerializer(problem).data)
|
return self.success(ContestProblemAdminSerializer(problem).data)
|
||||||
|
|
||||||
|
@problem_permission_required
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
problem_id = request.GET.get("id")
|
problem_id = request.GET.get("id")
|
||||||
contest_id = request.GET.get("contest_id")
|
contest_id = request.GET.get("contest_id")
|
||||||
@ -314,3 +286,53 @@ class ContestProblemAPI(APIView):
|
|||||||
if keyword:
|
if keyword:
|
||||||
problems = problems.filter(title__contains=keyword)
|
problems = problems.filter(title__contains=keyword)
|
||||||
return self.success(self.paginate_data(request, problems, ContestProblemAdminSerializer))
|
return self.success(self.paginate_data(request, problems, ContestProblemAdminSerializer))
|
||||||
|
|
||||||
|
@validate_serializer(EditContestProblemSerializer)
|
||||||
|
@problem_permission_required
|
||||||
|
def put(self, request):
|
||||||
|
data = request.data
|
||||||
|
try:
|
||||||
|
contest = Contest.objects.get(id=data.pop("contest_id"))
|
||||||
|
if request.user.is_admin() and contest.created_by != request.user:
|
||||||
|
return self.error("Contest does not exist")
|
||||||
|
except Contest.DoesNotExist:
|
||||||
|
return self.error("Contest does not exist")
|
||||||
|
|
||||||
|
if data["rule_type"] != contest.rule_type:
|
||||||
|
return self.error("Invalid rule type")
|
||||||
|
|
||||||
|
problem_id = data.pop("id")
|
||||||
|
user = request.user
|
||||||
|
|
||||||
|
try:
|
||||||
|
problem = Problem.objects.get(id=problem_id, contest=contest)
|
||||||
|
if not user.can_mgmt_all_problem() and problem.created_by != user:
|
||||||
|
return self.error("Problem does not exist")
|
||||||
|
except Problem.DoesNotExist:
|
||||||
|
return self.error("Problem does not exist")
|
||||||
|
|
||||||
|
_id = data["_id"]
|
||||||
|
if not _id:
|
||||||
|
return self.error("Display ID is required")
|
||||||
|
if Problem.objects.exclude(id=problem_id).filter(_id=_id, contest=contest).exists():
|
||||||
|
return self.error("Display ID already exists")
|
||||||
|
|
||||||
|
error_info = self.common_checks(request)
|
||||||
|
if error_info:
|
||||||
|
return self.error(error_info)
|
||||||
|
# todo check filename and score info
|
||||||
|
tags = data.pop("tags")
|
||||||
|
data["languages"] = list(data["languages"])
|
||||||
|
|
||||||
|
for k, v in data.items():
|
||||||
|
setattr(problem, k, v)
|
||||||
|
problem.save()
|
||||||
|
|
||||||
|
problem.tags.remove(*problem.tags.all())
|
||||||
|
for tag in tags:
|
||||||
|
try:
|
||||||
|
tag = ProblemTag.objects.get(name=tag)
|
||||||
|
except ProblemTag.DoesNotExist:
|
||||||
|
tag = ProblemTag.objects.create(name=tag)
|
||||||
|
problem.tags.add(tag)
|
||||||
|
return self.success()
|
||||||
|
Loading…
Reference in New Issue
Block a user