import datetime import logging from django.forms.utils import to_current_timezone from django.utils.formats import get_format from django.utils.translation import gettext_lazy from rest_framework import serializers, ISO_8601 from rest_framework.serializers import * from core.models import ConsoleAuthSettings, TLSSettings _log = logging.getLogger(__name__) class AuthSettingsSerializer(serializers.ModelSerializer): class Meta: model = ConsoleAuthSettings fields = ('login_attempts_limit', 'login_block_timeout') class TLSSettingsSerializer(serializers.ModelSerializer): class Meta: model = TLSSettings fields = ["enabled", "certificate", "key"] extra_kwargs = { 'enabled': { 'required': True } } def validate(self, attrs): file_count = 0 if attrs.get("certificate", None): file_count += 1 if attrs.get("key", None): file_count += 1 _log.info(f"File count: {file_count}") attrs['file_count'] = file_count if attrs['enabled'] and file_count == 0 and (not self.instance.certificate.name or not self.instance.key.name): _log.error("No cert or key provided from model") raise ValidationError(gettext_lazy("No certificate or key provided")) if file_count == 1: _log.error("No cert or key provided from request") raise ValidationError(gettext_lazy("No certificate or key provided")) return attrs def to_representation(self, tls_settings: TLSSettings) -> OrderedDict: data = super(TLSSettingsSerializer, self).to_representation(tls_settings) if tls_settings.certificate: data['certificate'] = tls_settings.certificate.url if tls_settings.key: data['key'] = tls_settings.key.url return data class DateTimeLocalizedField(serializers.DateTimeField): def __init__(self, format=empty, input_formats=None, default_timezone=None, *args, unix=False, **kwargs): if unix: format, input_formats = '%s', ['%s'] else: if format is empty: format = get_format('DATETIME_INPUT_FORMATS')[0] if input_formats is None: input_formats = get_format('DATETIME_INPUT_FORMATS') input_formats.append(ISO_8601) # any locale support iso-8601 super().__init__(format, input_formats, default_timezone, *args, **kwargs) class DateLocalizedField(serializers.DateField): def __init__(self, format=empty, input_formats=None, *args, unix=False, **kwargs): if unix: format, input_formats = '%s', ['%s'] else: if format is empty: format = get_format('DATE_INPUT_FORMATS')[0] if input_formats is None: input_formats = get_format('DATE_INPUT_FORMATS') input_formats.append(ISO_8601) # any locale support iso-8601 super().__init__(format, input_formats, *args, **kwargs) class TimeLocalizedField(serializers.TimeField): def __init__(self, format=empty, input_formats=None, *args, **kwargs): if format is empty: format = '%H:%M' if input_formats is None: input_formats = get_format('TIME_INPUT_FORMATS') input_formats.append(ISO_8601) # any locale support iso-8601 super().__init__(format, input_formats, *args, **kwargs) class TimeLocalizedTzAwareField(TimeLocalizedField): @staticmethod def _replace_time(datetime_obj, time_obj): return datetime_obj.replace(hour=time_obj.hour, minute=time_obj.minute, second=time_obj.second, microsecond=time_obj.microsecond) def to_internal_value(self, value): t_tz_naive = super().to_internal_value(value) if isinstance(t_tz_naive, datetime.time): dt_tz_aware = TimeLocalizedTzAwareField._replace_time(timezone.localtime(), t_tz_naive) t_utc_naive = dt_tz_aware.astimezone().time() value = t_utc_naive return value def to_representation(self, value): t_utc_naive = value if isinstance(t_utc_naive, datetime.time): dt_utc_aware = TimeLocalizedTzAwareField._replace_time(timezone.now(), t_utc_naive) t_tz_naive = to_current_timezone(dt_utc_aware).time() value = t_tz_naive return super().to_representation(value) class ModelLocalizedSerializer(serializers.ModelSerializer): serializer_field_mapping = serializers.ModelSerializer.serializer_field_mapping.copy() serializer_field_mapping[models.DateField] = DateLocalizedField serializer_field_mapping[models.DateTimeField] = DateTimeLocalizedField serializer_field_mapping[models.TimeField] = TimeLocalizedTzAwareField