from django.contrib.auth import logout from django.db import connections from django.db.utils import OperationalError from django.shortcuts import get_object_or_404, redirect from rest_framework import views, viewsets from rest_framework.permissions import AllowAny from rest_framework.authentication import TokenAuthentication from rest_framework.response import Response from rest_framework import status from . import serializers, models as frontend_models from .. import models class OperationalView(views.APIView): authentication_classes = [] permission_classes = (AllowAny,) def get(self, request, format=None): try: db_conn = connections['default'] db_conn.cursor() # we check if we can access the state request.session except OperationalError: op = False else: op = True response = {'operational': op} return Response(response) class LogoutView(views.APIView): def post(self, request, format=None): logout(request) return redirect('/backend/api/state/') class StateView(views.APIView): permission_classes = (AllowAny,) def get(self, request, format=None): response = { 'logged_in': request.user.is_authenticated() } if request.user.is_authenticated(): response['user'] = serializers.UserSerializer(request.user).data response['state'] = serializers.StateSerializer( frontend_models.State(request.user)).data return Response(response) class ServiceViewSet(viewsets.ModelViewSet): serializer_class = serializers.ServiceSerializer queryset = models.Service.objects.all() class SSHPublicKeyView(views.APIView): def post(self, request, format=None): if 'type' not in request.data: return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST) request_type = request.data['type'] if request_type == 'remove': if 'name' in request.data: key = get_object_or_404( models.SSHPublicKey, name=request.data['name']) key.delete() return redirect('/backend/api/state/') elif request_type == 'add': if 'key' in request.data: key = models.SSHPublicKey( user=request.user, name=request.data['key']['name'], key=request.data['key']['key'], ) key.save() return redirect('/backend/api/state/') return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST) class DeploymentView(views.APIView): def post(self, request, format=None): if ( 'type' not in request.data or 'key' not in request.data or 'service' not in request.data ): return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST) request_type = request.data['type'] request_service = get_object_or_404( models.Service, name=request.data['service']) request_key = get_object_or_404( models.SSHPublicKey, name=request.data['key']) # check if there is already an deployment try: deployment = request.user.deployments.get(service=request_service) except Exception: if request_type == 'remove': return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST) deployment = models.Deployment( user=request.user, service=request_service) deployment.save() if request_type == 'add': deployment.ssh_keys.add(request_key) deployment.save() return redirect('/backend/api/state/') elif request_type == 'remove': deployment.ssh_keys.remove(request_key) deployment.save() return redirect('/backend/api/state/') return Response({'ok': False}, status=status.HTTP_400_BAD_REQUEST) class ClientViewSet(viewsets.ModelViewSet): authentication_classes = (TokenAuthentication,) serializer_class = serializers.ClientViewSerializer def get_queryset(self): # services of this client services = self.request.user.site.services.all() deployments = {} for service in services: deployments[service.name] = [] for deployment in service.deployments.all(): deployments[service.name].append( serializers.UserSerializer(deployment.user).data ) c = models.ClientView() c.deployments = deployments return [c]