From 61813e2d4f707fafda2689e8c05635478e32670a Mon Sep 17 00:00:00 2001 From: Gagan Deep Date: Sat, 3 Aug 2024 00:28:26 +0530 Subject: [PATCH] [feature] Added support for device deactivation #560 Closes #560 --- .github/workflows/ci.yml | 2 ++ openwisp_monitoring/device/admin.py | 21 ++++++++++++------- .../device/change_form.html | 2 +- .../device/wifisession_tabular.html | 0 .../device/tests/test_admin.py | 6 ++++-- openwisp_monitoring/tests/test_selenium.py | 2 ++ 6 files changed, 22 insertions(+), 11 deletions(-) rename openwisp_monitoring/device/templates/admin/{config => monitoring}/device/change_form.html (99%) rename openwisp_monitoring/device/templates/admin/{config => monitoring}/device/wifisession_tabular.html (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06393e1c4..5c190474d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,6 +65,8 @@ jobs: pip install -r requirements-test.txt pip install -U -I -e . pip uninstall -y django + pip install -U --force-reinstall --no-deps https://github.com/openwisp/openwisp-utils/tarball/extendable-submit-line + pip install -U --force-reinstall --no-deps https://github.com/openwisp/openwisp-controller/tarball/issues/625-device-deactivation pip install ${{ matrix.django-version }} sudo npm install -g jshint stylelint diff --git a/openwisp_monitoring/device/admin.py b/openwisp_monitoring/device/admin.py index baea8ce1c..f35aa00c1 100644 --- a/openwisp_monitoring/device/admin.py +++ b/openwisp_monitoring/device/admin.py @@ -22,6 +22,7 @@ from swapper import load_model from openwisp_controller.config.admin import DeviceAdmin as BaseDeviceAdmin +from openwisp_controller.config.admin import DeactivatedDeviceReadOnlyMixin from openwisp_users.multitenancy import MultitenantAdminMixin from openwisp_utils.admin import ReadOnlyAdmin @@ -61,27 +62,29 @@ class InlinePermissionMixin: def has_add_permission(self, request, obj=None): # User will be able to add objects from inline even # if it only has permission to add a model object - return super().has_add_permission(request, obj) or request.user.has_perm( + return super().has_add_permission(request, obj) and request.user.has_perm( f'{self.model._meta.app_label}.add_{self.inline_permission_suffix}' ) def has_change_permission(self, request, obj=None): - return super().has_change_permission(request, obj) or request.user.has_perm( + return super().has_change_permission(request, obj) and request.user.has_perm( f'{self.model._meta.app_label}.change_{self.inline_permission_suffix}' ) def has_view_permission(self, request, obj=None): - return super().has_view_permission(request, obj) or request.user.has_perm( + return super().has_view_permission(request, obj) and request.user.has_perm( f'{self.model._meta.app_label}.view_{self.inline_permission_suffix}' ) def has_delete_permission(self, request, obj=None): - return super().has_delete_permission(request, obj) or request.user.has_perm( + return super().has_delete_permission(request, obj) and request.user.has_perm( f'{self.model._meta.app_label}.delete_{self.inline_permission_suffix}' ) -class CheckInline(InlinePermissionMixin, GenericStackedInline): +class CheckInline( + InlinePermissionMixin, DeactivatedDeviceReadOnlyMixin, GenericStackedInline +): model = Check extra = 0 formset = CheckInlineFormSet @@ -152,7 +155,9 @@ def get_queryset(self, request): return super().get_queryset(request).order_by('created') -class MetricInline(InlinePermissionMixin, NestedGenericStackedInline): +class MetricInline( + InlinePermissionMixin, DeactivatedDeviceReadOnlyMixin, NestedGenericStackedInline +): model = Metric extra = 0 inlines = [AlertSettingsInline] @@ -205,7 +210,7 @@ def has_delete_permission(self, request, obj=None): class DeviceAdmin(BaseDeviceAdmin, NestedModelAdmin): - change_form_template = 'admin/config/device/change_form.html' + change_form_template = 'admin/monitoring/device/change_form.html' list_filter = ['monitoring__status'] + BaseDeviceAdmin.list_filter list_select_related = ['monitoring'] + list(BaseDeviceAdmin.list_select_related) list_display = list(BaseDeviceAdmin.list_display) @@ -415,7 +420,7 @@ class WiFiSessionInline(WifiSessionAdminHelperMixin, admin.TabularInline): readonly_fields = fields can_delete = False extra = 0 - template = 'admin/config/device/wifisession_tabular.html' + template = 'admin/monitoring/device/wifisession_tabular.html' class Media: css = {'all': ('monitoring/css/wifi-sessions.css',)} diff --git a/openwisp_monitoring/device/templates/admin/config/device/change_form.html b/openwisp_monitoring/device/templates/admin/monitoring/device/change_form.html similarity index 99% rename from openwisp_monitoring/device/templates/admin/config/device/change_form.html rename to openwisp_monitoring/device/templates/admin/monitoring/device/change_form.html index e85c63557..d1b71eca1 100644 --- a/openwisp_monitoring/device/templates/admin/config/device/change_form.html +++ b/openwisp_monitoring/device/templates/admin/monitoring/device/change_form.html @@ -1,4 +1,4 @@ -{% extends "admin/config/change_form.html" %} +{% extends "admin/config/device/change_form.html" %} {% load i18n static %} {% block after_field_sets %} {% if not add and device_data %} diff --git a/openwisp_monitoring/device/templates/admin/config/device/wifisession_tabular.html b/openwisp_monitoring/device/templates/admin/monitoring/device/wifisession_tabular.html similarity index 100% rename from openwisp_monitoring/device/templates/admin/config/device/wifisession_tabular.html rename to openwisp_monitoring/device/templates/admin/monitoring/device/wifisession_tabular.html diff --git a/openwisp_monitoring/device/tests/test_admin.py b/openwisp_monitoring/device/tests/test_admin.py index 721b24040..e32e035e1 100644 --- a/openwisp_monitoring/device/tests/test_admin.py +++ b/openwisp_monitoring/device/tests/test_admin.py @@ -572,11 +572,11 @@ def test_check_alertsetting_inline(self): self.client.force_login(test_user) def _add_device_permissions(user): - test_user.user_permissions.clear() + user.user_permissions.clear() self.assertEqual(user.user_permissions.count(), 0) device_permissions = Permission.objects.filter(codename__endswith='device') # Permissions required to access device page - test_user.user_permissions.add(*device_permissions), + user.user_permissions.add(*device_permissions), self.assertEqual(user.user_permissions.count(), 4) def _add_user_permissions(user, permission_query, expected_perm_count): @@ -989,6 +989,8 @@ def test_wifi_session_chart_on_index(self): def test_deleting_device_with_wifisessions(self): device_data = self._save_device_data() + device = Device.objects.first() + device.deactivate() path = reverse('admin:config_device_delete', args=[device_data.pk]) response = self.client.post(path, {'post': 'yes'}, follow=True) self.assertEqual(response.status_code, 200) diff --git a/openwisp_monitoring/tests/test_selenium.py b/openwisp_monitoring/tests/test_selenium.py index 8bab42117..9d9df9500 100644 --- a/openwisp_monitoring/tests/test_selenium.py +++ b/openwisp_monitoring/tests/test_selenium.py @@ -101,6 +101,8 @@ def test_restoring_deleted_device(self): self.fail('Failed saving device') # Delete the device + device.deactivate() + device.config.set_status_deactivated() self.open( reverse(f'admin:{self.config_app_label}_device_delete', args=[device.id]) )