test for csrf
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
from utils.api import APIView
|
from utils.api import APIView
|
||||||
|
|
||||||
from announcement.models import Announcement
|
from announcement.models import Announcement
|
||||||
from announcement.serializers import (AnnouncementSerializer,
|
from announcement.serializers import AnnouncementSerializer, AnnouncementListSerializer
|
||||||
AnnouncementListSerializer)
|
|
||||||
|
|
||||||
|
|
||||||
class AnnouncementAPI(APIView):
|
class AnnouncementAPI(APIView):
|
||||||
@@ -16,4 +15,6 @@ class AnnouncementAPI(APIView):
|
|||||||
return self.error("Announcement does not exist")
|
return self.error("Announcement does not exist")
|
||||||
|
|
||||||
announcements = Announcement.objects.filter(visible=True)
|
announcements = Announcement.objects.filter(visible=True)
|
||||||
return self.success(self.paginate_data(request, announcements, AnnouncementListSerializer))
|
return self.success(
|
||||||
|
self.paginate_data(request, announcements, AnnouncementListSerializer)
|
||||||
|
)
|
||||||
|
|||||||
@@ -21,4 +21,6 @@ DEBUG = True
|
|||||||
|
|
||||||
ALLOWED_HOSTS = ["*"]
|
ALLOWED_HOSTS = ["*"]
|
||||||
|
|
||||||
|
CSRF_TRUSTED_ORIGINS = ["http://localhost:5173"]
|
||||||
|
|
||||||
DATA_DIR = f"{BASE_DIR}/data"
|
DATA_DIR = f"{BASE_DIR}/data"
|
||||||
|
|||||||
@@ -18,6 +18,23 @@ REDIS_CONF = {
|
|||||||
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
|
|
||||||
ALLOWED_HOSTS = ["*"]
|
ALLOWED_HOSTS = [
|
||||||
|
"localhost",
|
||||||
|
"127.0.0.1",
|
||||||
|
"oj.xuyue.cc",
|
||||||
|
"ojtest.xuyue.cc",
|
||||||
|
"10.13.114.114",
|
||||||
|
"150.158.29.156",
|
||||||
|
]
|
||||||
|
|
||||||
|
CSRF_TRUSTED_ORIGINS = [
|
||||||
|
"http://localhost:5173",
|
||||||
|
"http://localhost:9005", # health check
|
||||||
|
"http://127.0.0.1:5173",
|
||||||
|
"https://oj.xuyue.cc",
|
||||||
|
"https://ojtest.xuyue.cc",
|
||||||
|
"http://10.13.114.114:81",
|
||||||
|
"http://150.158.29.156:8881",
|
||||||
|
]
|
||||||
|
|
||||||
DATA_DIR = "/data"
|
DATA_DIR = "/data"
|
||||||
|
|||||||
196
oj/settings.py
196
oj/settings.py
@@ -9,6 +9,7 @@ https://docs.djangoproject.com/en/1.8/topics/settings/
|
|||||||
For the full list of settings and their values, see
|
For the full list of settings and their values, see
|
||||||
https://docs.djangoproject.com/en/1.8/ref/settings/
|
https://docs.djangoproject.com/en/1.8/ref/settings/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import raven
|
import raven
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
@@ -27,93 +28,93 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||||||
|
|
||||||
# Applications
|
# Applications
|
||||||
VENDOR_APPS = [
|
VENDOR_APPS = [
|
||||||
'django.contrib.auth',
|
"django.contrib.auth",
|
||||||
'django.contrib.sessions',
|
"django.contrib.sessions",
|
||||||
'django.contrib.contenttypes',
|
"django.contrib.contenttypes",
|
||||||
'django.contrib.messages',
|
"django.contrib.messages",
|
||||||
'django.contrib.staticfiles',
|
"django.contrib.staticfiles",
|
||||||
'rest_framework',
|
"rest_framework",
|
||||||
'django_dramatiq',
|
"django_dramatiq",
|
||||||
'django_dbconn_retry',
|
"django_dbconn_retry",
|
||||||
]
|
]
|
||||||
|
|
||||||
if production_env:
|
if production_env:
|
||||||
VENDOR_APPS.append('raven.contrib.django.raven_compat')
|
VENDOR_APPS.append("raven.contrib.django.raven_compat")
|
||||||
|
|
||||||
|
|
||||||
LOCAL_APPS = [
|
LOCAL_APPS = [
|
||||||
'account',
|
"account",
|
||||||
'announcement',
|
"announcement",
|
||||||
'conf',
|
"conf",
|
||||||
'problem',
|
"problem",
|
||||||
'contest',
|
"contest",
|
||||||
'utils',
|
"utils",
|
||||||
'submission',
|
"submission",
|
||||||
'options',
|
"options",
|
||||||
'judge',
|
"judge",
|
||||||
'message',
|
"message",
|
||||||
'comment',
|
"comment",
|
||||||
'tutorial',
|
"tutorial",
|
||||||
]
|
]
|
||||||
|
|
||||||
INSTALLED_APPS = VENDOR_APPS + LOCAL_APPS
|
INSTALLED_APPS = VENDOR_APPS + LOCAL_APPS
|
||||||
|
|
||||||
MIDDLEWARE = (
|
MIDDLEWARE = (
|
||||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
'django.middleware.common.CommonMiddleware',
|
"django.middleware.common.CommonMiddleware",
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
'account.middleware.APITokenAuthMiddleware',
|
"account.middleware.APITokenAuthMiddleware",
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
'django.middleware.security.SecurityMiddleware',
|
"django.middleware.security.SecurityMiddleware",
|
||||||
'account.middleware.AdminRoleRequiredMiddleware',
|
"account.middleware.AdminRoleRequiredMiddleware",
|
||||||
'account.middleware.SessionRecordMiddleware',
|
"account.middleware.SessionRecordMiddleware",
|
||||||
# 'account.middleware.LogSqlMiddleware',
|
# 'account.middleware.LogSqlMiddleware',
|
||||||
)
|
)
|
||||||
ROOT_URLCONF = 'oj.urls'
|
ROOT_URLCONF = "oj.urls"
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
'DIRS': [],
|
"DIRS": [],
|
||||||
'APP_DIRS': True,
|
"APP_DIRS": True,
|
||||||
'OPTIONS': {
|
"OPTIONS": {
|
||||||
'context_processors': [
|
"context_processors": [
|
||||||
'django.template.context_processors.debug',
|
"django.template.context_processors.debug",
|
||||||
'django.template.context_processors.request',
|
"django.template.context_processors.request",
|
||||||
'django.contrib.auth.context_processors.auth',
|
"django.contrib.auth.context_processors.auth",
|
||||||
'django.contrib.messages.context_processors.messages',
|
"django.contrib.messages.context_processors.messages",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
WSGI_APPLICATION = 'oj.wsgi.application'
|
WSGI_APPLICATION = "oj.wsgi.application"
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
# https://docs.djangoproject.com/en/1.8/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = "en-us"
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = "UTC"
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
@@ -124,9 +125,9 @@ USE_TZ = True
|
|||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
# https://docs.djangoproject.com/en/1.8/howto/static-files/
|
# https://docs.djangoproject.com/en/1.8/howto/static-files/
|
||||||
|
|
||||||
STATIC_URL = '/public/'
|
STATIC_URL = "/public/"
|
||||||
|
|
||||||
AUTH_USER_MODEL = 'account.User'
|
AUTH_USER_MODEL = "account.User"
|
||||||
|
|
||||||
TEST_CASE_DIR = os.path.join(DATA_DIR, "test_case")
|
TEST_CASE_DIR = os.path.join(DATA_DIR, "test_case")
|
||||||
LOG_PATH = os.path.join(DATA_DIR, "log")
|
LOG_PATH = os.path.join(DATA_DIR, "log")
|
||||||
@@ -142,57 +143,55 @@ HITOKOTO_DIR = os.path.join(DATA_DIR, "hitokoto")
|
|||||||
STATICFILES_DIRS = [os.path.join(DATA_DIR, "public")]
|
STATICFILES_DIRS = [os.path.join(DATA_DIR, "public")]
|
||||||
|
|
||||||
|
|
||||||
LOGGING_HANDLERS = ['console', 'sentry'] if production_env else ['console']
|
LOGGING_HANDLERS = ["console", "sentry"] if production_env else ["console"]
|
||||||
LOGGING = {
|
LOGGING = {
|
||||||
'version': 1,
|
"version": 1,
|
||||||
'disable_existing_loggers': False,
|
"disable_existing_loggers": False,
|
||||||
'formatters': {
|
"formatters": {
|
||||||
'standard': {
|
"standard": {
|
||||||
'format': '[%(asctime)s] - [%(levelname)s] - [%(name)s:%(lineno)d] - %(message)s',
|
"format": "[%(asctime)s] - [%(levelname)s] - [%(name)s:%(lineno)d] - %(message)s",
|
||||||
'datefmt': '%Y-%m-%d %H:%M:%S'
|
"datefmt": "%Y-%m-%d %H:%M:%S",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'handlers': {
|
"handlers": {
|
||||||
'console': {
|
"console": {
|
||||||
'level': 'DEBUG',
|
"level": "DEBUG",
|
||||||
'class': 'logging.StreamHandler',
|
"class": "logging.StreamHandler",
|
||||||
'formatter': 'standard'
|
"formatter": "standard",
|
||||||
},
|
},
|
||||||
'sentry': {
|
"sentry": {
|
||||||
'level': 'ERROR',
|
"level": "ERROR",
|
||||||
'class': 'raven.contrib.django.raven_compat.handlers.SentryHandler',
|
"class": "raven.contrib.django.raven_compat.handlers.SentryHandler",
|
||||||
'formatter': 'standard'
|
"formatter": "standard",
|
||||||
}
|
|
||||||
},
|
},
|
||||||
'loggers': {
|
|
||||||
'django.request': {
|
|
||||||
'handlers': LOGGING_HANDLERS,
|
|
||||||
'level': 'ERROR',
|
|
||||||
'propagate': True,
|
|
||||||
},
|
},
|
||||||
'django.db.backends': {
|
"loggers": {
|
||||||
'handlers': LOGGING_HANDLERS,
|
"django.request": {
|
||||||
'level': 'ERROR',
|
"handlers": LOGGING_HANDLERS,
|
||||||
'propagate': True,
|
"level": "ERROR",
|
||||||
|
"propagate": True,
|
||||||
},
|
},
|
||||||
'dramatiq': {
|
"django.db.backends": {
|
||||||
'handlers': LOGGING_HANDLERS,
|
"handlers": LOGGING_HANDLERS,
|
||||||
'level': 'DEBUG',
|
"level": "ERROR",
|
||||||
'propagate': False,
|
"propagate": True,
|
||||||
|
},
|
||||||
|
"dramatiq": {
|
||||||
|
"handlers": LOGGING_HANDLERS,
|
||||||
|
"level": "DEBUG",
|
||||||
|
"propagate": False,
|
||||||
|
},
|
||||||
|
"": {
|
||||||
|
"handlers": LOGGING_HANDLERS,
|
||||||
|
"level": "WARNING",
|
||||||
|
"propagate": True,
|
||||||
},
|
},
|
||||||
'': {
|
|
||||||
'handlers': LOGGING_HANDLERS,
|
|
||||||
'level': 'WARNING',
|
|
||||||
'propagate': True,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
|
"TEST_REQUEST_DEFAULT_FORMAT": "json",
|
||||||
'DEFAULT_RENDERER_CLASSES': (
|
"DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",),
|
||||||
'rest_framework.renderers.JSONRenderer',
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
REDIS_URL = "redis://%s:%s" % (REDIS_CONF["host"], REDIS_CONF["port"])
|
REDIS_URL = "redis://%s:%s" % (REDIS_CONF["host"], REDIS_CONF["port"])
|
||||||
@@ -207,13 +206,12 @@ def redis_config(db):
|
|||||||
"LOCATION": f"{REDIS_URL}/{db}",
|
"LOCATION": f"{REDIS_URL}/{db}",
|
||||||
"TIMEOUT": None,
|
"TIMEOUT": None,
|
||||||
"KEY_PREFIX": "",
|
"KEY_PREFIX": "",
|
||||||
"KEY_FUNCTION": make_key
|
"KEY_FUNCTION": make_key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if production_env:
|
if production_env:
|
||||||
CACHES = {
|
CACHES = {"default": redis_config(db=1)}
|
||||||
"default": redis_config(db=1)
|
|
||||||
}
|
|
||||||
|
|
||||||
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
|
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
|
||||||
SESSION_CACHE_ALIAS = "default"
|
SESSION_CACHE_ALIAS = "default"
|
||||||
@@ -230,8 +228,8 @@ DRAMATIQ_BROKER = {
|
|||||||
"dramatiq.middleware.Callbacks",
|
"dramatiq.middleware.Callbacks",
|
||||||
"dramatiq.middleware.Retries",
|
"dramatiq.middleware.Retries",
|
||||||
# "django_dramatiq.middleware.AdminMiddleware",
|
# "django_dramatiq.middleware.AdminMiddleware",
|
||||||
"django_dramatiq.middleware.DbConnectionsMiddleware"
|
"django_dramatiq.middleware.DbConnectionsMiddleware",
|
||||||
]
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
DRAMATIQ_RESULT_BACKEND = {
|
DRAMATIQ_RESULT_BACKEND = {
|
||||||
@@ -239,15 +237,13 @@ DRAMATIQ_RESULT_BACKEND = {
|
|||||||
"BACKEND_OPTIONS": {
|
"BACKEND_OPTIONS": {
|
||||||
"url": f"{REDIS_URL}/4",
|
"url": f"{REDIS_URL}/4",
|
||||||
},
|
},
|
||||||
"MIDDLEWARE_OPTIONS": {
|
"MIDDLEWARE_OPTIONS": {"result_ttl": None},
|
||||||
"result_ttl": None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RAVEN_CONFIG = {
|
RAVEN_CONFIG = {
|
||||||
'dsn': 'https://b200023b8aed4d708fb593c5e0a6ad3d:1fddaba168f84fcf97e0d549faaeaff0@sentry.io/263057'
|
"dsn": "https://b200023b8aed4d708fb593c5e0a6ad3d:1fddaba168f84fcf97e0d549faaeaff0@sentry.io/263057"
|
||||||
}
|
}
|
||||||
|
|
||||||
IP_HEADER = "HTTP_X_REAL_IP"
|
IP_HEADER = "HTTP_X_REAL_IP"
|
||||||
|
|
||||||
DEFAULT_AUTO_FIELD='django.db.models.AutoField'
|
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
from rest_framework import viewsets, permissions
|
from rest_framework import viewsets, permissions
|
||||||
from account.decorators import super_admin_required
|
|
||||||
from ..models import Tutorial
|
from ..models import Tutorial
|
||||||
from ..serializers import TutorialSerializer
|
from ..serializers import TutorialSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class IsSuperAdminUser(permissions.BasePermission):
|
||||||
|
def has_permission(self, request, view):
|
||||||
|
return bool(request.user and request.user.is_super_admin())
|
||||||
|
|
||||||
|
|
||||||
class AdminTutorialViewSet(viewsets.ModelViewSet):
|
class AdminTutorialViewSet(viewsets.ModelViewSet):
|
||||||
queryset = Tutorial.objects.all()
|
queryset = Tutorial.objects.all()
|
||||||
serializer_class = TutorialSerializer
|
serializer_class = TutorialSerializer
|
||||||
permission_classes = [permissions.IsAuthenticated]
|
permission_classes = [IsSuperAdminUser]
|
||||||
|
|
||||||
def get_permissions(self):
|
|
||||||
if self.action in ['create', 'update', 'partial_update', 'destroy']:
|
|
||||||
return [super_admin_required()]
|
|
||||||
return [permissions.AllowAny()]
|
|
||||||
|
|
||||||
def perform_create(self, serializer):
|
def perform_create(self, serializer):
|
||||||
serializer.save(created_by=self.request.user)
|
serializer.save(created_by=self.request.user)
|
||||||
Reference in New Issue
Block a user