|
7 | 7 |
|
8 | 8 | from openwisp_controller.config.api.serializers import BaseConfigSerializer |
9 | 9 | from openwisp_controller.tests.utils import TestAdminMixin |
10 | | -from openwisp_users.tests.test_api import AuthenticationMixin |
| 10 | +from openwisp_users.tests.test_api import AuthenticationMixin, TestMultitenantApiMixin |
11 | 11 | from openwisp_utils.tests import capture_any_output, catch_signal |
12 | 12 |
|
13 | 13 | from .. import settings as app_settings |
|
30 | 30 | OrganizationUser = load_model("openwisp_users", "OrganizationUser") |
31 | 31 |
|
32 | 32 |
|
33 | | -class ApiTestMixin: |
| 33 | +class ApiTestMixin(AuthenticationMixin, TestMultitenantApiMixin): |
34 | 34 | @property |
35 | 35 | def _template_data(self): |
36 | 36 | return { |
@@ -100,7 +100,6 @@ class TestConfigApi( |
100 | 100 | CreateConfigTemplateMixin, |
101 | 101 | TestVpnX509Mixin, |
102 | 102 | CreateDeviceGroupMixin, |
103 | | - AuthenticationMixin, |
104 | 103 | TestCase, |
105 | 104 | ): |
106 | 105 | def setUp(self): |
@@ -648,29 +647,59 @@ def test_template_create_of_vpn_type(self): |
648 | 647 | self.assertEqual(Template.objects.count(), 1) |
649 | 648 | self.assertEqual(r.status_code, 201) |
650 | 649 |
|
651 | | - def test_template_create_with_shared_vpn(self): |
652 | | - org1 = self._get_org() |
653 | | - test_user = self._create_operator(organizations=[org1]) |
654 | | - self.client.force_login(test_user) |
655 | | - vpn1 = self._create_vpn(name="vpn1", organization=None) |
656 | | - path = reverse("config_api:template_list") |
657 | | - data = self._template_data |
658 | | - data["type"] = "vpn" |
659 | | - data["vpn"] = vpn1.id |
660 | | - data["organization"] = org1.pk |
661 | | - r = self.client.post(path, data, content_type="application/json") |
662 | | - self.assertEqual(r.status_code, 201) |
663 | | - self.assertEqual(Template.objects.count(), 1) |
664 | | - self.assertEqual(r.data["vpn"], vpn1.id) |
665 | | - |
666 | | - def test_template_creation_with_no_org_by_operator(self): |
667 | | - path = reverse("config_api:template_list") |
668 | | - data = self._template_data |
| 650 | + def test_operator_access_shared_template(self): |
669 | 651 | test_user = self._create_operator(organizations=[self._get_org()]) |
670 | | - self.client.force_login(test_user) |
671 | | - r = self.client.post(path, data, content_type="application/json") |
672 | | - self.assertEqual(r.status_code, 400) |
673 | | - self.assertIn("This field may not be null.", str(r.content)) |
| 652 | + token = self._obtain_auth_token(test_user) |
| 653 | + self._create_template(organization=None) |
| 654 | + self._test_org_user_access_shared_object( |
| 655 | + listview_name='config_api:template_list', |
| 656 | + detailview_name='config_api:template_detail', |
| 657 | + create_payload={'name': 'test', 'organization': ''}, |
| 658 | + update_payload={'name': 'updated-test'}, |
| 659 | + expected_count=1, |
| 660 | + token=token, |
| 661 | + expected_status_codes={ |
| 662 | + 'create': 400, |
| 663 | + 'list': 200, |
| 664 | + 'retrieve': 403, |
| 665 | + 'update': 403, |
| 666 | + 'delete': 403, |
| 667 | + 'head': 403, |
| 668 | + 'option': 200, |
| 669 | + }, |
| 670 | + ) |
| 671 | + |
| 672 | + def test_org_admin_create_template_with_shared_vpn(self): |
| 673 | + org = self._get_org() |
| 674 | + vpn = self._create_vpn(organization=None) |
| 675 | + create_payload = self._template_data |
| 676 | + create_payload.update( |
| 677 | + { |
| 678 | + 'organization': org.pk, |
| 679 | + 'type': 'vpn', |
| 680 | + 'vpn': vpn.pk, |
| 681 | + } |
| 682 | + ) |
| 683 | + update_payload = create_payload.copy() |
| 684 | + update_payload['name'] = 'updated-test' |
| 685 | + test_user = self._create_operator(organizations=[org]) |
| 686 | + self._test_org_user_access_shared_object( |
| 687 | + listview_name='config_api:template_list', |
| 688 | + detailview_name='config_api:template_detail', |
| 689 | + create_payload=create_payload, |
| 690 | + update_payload=update_payload, |
| 691 | + expected_count=1, |
| 692 | + expected_status_codes={ |
| 693 | + 'create': 201, |
| 694 | + 'list': 200, |
| 695 | + 'retrieve': 200, |
| 696 | + 'update': 200, |
| 697 | + 'delete': 204, |
| 698 | + 'head': 403, |
| 699 | + 'option': 200, |
| 700 | + }, |
| 701 | + token=self._obtain_auth_token(test_user), |
| 702 | + ) |
674 | 703 |
|
675 | 704 | def test_template_create_with_empty_config(self): |
676 | 705 | path = reverse("config_api:template_list") |
@@ -832,19 +861,50 @@ def test_vpn_create_api(self): |
832 | 861 | self.assertEqual(r.status_code, 201) |
833 | 862 | self.assertEqual(Vpn.objects.count(), 1) |
834 | 863 |
|
835 | | - def test_vpn_create_with_shared_objects(self): |
836 | | - org1 = self._get_org() |
837 | | - shared_ca = self._create_ca(name="shared_ca", organization=None) |
838 | | - test_user = self._create_administrator(organizations=[org1]) |
839 | | - self.client.force_login(test_user) |
| 864 | + def test_org_admin_access_vpn_with_shared_objects(self): |
| 865 | + org = self._get_org() |
| 866 | + shared_ca = self._create_ca(name='shared_ca', organization=None) |
| 867 | + create_payload = self._vpn_data |
| 868 | + create_payload.update( |
| 869 | + { |
| 870 | + 'organization': org.pk, |
| 871 | + 'ca': shared_ca.pk, |
| 872 | + } |
| 873 | + ) |
| 874 | + update_payload = create_payload.copy() |
| 875 | + update_payload['name'] = 'updated-test-vpn' |
| 876 | + administrator = self._create_administrator(organizations=[org]) |
| 877 | + self._test_access_shared_object( |
| 878 | + listview_name='config_api:vpn_list', |
| 879 | + detailview_name='config_api:vpn_detail', |
| 880 | + create_payload=create_payload, |
| 881 | + update_payload=update_payload, |
| 882 | + expected_count=1, |
| 883 | + expected_status_codes={ |
| 884 | + 'create': 201, |
| 885 | + 'list': 200, |
| 886 | + 'retrieve': 200, |
| 887 | + 'update': 200, |
| 888 | + 'delete': 204, |
| 889 | + 'head': 200, |
| 890 | + 'option': 200, |
| 891 | + }, |
| 892 | + token=self._obtain_auth_token(administrator), |
| 893 | + ) |
| 894 | + |
| 895 | + def test_org_admin_create_shared_vpn(self): |
| 896 | + shared_ca = self._create_ca(name='shared_ca', organization=None) |
840 | 897 | data = self._vpn_data |
841 | | - data["organization"] = org1.pk |
842 | | - data["ca"] = shared_ca.pk |
843 | | - path = reverse("config_api:vpn_list") |
844 | | - r = self.client.post(path, data, content_type="application/json") |
845 | | - self.assertEqual(Vpn.objects.count(), 1) |
846 | | - self.assertEqual(r.status_code, 201) |
847 | | - self.assertEqual(r.data["ca"], shared_ca.pk) |
| 898 | + data['ca'] = shared_ca.pk |
| 899 | + # API does not allow creating shared VPN by org admin, |
| 900 | + # therefore we create an object to test the detail view. |
| 901 | + self._create_vpn(organization=None, ca=shared_ca) |
| 902 | + self._test_org_user_access_shared_object( |
| 903 | + listview_name='config_api:vpn_list', |
| 904 | + detailview_name='config_api:vpn_detail', |
| 905 | + create_payload=data, |
| 906 | + expected_count=1, |
| 907 | + ) |
848 | 908 |
|
849 | 909 | def test_vpn_list_api(self): |
850 | 910 | org = self._get_org() |
|
0 commit comments