import logging import os from django.conf import settings from rest_framework.generics import RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView, CreateAPIView from rest_framework.response import Response from rest_framework.views import APIView from core import constants from core.mixins import ApiPermissionCheckMixin from core.models import ConsoleAuthSettings, TLSSettings from core.serializers import AuthSettingsSerializer, TLSSettingsSerializer from core.services.tls_settings import handle_uploaded_file, update_nginx, remove_ssl_certificate, restart_nginx, \ update_model, create_cert from perms.models import Perm _log = logging.getLogger(__name__) class AuthSettingsAPIView(ApiPermissionCheckMixin, RetrieveUpdateAPIView): console_permissions = [Perm.can_view_system_settings] serializer_class = AuthSettingsSerializer def get_object(self): auth_settings = ConsoleAuthSettings.get_solo() return auth_settings class Meta: model = ConsoleAuthSettings class TLSSettingsAPIView(ApiPermissionCheckMixin, RetrieveUpdateDestroyAPIView, CreateAPIView): console_permissions = [Perm.can_view_system_settings] serializer_class = TLSSettingsSerializer def get_object(self): tls_settings = TLSSettings.get_solo() return tls_settings def create(self, request, *args, **kwargs): """ Generate new TLS certificate and save to MEDIA_ROOT """ tls_settings = self.get_object() create_cert(tls_settings) tls_settings.save() data = self.serializer_class(tls_settings).data return Response(data) def retrieve(self, request, *args, **kwargs): tls_settings = self.get_object() if os.path.exists(os.path.join(settings.MEDIA_ROOT, constants.DEFAULT_CERT_FILENAME)) and \ os.path.exists(os.path.join(settings.MEDIA_ROOT, constants.DEFAULT_KEY_FILENAME)): tls_settings.certificate.name = constants.DEFAULT_CERT_FILENAME tls_settings.key.name = constants.DEFAULT_KEY_FILENAME tls_settings.save() serializer = self.get_serializer(instance=tls_settings) return Response(serializer.data) def update(self, request, *args, **kwargs): tls_settings = self.get_object() serializer = self.get_serializer(instance=tls_settings, data=request.data) serializer.is_valid(raise_exception=True) tls_settings.enabled = serializer.validated_data["enabled"] _log.info("Processing upload files") if serializer.validated_data['file_count'] == 2: handle_uploaded_file(serializer.validated_data.get("certificate", None), os.path.join(settings.MEDIA_ROOT, constants.DEFAULT_CERT_FILENAME)) handle_uploaded_file(serializer.validated_data.get("key", None), os.path.join(settings.MEDIA_ROOT, constants.DEFAULT_KEY_FILENAME)) update_model(tls_settings) _log.info(f"User [{request.user}] set HTTPS enabled to [{serializer.validated_data['enabled']}]") update_nginx(serializer.validated_data["enabled"]) restart_nginx() tls_settings.save() tls_settings.clear_cache() return Response(serializer.data) def destroy(self, request, *args, **kwargs): remove_ssl_certificate() update_nginx(False) restart_nginx() _log.info(f"User [{request.user}] set HTTPS enabled to false") return Response() class ProductVersionView(APIView): """Product version API""" def get(self, request): return Response(settings.PRODUCT_VERSION)