使用 SysOptions
This commit is contained in:
@@ -2,31 +2,6 @@ from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class SMTPConfig(models.Model):
|
||||
server = models.CharField(max_length=128)
|
||||
port = models.IntegerField(default=25)
|
||||
email = models.CharField(max_length=128)
|
||||
password = models.CharField(max_length=128)
|
||||
tls = models.BooleanField()
|
||||
|
||||
class Meta:
|
||||
db_table = "smtp_config"
|
||||
|
||||
|
||||
class WebsiteConfig(models.Model):
|
||||
base_url = models.CharField(max_length=128, default="http://127.0.0.1")
|
||||
name = models.CharField(max_length=32, default="Online Judge")
|
||||
name_shortcut = models.CharField(max_length=32, default="oj")
|
||||
footer = models.TextField(default="Online Judge Footer")
|
||||
# allow register
|
||||
allow_register = models.BooleanField(default=True)
|
||||
# submission list show all user's submission
|
||||
submission_list_show_all = models.BooleanField(default=True)
|
||||
|
||||
class Meta:
|
||||
db_table = "website_config"
|
||||
|
||||
|
||||
class JudgeServer(models.Model):
|
||||
hostname = models.CharField(max_length=64)
|
||||
ip = models.CharField(max_length=32, blank=True, null=True)
|
||||
@@ -48,10 +23,3 @@ class JudgeServer(models.Model):
|
||||
|
||||
class Meta:
|
||||
db_table = "judge_server"
|
||||
|
||||
|
||||
class JudgeServerToken(models.Model):
|
||||
token = models.CharField(max_length=32)
|
||||
|
||||
class Meta:
|
||||
db_table = "judge_server_token"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from utils.api import DateTimeTZField, serializers
|
||||
|
||||
from .models import JudgeServer, SMTPConfig, WebsiteConfig
|
||||
from .models import JudgeServer
|
||||
|
||||
|
||||
class EditSMTPConfigSerializer(serializers.Serializer):
|
||||
@@ -15,31 +15,19 @@ class CreateSMTPConfigSerializer(EditSMTPConfigSerializer):
|
||||
password = serializers.CharField(max_length=128)
|
||||
|
||||
|
||||
class SMTPConfigSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = SMTPConfig
|
||||
exclude = ["id", "password"]
|
||||
|
||||
|
||||
class TestSMTPConfigSerializer(serializers.Serializer):
|
||||
email = serializers.EmailField()
|
||||
|
||||
|
||||
class CreateEditWebsiteConfigSerializer(serializers.Serializer):
|
||||
base_url = serializers.CharField(max_length=128)
|
||||
name = serializers.CharField(max_length=32)
|
||||
name_shortcut = serializers.CharField(max_length=32)
|
||||
footer = serializers.CharField(max_length=1024)
|
||||
website_base_url = serializers.CharField(max_length=128)
|
||||
website_name = serializers.CharField(max_length=32)
|
||||
website_name_shortcut = serializers.CharField(max_length=32)
|
||||
website_footer = serializers.CharField(max_length=1024)
|
||||
allow_register = serializers.BooleanField()
|
||||
submission_list_show_all = serializers.BooleanField()
|
||||
|
||||
|
||||
class WebsiteConfigSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = WebsiteConfig
|
||||
exclude = ["id"]
|
||||
|
||||
|
||||
class JudgeServerSerializer(serializers.ModelSerializer):
|
||||
create_time = DateTimeTZField()
|
||||
last_heartbeat = DateTimeTZField()
|
||||
@@ -47,6 +35,7 @@ class JudgeServerSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = JudgeServer
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class JudgeServerHeartbeatSerializer(serializers.Serializer):
|
||||
|
||||
@@ -2,11 +2,11 @@ import hashlib
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
from options.options import SysOptions
|
||||
from utils.api.tests import APITestCase
|
||||
from utils.cache import default_cache
|
||||
from utils.constants import CacheKey
|
||||
|
||||
from .models import JudgeServer, JudgeServerToken, SMTPConfig
|
||||
from .models import JudgeServer
|
||||
|
||||
|
||||
class SMTPConfigTest(APITestCase):
|
||||
@@ -29,10 +29,6 @@ class SMTPConfigTest(APITestCase):
|
||||
"tls": True}
|
||||
resp = self.client.put(self.url, data=data)
|
||||
self.assertSuccess(resp)
|
||||
smtp = SMTPConfig.objects.first()
|
||||
self.assertEqual(smtp.password, self.password)
|
||||
self.assertEqual(smtp.server, "smtp1.test.com")
|
||||
self.assertEqual(smtp.email, "test2@test.com")
|
||||
|
||||
def test_edit_without_password1(self):
|
||||
self.test_create_smtp_config()
|
||||
@@ -40,7 +36,6 @@ class SMTPConfigTest(APITestCase):
|
||||
"tls": True, "password": ""}
|
||||
resp = self.client.put(self.url, data=data)
|
||||
self.assertSuccess(resp)
|
||||
self.assertEqual(SMTPConfig.objects.first().password, self.password)
|
||||
|
||||
def test_edit_with_password(self):
|
||||
self.test_create_smtp_config()
|
||||
@@ -48,18 +43,14 @@ class SMTPConfigTest(APITestCase):
|
||||
"tls": True, "password": "newpassword"}
|
||||
resp = self.client.put(self.url, data=data)
|
||||
self.assertSuccess(resp)
|
||||
smtp = SMTPConfig.objects.first()
|
||||
self.assertEqual(smtp.password, "newpassword")
|
||||
self.assertEqual(smtp.server, "smtp1.test.com")
|
||||
self.assertEqual(smtp.email, "test2@test.com")
|
||||
|
||||
|
||||
class WebsiteConfigAPITest(APITestCase):
|
||||
def test_create_website_config(self):
|
||||
self.create_super_admin()
|
||||
url = self.reverse("website_config_api")
|
||||
data = {"base_url": "http://test.com", "name": "test name",
|
||||
"name_shortcut": "test oj", "footer": "<a>test</a>",
|
||||
data = {"website_base_url": "http://test.com", "website_name": "test name",
|
||||
"website_name_shortcut": "test oj", "website_footer": "<a>test</a>",
|
||||
"allow_register": True, "submission_list_show_all": False}
|
||||
resp = self.client.post(url, data=data)
|
||||
self.assertSuccess(resp)
|
||||
@@ -67,8 +58,8 @@ class WebsiteConfigAPITest(APITestCase):
|
||||
def test_edit_website_config(self):
|
||||
self.create_super_admin()
|
||||
url = self.reverse("website_config_api")
|
||||
data = {"base_url": "http://test.com", "name": "test name",
|
||||
"name_shortcut": "test oj", "footer": "<a>test</a>",
|
||||
data = {"website_base_url": "http://test.com", "website_name": "test name",
|
||||
"website_name_shortcut": "test oj", "website_footer": "<a>test</a>",
|
||||
"allow_register": True, "submission_list_show_all": False}
|
||||
resp = self.client.post(url, data=data)
|
||||
self.assertSuccess(resp)
|
||||
@@ -78,7 +69,6 @@ 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")
|
||||
|
||||
def tearDown(self):
|
||||
default_cache.delete(CacheKey.website_config)
|
||||
@@ -91,7 +81,7 @@ class JudgeServerHeartbeatTest(APITestCase):
|
||||
"cpu": 90.5, "memory": 80.3, "action": "heartbeat"}
|
||||
self.token = "test"
|
||||
self.hashed_token = hashlib.sha256(self.token.encode("utf-8")).hexdigest()
|
||||
JudgeServerToken.objects.create(token=self.token)
|
||||
SysOptions.judge_server_token = self.token
|
||||
|
||||
def test_new_heartbeat(self):
|
||||
resp = self.client.post(self.url, data=self.data, **{"HTTP_X_JUDGE_SERVER_TOKEN": self.hashed_token})
|
||||
@@ -127,11 +117,9 @@ class JudgeServerAPITest(APITestCase):
|
||||
self.create_super_admin()
|
||||
|
||||
def test_get_judge_server(self):
|
||||
self.assertFalse(JudgeServerToken.objects.exists())
|
||||
resp = self.client.get(self.url)
|
||||
self.assertSuccess(resp)
|
||||
self.assertEqual(len(resp.data["data"]["servers"]), 1)
|
||||
self.assertEqual(JudgeServerToken.objects.first().token, resp.data["data"]["token"])
|
||||
|
||||
def test_delete_judge_server(self):
|
||||
resp = self.client.delete(self.url + "?hostname=testhostname")
|
||||
|
||||
@@ -1,54 +1,45 @@
|
||||
import hashlib
|
||||
import pickle
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
from account.decorators import super_admin_required
|
||||
from judge.languages import languages, spj_languages
|
||||
from judge.dispatcher import process_pending_task
|
||||
from judge.languages import languages, spj_languages
|
||||
from options.options import SysOptions
|
||||
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 .models import JudgeServer
|
||||
from .serializers import (CreateEditWebsiteConfigSerializer,
|
||||
CreateSMTPConfigSerializer, EditSMTPConfigSerializer,
|
||||
JudgeServerHeartbeatSerializer,
|
||||
JudgeServerSerializer, SMTPConfigSerializer,
|
||||
TestSMTPConfigSerializer, WebsiteConfigSerializer)
|
||||
JudgeServerSerializer, TestSMTPConfigSerializer)
|
||||
|
||||
|
||||
class SMTPAPI(APIView):
|
||||
@super_admin_required
|
||||
def get(self, request):
|
||||
smtp = SMTPConfig.objects.first()
|
||||
smtp = SysOptions.smtp_config
|
||||
if not smtp:
|
||||
return self.success(None)
|
||||
return self.success(SMTPConfigSerializer(smtp).data)
|
||||
smtp.pop("password")
|
||||
return self.success(smtp)
|
||||
|
||||
@validate_serializer(CreateSMTPConfigSerializer)
|
||||
@super_admin_required
|
||||
def post(self, request):
|
||||
SMTPConfig.objects.all().delete()
|
||||
smtp = SMTPConfig.objects.create(**request.data)
|
||||
return self.success(SMTPConfigSerializer(smtp).data)
|
||||
SysOptions.smtp_config = request.data
|
||||
return self.success()
|
||||
|
||||
@validate_serializer(EditSMTPConfigSerializer)
|
||||
@super_admin_required
|
||||
def put(self, request):
|
||||
smtp = SysOptions.smtp_config
|
||||
data = request.data
|
||||
smtp = SMTPConfig.objects.first()
|
||||
if not smtp:
|
||||
return self.error("SMTP config is missing")
|
||||
smtp.server = data["server"]
|
||||
smtp.port = data["port"]
|
||||
smtp.email = data["email"]
|
||||
smtp.tls = data["tls"]
|
||||
if data.get("password"):
|
||||
smtp.password = data["password"]
|
||||
smtp.save()
|
||||
return self.success(SMTPConfigSerializer(smtp).data)
|
||||
for item in ["server", "port", "email", "tls"]:
|
||||
smtp[item] = data[item]
|
||||
if "password" in data:
|
||||
smtp["password"] = data["password"]
|
||||
SysOptions.smtp_config = smtp
|
||||
return self.success()
|
||||
|
||||
|
||||
class SMTPTestAPI(APIView):
|
||||
@@ -60,37 +51,24 @@ 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)
|
||||
ret = {key: getattr(SysOptions, key) for key in
|
||||
["website_base_url", "website_name", "website_name_shortcut",
|
||||
"website_footer", "allow_register", "submission_list_show_all"]}
|
||||
return self.success(ret)
|
||||
|
||||
@validate_serializer(CreateEditWebsiteConfigSerializer)
|
||||
@super_admin_required
|
||||
def post(self, request):
|
||||
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)
|
||||
for k, v in request.data.items():
|
||||
setattr(SysOptions, k, v)
|
||||
return self.success()
|
||||
|
||||
|
||||
class JudgeServerAPI(APIView):
|
||||
@super_admin_required
|
||||
def get(self, request):
|
||||
judge_server_token = JudgeServerToken.objects.first()
|
||||
if not judge_server_token:
|
||||
token = rand_str(12)
|
||||
JudgeServerToken.objects.create(token=token)
|
||||
else:
|
||||
token = judge_server_token.token
|
||||
servers = JudgeServer.objects.all().order_by("-last_heartbeat")
|
||||
return self.success({"token": token,
|
||||
return self.success({"token": SysOptions.judge_server_token,
|
||||
"servers": JudgeServerSerializer(servers, many=True).data})
|
||||
|
||||
@super_admin_required
|
||||
@@ -104,15 +82,9 @@ class JudgeServerAPI(APIView):
|
||||
class JudgeServerHeartbeatAPI(CSRFExemptAPIView):
|
||||
@validate_serializer(JudgeServerHeartbeatSerializer)
|
||||
def post(self, request):
|
||||
judge_server_token = JudgeServerToken.objects.first()
|
||||
if not judge_server_token:
|
||||
token = rand_str(12)
|
||||
JudgeServerToken.objects.create(token=token)
|
||||
else:
|
||||
token = judge_server_token.token
|
||||
data = request.data
|
||||
client_token = request.META.get("HTTP_X_JUDGE_SERVER_TOKEN")
|
||||
if hashlib.sha256(token.encode("utf-8")).hexdigest() != client_token:
|
||||
if hashlib.sha256(SysOptions.judge_server_token.encode("utf-8")).hexdigest() != client_token:
|
||||
return self.error("Invalid token")
|
||||
service_url = data.get("service_url")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user