# Create your views here. import requests import structlog from django.conf import settings from django.contrib.auth import authenticate, login, logout 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): if settings.ALLOW_LOCAL_LOGIN: 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) else: return Response({'success': False, 'message': 'ALLOW_LOCAL_LOGIN=false'}, status=403) @api_view(['GET']) def me_user_view(request): if request.user.is_authenticated: return Response(UserSerializer(request.user).data) return Response(status=403) @api_view(['POST']) def vue_logout(request): logout(request) return Response({'success': True}, 200) 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/')