adjust account fields, cache the website_config

This commit is contained in:
zema1 2017-09-22 16:41:29 +08:00
parent 034ad59f2e
commit e9c7344815
9 changed files with 90 additions and 11 deletions

View File

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.4 on 2017-09-20 02:54
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('account', '0006_user_session_keys'),
]
operations = [
migrations.RenameField(
model_name='userprofile',
old_name='phone_number',
new_name='github',
),
migrations.AlterField(
model_name='userprofile',
name='avatar',
field=models.CharField(default='/static/avatar/default.png', max_length=50),
),
migrations.AlterField(
model_name='userprofile',
name='github',
field=models.CharField(blank=True, max_length=50, null=True),
),
]

View File

@ -76,10 +76,10 @@ class UserProfile(models.Model):
oi_problems_status = JSONField(default={})
real_name = models.CharField(max_length=30, blank=True, null=True)
avatar = models.CharField(max_length=50, default=_default_avatar)
avatar = models.CharField(max_length=50, default=_default_avatar())
blog = models.URLField(blank=True, null=True)
mood = models.CharField(max_length=200, blank=True, null=True)
phone_number = models.CharField(max_length=15, blank=True, null=True)
github = models.CharField(max_length=50, blank=True, null=True)
school = models.CharField(max_length=200, blank=True, null=True)
major = models.CharField(max_length=200, blank=True, null=True)
language = models.CharField(max_length=32, blank=True, null=True)

View File

@ -74,7 +74,7 @@ class EditUserProfileSerializer(serializers.Serializer):
avatar = serializers.CharField(max_length=100, allow_blank=True, required=False)
blog = serializers.URLField(allow_blank=True, required=False)
mood = serializers.CharField(max_length=200, allow_blank=True, required=False)
phone_number = serializers.CharField(max_length=15, allow_blank=True, required=False, )
github = serializers.CharField(max_length=50, allow_blank=True, required=False)
school = serializers.CharField(max_length=200, allow_blank=True, required=False)
major = serializers.CharField(max_length=200, allow_blank=True, required=False)

View File

@ -8,8 +8,11 @@ from otpauth import OtpAuth
from utils.api.tests import APIClient, APITestCase
from utils.shortcuts import rand_str
from utils.cache import default_cache
from utils.constants import CacheKey
from .models import AdminType, ProblemPermission, User
from conf.models import WebsiteConfig
class PermissionDecoratorTest(APITestCase):
@ -128,6 +131,13 @@ class UserLoginAPITest(APITestCase):
user = auth.get_user(self.client)
self.assertFalse(user.is_authenticated())
def test_user_disabled(self):
self.user.is_disabled = True
self.user.save()
resp = self.client.post(self.login_url, data={"username": self.username,
"password": self.password})
self.assertDictEqual(resp.data, {"error": "error", "data": "Your account have been disabled"})
class CaptchaTest(APITestCase):
def _set_captcha(self, session):
@ -147,6 +157,15 @@ class UserRegisterAPITest(CaptchaTest):
self.data = {"username": "test_user", "password": "testuserpassword",
"real_name": "real_name", "email": "test@qduoj.com",
"captcha": self._set_captcha(self.client.session)}
# clea cache in redis
default_cache.delete(CacheKey.website_config)
def test_website_config_limit(self):
website = WebsiteConfig.objects.create()
website.allow_register = False
website.save()
resp = self.client.post(self.register_url, data=self.data)
self.assertDictEqual(resp.data, {"error": "error", "data": "Register have been disabled by admin"})
def test_invalid_captcha(self):
self.data["captcha"] = "****"

View File

@ -1,5 +1,6 @@
import os
import qrcode
import pickle
from datetime import timedelta
from otpauth import OtpAuth
@ -15,6 +16,8 @@ from conf.models import WebsiteConfig
from utils.api import APIView, validate_serializer
from utils.captcha import Captcha
from utils.shortcuts import rand_str, img2base64, timestamp2utcstr
from utils.cache import default_cache
from utils.constants import CacheKey
from ..decorators import login_required
from ..models import User, UserProfile
@ -62,6 +65,7 @@ class UserProfileAPI(APIView):
class AvatarUploadAPI(APIView):
request_parsers = ()
@login_required
def post(self, request):
form = AvatarUploadForm(request.POST, request.FILES)
if form.is_valid():
@ -195,6 +199,8 @@ class UserLoginAPI(APIView):
user = auth.authenticate(username=data["username"], password=data["password"])
# None is returned if username or password is wrong
if user:
if user.is_disabled:
return self.error("Your account have been disabled")
if not user.two_factor_auth:
auth.login(request, user)
return self.success("Succeeded")
@ -250,6 +256,18 @@ class UserRegisterAPI(APIView):
"""
User register api
"""
config = default_cache.get(CacheKey.website_config)
if config:
config = pickle.loads(config)
else:
config = WebsiteConfig.objects.first()
if not config:
config = WebsiteConfig.objects.create()
default_cache.set(CacheKey.website_config, pickle.dumps(config))
if not config.allow_register:
return self.error("Register have been disabled by admin")
data = request.data
captcha = Captcha(request)
if not captcha.check(data["captcha"]):
@ -385,7 +403,9 @@ class UserRankAPI(APIView):
rule_type = request.GET.get("rule")
if rule_type not in ["acm", "oi"]:
rule_type = "acm"
profiles = UserProfile.objects.select_related("user").filter(submission_number__gt=0)
profiles = UserProfile.objects.select_related("user")\
.filter(submission_number__gt=0)\
.exclude(user__is_disabled=True)
if rule_type == "acm":
profiles = profiles.order_by("-accepted_number", "submission_number")
else:

View File

@ -76,7 +76,7 @@ class WebsiteConfigAPITest(APITestCase):
url = self.reverse("website_info_api")
resp = self.client.get(url)
self.assertSuccess(resp)
self.assertEqual(resp.data["data"]["name_shortcut"], "oj")
self.assertEqual(resp.data["data"]["name_shortcut"], "test oj")
class JudgeServerHeartbeatTest(APITestCase):

View File

@ -1,4 +1,5 @@
import hashlib
import pickle
from django.utils import timezone
@ -7,6 +8,8 @@ from judge.languages import languages, spj_languages
from judge.dispatcher import process_pending_task
from utils.api import APIView, CSRFExemptAPIView, validate_serializer
from utils.shortcuts import rand_str
from utils.cache import default_cache
from utils.constants import CacheKey
from .models import JudgeServer, JudgeServerToken, SMTPConfig, WebsiteConfig
from .serializers import (CreateEditWebsiteConfigSerializer,
@ -57,9 +60,14 @@ class SMTPTestAPI(APIView):
class WebsiteConfigAPI(APIView):
def get(self, request):
config = default_cache.get(CacheKey.website_config)
if config:
config = pickle.loads(config)
else:
config = WebsiteConfig.objects.first()
if not config:
config = WebsiteConfig.objects.create()
default_cache.set(CacheKey.website_config, pickle.dumps(config))
return self.success(WebsiteConfigSerializer(config).data)
@validate_serializer(CreateEditWebsiteConfigSerializer)
@ -68,6 +76,7 @@ class WebsiteConfigAPI(APIView):
data = request.data
WebsiteConfig.objects.all().delete()
config = WebsiteConfig.objects.create(**data)
default_cache.set(CacheKey.website_config, pickle.dumps(config))
return self.success(WebsiteConfigSerializer(config).data)

View File

@ -43,9 +43,9 @@ class ProblemAPI(APIView):
problems = problems.filter(Q(title__contains=keyword) | Q(description__contains=keyword))
# 难度筛选
difficulty_rank = request.GET.get("difficulty")
if difficulty_rank:
problems = problems.filter(difficulty=difficulty_rank)
difficulty = request.GET.get("difficulty")
if difficulty:
problems = problems.filter(difficulty=difficulty)
# 根据profile 为做过的题目添加标记
data = self.paginate_data(request, problems, ProblemSerializer)
if request.user.id:

View File

@ -1,3 +1,4 @@
class CacheKey:
waiting_queue = "waiting_queue"
contest_rank_cache = "contest_rank_cache_"
website_config = "website_config"