106 lines
3.5 KiB
Python
106 lines
3.5 KiB
Python
# Create your views here.
|
|
|
|
import requests
|
|
import structlog
|
|
from django.conf import settings
|
|
from django.contrib.auth import authenticate, login
|
|
from django.core.management import call_command
|
|
from django.http import JsonResponse, HttpResponse, HttpResponseRedirect
|
|
from django.shortcuts import render
|
|
from django.template import loader
|
|
from django.views.decorators.csrf import ensure_csrf_cookie
|
|
from ratelimit.decorators import ratelimit
|
|
from rest_framework import authentication
|
|
from rest_framework.decorators import api_view, authentication_classes, permission_classes
|
|
from rest_framework.permissions import IsAdminUser
|
|
from rest_framework.response import Response
|
|
|
|
from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
|
|
from vbv_lernwelt.core.serializers import UserSerializer
|
|
|
|
logger = structlog.get_logger(__name__)
|
|
|
|
|
|
@django_view_authentication_exempt
|
|
@ensure_csrf_cookie
|
|
def vue_home(request):
|
|
if settings.IT_SERVE_VUE:
|
|
try:
|
|
res = requests.get(f'{settings.IT_SERVE_VUE_URL}{request.get_full_path()}')
|
|
content = res.text
|
|
content = content.replace('https://vbv-lernwelt.control.iterativ.ch/static/', '/static/')
|
|
headers = res.headers
|
|
content_type = headers.get('content-type', 'text/html')
|
|
return HttpResponse(content, content_type=content_type)
|
|
except Exception as e:
|
|
return HttpResponse(
|
|
f'Can not connect to vue dev server at {settings.IT_SERVE_VUE_URL}: {e}'
|
|
)
|
|
|
|
# render index.html from `npm run build`
|
|
content = loader.render_to_string('vue/index.html', context={}, request=request)
|
|
content = content.replace('https://vbv-lernwelt.control.iterativ.ch/static/', '/static/')
|
|
return HttpResponse(content)
|
|
|
|
|
|
@api_view(['POST'])
|
|
@ensure_csrf_cookie
|
|
def vue_login(request):
|
|
try:
|
|
username = request.data.get('username')
|
|
password = request.data.get('password')
|
|
if username and password:
|
|
user = authenticate(request, username=username, password=password)
|
|
if user:
|
|
login(request, user)
|
|
logger.debug('login successful', username=username, email=user.email, label='login')
|
|
return Response(UserSerializer(user).data)
|
|
except Exception as e:
|
|
logger.exception(e)
|
|
|
|
logger.debug('login failed', username=username, label='login')
|
|
return Response({'success': False}, status=401)
|
|
|
|
|
|
@api_view(['GET'])
|
|
def me_user_view(request):
|
|
if request.user.is_authenticated:
|
|
return Response(UserSerializer(request.user).data)
|
|
return Response(status=403)
|
|
|
|
|
|
def permission_denied_view(request, exception):
|
|
return render(request, "403.html", status=403)
|
|
|
|
|
|
def rate_limit_exceeded_view(request, exception):
|
|
return render(request, "429.html", status=429)
|
|
|
|
|
|
@django_view_authentication_exempt
|
|
def server_json_error(request, *args, **kwargs):
|
|
"""
|
|
Generic 500 error handler.
|
|
"""
|
|
data = {
|
|
"detail": "Server Error (500)",
|
|
"status_code": 500,
|
|
}
|
|
return JsonResponse(data, status=500)
|
|
|
|
|
|
@ratelimit(key="ip", rate="5/m", block=True)
|
|
@django_view_authentication_exempt
|
|
def check_rate_limit(request):
|
|
return HttpResponse(content=b"Hello")
|
|
|
|
|
|
@api_view(['POST'])
|
|
@authentication_classes((authentication.SessionAuthentication,))
|
|
@permission_classes((IsAdminUser,))
|
|
def cypress_reset_view(request):
|
|
if settings.APP_ENVIRONMENT != 'production':
|
|
call_command('cypress_reset')
|
|
|
|
return HttpResponseRedirect('/admin/')
|