From 5558dfba30492e2f282584511bbf1004fa295666 Mon Sep 17 00:00:00 2001 From: Spitap Date: Fri, 3 Mar 2023 11:24:47 +0100 Subject: [PATCH] Fix review Co-Authored-By: Antoine Nguyen --- frontend/src/App.vue | 19 ++++++++++++---- frontend/src/components/alarms/AlarmList.vue | 7 +++--- frontend/src/constants.json | 1 + frontend/src/views/Login.vue | 2 +- modoboa/admin/api/v2/viewsets.py | 22 +++++++++++++++---- .../commands/subcommands/_manage_dkim_keys.py | 15 +++++-------- 6 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 frontend/src/constants.json diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 9d2d7bdda..a2603c62b 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -52,7 +52,7 @@ export default { created () { // this.$store.dispatch('auth/initialize') bus.$on('notification', this.showNotification) - bus.$on('logged', this.checkAlarms) + bus.$on('loggedIn', this.checkAlarms) }, mounted () { this.checkAlarms() @@ -66,7 +66,9 @@ export default { notificationColor: 'success', notificationTimeout: 2000, alarmNotified: [], - alarmChecker: null + alarmChecker: null, + lastAlarmDate: '', + alarmSleepTime: 10000 }), methods: { showNotification (options) { @@ -79,10 +81,19 @@ export default { checkAlarms () { if (this.isAuthenticated) { this.alarmChecker = window.setInterval(() => { - alarms.getAll({}).then(resp => { + const params = {} + if (this.lastAlarmDate instanceof Date) { + params.min_date = this.lastAlarmDate + } + alarms.getAll(params).then(resp => { let count = 0 for (const alarm of resp.data) { if (alarm.status === 1 && !this.alarmNotified.includes(alarm.id)) { + if (this.lastAlarmDate instanceof Date && new Date(alarm.created) > this.lastAlarmDate) { + this.lastAlarmDate = new Date(alarm.created) + } else if (!(this.lastAlarmDate instanceof Date)) { + this.lastAlarmDate = new Date(alarm.created) + } count++ this.alarmNotified.push(alarm.id) } @@ -91,7 +102,7 @@ export default { bus.$emit('notification', { msg: this.$gettext('You have one or more opened alarms'), type: 'error' }) } }) - }, 10000) + }, this.alarmSleepTime) } } } diff --git a/frontend/src/components/alarms/AlarmList.vue b/frontend/src/components/alarms/AlarmList.vue index 04cf2be73..dfda1b339 100644 --- a/frontend/src/components/alarms/AlarmList.vue +++ b/frontend/src/components/alarms/AlarmList.vue @@ -82,6 +82,7 @@ import { bus } from '@/main' import alarms from '@/api/alarms' import debounce from 'debounce' import MenuItems from '@/components/tools/MenuItems' +import constants from '@/constants.json' export default { components: { @@ -121,7 +122,7 @@ export default { } this.loading = true alarms.getAll(params).then(resp => { - this.alarms = resp.data.results + this.alarms = resp.data this.totalAlarms = resp.data.count this.loading = false }) @@ -135,13 +136,13 @@ export default { }) }, async closeAlarm (alarm) { - alarms.switchStatus(alarm.id, { status: 2 }).then(() => { + alarms.switchStatus(alarm.id, { status: constants.ALARM_CLOSED }).then(() => { bus.$emit('notification', { msg: this.$gettext('Alarm closed') }) this.fetchAlarms() }) }, async openAlarm (alarm) { - alarms.switchStatus(alarm.id, { status: 1 }).then(() => { + alarms.switchStatus(alarm.id, { status: constants.ALARM_OPENED }).then(() => { bus.$emit('notification', { msg: this.$gettext('Alarm re-opened') }) this.fetchAlarms() }) diff --git a/frontend/src/constants.json b/frontend/src/constants.json new file mode 100644 index 000000000..7f66341bd --- /dev/null +++ b/frontend/src/constants.json @@ -0,0 +1 @@ +{"ALARM_OPENED":1, "ALARM_CLOSED":2} diff --git a/frontend/src/views/Login.vue b/frontend/src/views/Login.vue index 1fc8b31a3..77a927dc0 100644 --- a/frontend/src/views/Login.vue +++ b/frontend/src/views/Login.vue @@ -87,7 +87,7 @@ export default { Cookies.set('token', resp.data.access, { sameSite: 'strict' }) Cookies.set('refreshToken', resp.data.refresh, { sameSite: 'strict' }) this.$store.dispatch('auth/initialize').then(() => { - bus.$emit('logged') + bus.$emit('loggedIn') this.$router.push({ name: 'DomainList' }) }) }).catch(err => { diff --git a/modoboa/admin/api/v2/viewsets.py b/modoboa/admin/api/v2/viewsets.py index 5c3da0f08..d3d5e4c04 100644 --- a/modoboa/admin/api/v2/viewsets.py +++ b/modoboa/admin/api/v2/viewsets.py @@ -326,13 +326,29 @@ class UserAccountViewSet(GetThrottleViewsetMixin, viewsets.ViewSet): return response.Response(serializer.validated_data) +class AlarmFilterSet(dj_filters.FilterSet): + """Custom FilterSet for Alarms.""" + + min_date = dj_filters.DateTimeFilter(method="filter_date") + + class Meta: + model = models.Alarm + fields = ["created"] + + def filter_date(self, queryset, name, value): + return queryset.filter(created__gt=value) + + class AlarmViewSet(GetThrottleViewsetMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet): """Viewset for Alarm.""" - filter_backends = (filters.OrderingFilter, filters.SearchFilter, ) + filter_backends = (filters.OrderingFilter, + filters.SearchFilter, + dj_filters.DjangoFilterBackend) + filterset_class = AlarmFilterSet ordering_fields = ["created", "status", "title"] pagination_class = pagination.PageNumberPagination permission_classes = ( @@ -349,9 +365,8 @@ class AlarmViewSet(GetThrottleViewsetMixin, @action(methods=["delete"], detail=True) def delete(self, request, **kwargs): - """Custom delete method that accepts body arguments.""" + """Allow admins to delete alarms.""" alarm = self.get_object() - domain = models.Domain.objects.get(pk=alarm.domain.pk) alarm.delete() return response.Response(status=status.HTTP_204_NO_CONTENT) @@ -361,7 +376,6 @@ class AlarmViewSet(GetThrottleViewsetMixin, alarm = self.get_object() serializer = serializers.AlarmSwitchStatusSerializer(data=request.data) serializer.is_valid(raise_exception=True) - domain = models.Domain.objects.get(pk=alarm.domain.pk) if serializer.data["status"] == constants.ALARM_CLOSED: alarm.close() else: diff --git a/modoboa/admin/management/commands/subcommands/_manage_dkim_keys.py b/modoboa/admin/management/commands/subcommands/_manage_dkim_keys.py index d929d01a9..1d125ed43 100644 --- a/modoboa/admin/management/commands/subcommands/_manage_dkim_keys.py +++ b/modoboa/admin/management/commands/subcommands/_manage_dkim_keys.py @@ -21,23 +21,18 @@ 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) + alarm_qset = domain.alarms.filter(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, + if not alarm_qset.exists(): + domain.alarms.create( title=_("DKIM path non-writable"), - internal_name=DKIM_WRITE_ERROR - ) - alarm.save() + internal_name=DKIM_WRITE_ERROR) else: alarm = alarm_qset.first() if alarm.status != ALARM_OPENED: alarm.reopen() return - elif alarm_qset: + elif alarm_qset.exists(): alarm_qset.first().close() key_size = ( domain.dkim_key_length if domain.dkim_key_length