test for csrf

This commit is contained in:
2025-06-15 10:42:28 +08:00
parent c655ba6991
commit d4409ab595
5 changed files with 134 additions and 118 deletions

View File

@@ -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)
)

View File

@@ -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"

View File

@@ -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"

View File

@@ -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"

View File

@@ -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)