mirror of
https://github.com/jwinterm/modoboa.git
synced 2026-10-28 06:28:43 +01:00
reworked alarms, added alarm on dkim issue
This commit is contained in:
@@ -225,6 +225,10 @@ class AdminGlobalParametersSerializer(serializers.Serializer):
|
||||
raise serializers.ValidationError(
|
||||
_("Directory not found.")
|
||||
)
|
||||
if not os.access(value, os.W_OK):
|
||||
raise serializers.ValidationError(
|
||||
_("Directory non-writable")
|
||||
)
|
||||
code, output = exec_cmd("which openssl")
|
||||
if code:
|
||||
raise serializers.ValidationError(
|
||||
@@ -588,3 +592,14 @@ class AlarmSerializer(serializers.ModelSerializer):
|
||||
depth = 1
|
||||
fields = "__all__"
|
||||
model = models.Alarm
|
||||
|
||||
|
||||
class AlarmSwitchStatusSerializer(serializers.Serializer):
|
||||
"""Serializer to switch the status of an Alarm."""
|
||||
|
||||
status = serializers.IntegerField()
|
||||
|
||||
def validate(self, data):
|
||||
if data["status"] not in [constants.ALARM_OPENED, constants.ALARM_CLOSED]:
|
||||
raise ValidationError(_("Unknown status"))
|
||||
return data
|
||||
|
||||
@@ -10,7 +10,7 @@ from rest_framework import (
|
||||
filters, mixins, parsers, pagination, permissions, response, status, viewsets
|
||||
)
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import PermissionDenied
|
||||
from rest_framework.exceptions import PermissionDenied, ValidationError
|
||||
|
||||
from modoboa.admin.api.v1 import viewsets as v1_viewsets
|
||||
from modoboa.core import models as core_models
|
||||
@@ -20,6 +20,7 @@ from modoboa.lib.throttle import GetThrottleViewsetMixin
|
||||
|
||||
from ... import lib
|
||||
from ... import models
|
||||
from ... import constants
|
||||
from . import serializers
|
||||
|
||||
|
||||
@@ -325,7 +326,10 @@ class UserAccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet):
|
||||
return response.Response(serializer.validated_data)
|
||||
|
||||
|
||||
class AlarmViewSet(GetThrottleViewsetMixin, viewsets.ReadOnlyModelViewSet):
|
||||
class AlarmViewSet(GetThrottleViewsetMixin,
|
||||
mixins.ListModelMixin,
|
||||
mixins.RetrieveModelMixin,
|
||||
viewsets.GenericViewSet):
|
||||
"""Viewset for Alarm."""
|
||||
|
||||
filter_backends = (filters.OrderingFilter, filters.SearchFilter, )
|
||||
@@ -342,3 +346,35 @@ class AlarmViewSet(GetThrottleViewsetMixin, viewsets.ReadOnlyModelViewSet):
|
||||
domain__in=models.Domain.objects.get_for_admin(
|
||||
self.request.user)
|
||||
).order_by("-created")
|
||||
|
||||
@action(methods=["delete"], detail=True)
|
||||
def delete(self, request, **kwargs):
|
||||
"""Custom delete method that accepts body arguments."""
|
||||
alarm = self.get_object()
|
||||
domain = models.Domain.objects.filter(pk=alarm.domain.pk)
|
||||
if not domain.exists():
|
||||
alarm.delete()
|
||||
if not request.user.can_access(domain):
|
||||
raise PermissionDenied(_("You don't have access to this domain"))
|
||||
else:
|
||||
alarm.delete()
|
||||
return response.Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@action(methods=['patch'], detail=True)
|
||||
def switch(self, request, **kwargs):
|
||||
"""Custom update method that switch status of an alarm."""
|
||||
alarm = self.get_object()
|
||||
serializer = serializers.AlarmSwitchStatusSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
domain = models.Domain.objects.filter(pk=alarm.domain.pk)
|
||||
if not domain.exists():
|
||||
alarm.delete()
|
||||
raise ValidationError(_("No alarm found"))
|
||||
if not request.user.can_access(domain):
|
||||
raise PermissionDenied(_("You don't have access to this domain"))
|
||||
else:
|
||||
if serializer.data["status"] == constants.ALARM_CLOSED:
|
||||
alarm.close()
|
||||
else:
|
||||
alarm.reopen()
|
||||
return response.Response(status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
@@ -35,6 +35,8 @@ DKIM_KEY_LENGTHS = [
|
||||
(4096, "4096"),
|
||||
]
|
||||
|
||||
DKIM_WRITE_ERROR = "DKIM path error"
|
||||
|
||||
ALARM_OPENED = 1
|
||||
ALARM_CLOSED = 2
|
||||
|
||||
|
||||
@@ -4,12 +4,14 @@ import os
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.utils.encoding import smart_text
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from modoboa.lib import sysutils
|
||||
from modoboa.parameters import tools as param_tools
|
||||
|
||||
from .... import models
|
||||
from .... import signals
|
||||
from ....constants import DKIM_WRITE_ERROR, ALARM_OPENED
|
||||
|
||||
|
||||
class ManageDKIMKeys(BaseCommand):
|
||||
@@ -19,6 +21,25 @@ class ManageDKIMKeys(BaseCommand):
|
||||
"""Create a new DKIM key."""
|
||||
storage_dir = param_tools.get_global_parameter("dkim_keys_storage_dir")
|
||||
pkey_path = os.path.join(storage_dir, "{}.pem".format(domain.name))
|
||||
alarm_qset = models.alarm.Alarm.objects.filter(
|
||||
domain=domain.pk,
|
||||
internal_name=DKIM_WRITE_ERROR)
|
||||
if not os.access(storage_dir, os.W_OK):
|
||||
if not alarm_qset:
|
||||
alarm = models.alarm.Alarm.objects.create(
|
||||
domain=domain,
|
||||
title=_("DKIM path non-writable"),
|
||||
internal_name=DKIM_WRITE_ERROR
|
||||
)
|
||||
alarm.save()
|
||||
else:
|
||||
alarm = alarm_qset.first()
|
||||
if alarm.status != ALARM_OPENED:
|
||||
alarm.status = ALARM_OPENED
|
||||
alarm.save()
|
||||
return
|
||||
elif alarm_qset:
|
||||
alarm_qset.first().close()
|
||||
key_size = (
|
||||
domain.dkim_key_length if domain.dkim_key_length
|
||||
else self.default_key_length)
|
||||
|
||||
@@ -51,5 +51,11 @@ class Alarm(models.Model):
|
||||
self.closed = timezone.now()
|
||||
self.save()
|
||||
|
||||
def reopen(self):
|
||||
"""Reopen this alarm."""
|
||||
self.status = constants.ALARM_OPENED
|
||||
self.closed = None
|
||||
self.save()
|
||||
|
||||
|
||||
reversion.register(Alarm)
|
||||
|
||||
Reference in New Issue
Block a user