2024-08-29 12:36:35 -06:00
|
|
|
import gzip
|
|
|
|
|
import json
|
2024-07-31 13:12:56 -03:00
|
|
|
import logging
|
2024-08-26 13:12:18 -06:00
|
|
|
from dataclasses import asdict, is_dataclass
|
2024-07-31 13:12:56 -03:00
|
|
|
|
|
|
|
|
from django.conf import settings
|
|
|
|
|
from rest_framework import status
|
|
|
|
|
from rest_framework.request import Request
|
|
|
|
|
from rest_framework.response import Response
|
|
|
|
|
from rest_framework.views import APIView
|
|
|
|
|
|
2024-08-16 18:43:52 +02:00
|
|
|
from apps.auth_token.auth import BasePluginAuthentication
|
2024-07-31 13:12:56 -03:00
|
|
|
from apps.grafana_plugin.serializers.sync_data import SyncDataSerializer
|
|
|
|
|
from apps.user_management.models import Organization
|
|
|
|
|
from apps.user_management.sync import apply_sync_data, get_or_create_organization
|
|
|
|
|
from common.api_helpers.errors import INVALID_SELF_HOSTED_ID
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SyncException(Exception):
|
|
|
|
|
def __init__(self, error_data):
|
|
|
|
|
self.error_data = error_data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class SyncV2View(APIView):
|
2024-08-16 18:43:52 +02:00
|
|
|
authentication_classes = (BasePluginAuthentication,)
|
2024-07-31 13:12:56 -03:00
|
|
|
|
|
|
|
|
def do_sync(self, request: Request) -> Organization:
|
2024-08-29 12:36:35 -06:00
|
|
|
if request.headers.get("Content-Encoding") == "gzip":
|
|
|
|
|
gzip_data = gzip.GzipFile(fileobj=request).read()
|
|
|
|
|
decoded_data = gzip_data.decode("utf-8")
|
|
|
|
|
data = json.loads(decoded_data)
|
|
|
|
|
else:
|
|
|
|
|
data = request.data
|
|
|
|
|
|
|
|
|
|
serializer = SyncDataSerializer(data=data)
|
2024-07-31 13:12:56 -03:00
|
|
|
if not serializer.is_valid():
|
|
|
|
|
raise SyncException(serializer.errors)
|
|
|
|
|
|
|
|
|
|
sync_data = serializer.save()
|
|
|
|
|
|
|
|
|
|
if settings.LICENSE == settings.OPEN_SOURCE_LICENSE_NAME:
|
|
|
|
|
stack_id = settings.SELF_HOSTED_SETTINGS["STACK_ID"]
|
|
|
|
|
org_id = settings.SELF_HOSTED_SETTINGS["ORG_ID"]
|
|
|
|
|
else:
|
2024-08-16 18:43:52 +02:00
|
|
|
org_id = request.auth.organization.org_id
|
2024-07-31 13:12:56 -03:00
|
|
|
stack_id = request.auth.organization.stack_id
|
|
|
|
|
|
|
|
|
|
if sync_data.settings.org_id != org_id or sync_data.settings.stack_id != stack_id:
|
|
|
|
|
raise SyncException(INVALID_SELF_HOSTED_ID)
|
|
|
|
|
|
|
|
|
|
organization = get_or_create_organization(sync_data.settings.org_id, sync_data.settings.stack_id, sync_data)
|
|
|
|
|
apply_sync_data(organization, sync_data)
|
|
|
|
|
return organization
|
|
|
|
|
|
|
|
|
|
def post(self, request: Request) -> Response:
|
|
|
|
|
try:
|
|
|
|
|
self.do_sync(request)
|
|
|
|
|
except SyncException as e:
|
2024-08-26 13:12:18 -06:00
|
|
|
return Response(
|
|
|
|
|
data=asdict(e.error_data) if is_dataclass(e.error_data) else e.error_data,
|
|
|
|
|
status=status.HTTP_400_BAD_REQUEST,
|
|
|
|
|
)
|
2024-07-31 13:12:56 -03:00
|
|
|
|
|
|
|
|
return Response(status=status.HTTP_200_OK)
|