From 70b696ec332d9135bba60de301fc0a41c12090e4 Mon Sep 17 00:00:00 2001 From: Philip Guyton Date: Fri, 8 Nov 2024 17:16:36 +0000 Subject: [PATCH] NFS exports restored as read-only - continued 4 #2912 - Enable previously dormant field validation via addition of: NFSExportGroup.clean_fields() prior to model.save(). Affects: host_str, modify_str, & sync_choice during post & put. - Additional tests to prove field validation function within current validation capability (need refinement). --- .../storageadmin/tests/test_nfs_export.py | 101 ++++++++++++++++++ .../storageadmin/views/nfs_exports.py | 2 + 2 files changed, 103 insertions(+) diff --git a/src/rockstor/storageadmin/tests/test_nfs_export.py b/src/rockstor/storageadmin/tests/test_nfs_export.py index 2f6903339..2bb7ff807 100644 --- a/src/rockstor/storageadmin/tests/test_nfs_export.py +++ b/src/rockstor/storageadmin/tests/test_nfs_export.py @@ -157,6 +157,107 @@ def test_no_nfs_client(self): self.assertEqual(response.status_code, status.HTTP_200_OK, msg=response.data) self.assertEqual(response.data["host_str"], "*") + def test_mod_choice_validator_post(self): + # DB validator should restrict to "ro" or "rw": validate_nfs_modify_str() & model choices + data = { + "shares": ("share2",), + "mod_choice": "rr", + "sync_choice": "async", + } + response = self.client.post(self.BASE_URL, data=data) + self.assertEqual( + response.status_code, + status.HTTP_500_INTERNAL_SERVER_ERROR, + msg=response.data, + ) + e_msg = {'editable': ["Value 'rr' is not a valid choice."]} + self.assertEqual(response.data[0], str(e_msg)) + + def test_mod_choice_validator_put(self): + # DB validator should restrict to "ro" or "rw": validate_nfs_modify_str() & model choices + data = { + "shares": ("share-nfs",), + "mod_choice": "rr", + "sync_choice": "async", + } + nfs_id = 3 # from fixture + response = self.client.put(f"{self.BASE_URL}/{nfs_id}", data=data) + self.assertEqual( + response.status_code, + status.HTTP_500_INTERNAL_SERVER_ERROR, + msg=response.data, + ) + e_msg = {'editable': ["Value 'rr' is not a valid choice."]} + self.assertEqual(response.data[0], str(e_msg)) + + def test_sync_choice_validator_post(self): + # DB validator should restrict to "async" or "sync": validate_nfs_sync_choice() & model choices + data = { + "shares": ("share2",), + "mod_choice": "ro", + "sync_choice": "aaaaa", + } + response = self.client.post(self.BASE_URL, data=data) + self.assertEqual( + response.status_code, + status.HTTP_500_INTERNAL_SERVER_ERROR, + msg=response.data, + ) + e_msg = {'syncable': ["Value 'aaaaa' is not a valid choice."]} + self.assertEqual(response.data[0], str(e_msg)) + + def test_sync_choice_validator_put(self): + # DB validator should restrict to "async" or "sync": validate_nfs_sync_choice() & model choices + data = { + "shares": ("share-nfs",), + "mod_choice": "ro", + "sync_choice": "aaaaa", + } + nfs_id = 3 # from fixture + response = self.client.put(f"{self.BASE_URL}/{nfs_id}", data=data) + self.assertEqual( + response.status_code, + status.HTTP_500_INTERNAL_SERVER_ERROR, + msg=response.data, + ) + e_msg = {'syncable': ["Value 'aaaaa' is not a valid choice."]} + self.assertEqual(response.data[0], str(e_msg)) + + def test_host_str_validator_post(self): + # DB validator should restrict to valid entry: validate_nfs_host_str + data = { + "shares": ("share2",), + "host_str": "1.!", + "mod_choice": "ro", + "sync_choice": "async", + } + response = self.client.post(self.BASE_URL, data=data) + self.assertEqual( + response.status_code, + status.HTTP_500_INTERNAL_SERVER_ERROR, + msg=response.data, + ) + e_msg = {'host_str': ['Invalid host string: 1.!']} + self.assertEqual(response.data[0], str(e_msg)) + + def test_host_str_validator_put(self): + # DB validator should restrict to valid entry: validate_nfs_host_str + data = { + "shares": ("share-nfs",), + "host_str": "ted fred", + "mod_choice": "ro", + "sync_choice": "async", + } + nfs_id = 3 # from fixture + response = self.client.put(f"{self.BASE_URL}/{nfs_id}", data=data) + self.assertEqual( + response.status_code, + status.HTTP_500_INTERNAL_SERVER_ERROR, + msg=response.data, + ) + e_msg = {'host_str': ['Invalid host string: ted fred']} + self.assertEqual(response.data[0], str(e_msg)) + def test_share_already_exported(self): # Add NFS export for share already exported data = { diff --git a/src/rockstor/storageadmin/views/nfs_exports.py b/src/rockstor/storageadmin/views/nfs_exports.py index 38171bbc8..2d94a1aa1 100644 --- a/src/rockstor/storageadmin/views/nfs_exports.py +++ b/src/rockstor/storageadmin/views/nfs_exports.py @@ -170,6 +170,7 @@ def post(self, request): cur_exports = list(NFSExport.objects.all()) eg = NFSExportGroup(**options) + eg.clean_fields(exclude="admin_host") eg.save() for s in shares: mnt_pt = "%s%s" % (settings.MNT_PT, s.name) @@ -237,6 +238,7 @@ def put(self, request, export_id): s, options["host_str"], request, export_id=int(export_id) ) NFSExportGroup.objects.filter(id=export_id).update(**options) + NFSExportGroup.objects.filter(id=export_id)[0].clean_fields(exclude="admin_host") NFSExportGroup.objects.filter(id=export_id)[0].save() cur_exports = list(NFSExport.objects.all()) for e in NFSExport.objects.filter(export_group=eg):