From bbb7ef8aaf5bb4a2d6e432090f391ee883d71ac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=B4mulo=20Penido?= Date: Mon, 16 Oct 2023 16:30:52 -0300 Subject: [PATCH] feat: override permissions for exporting a taxonomy (#33483) --- .../rest_api/v1/tests/test_views.py | 126 +++++++++--------- .../core/djangoapps/content_tagging/rules.py | 1 + requirements/constraints.txt | 2 +- requirements/edx/base.txt | 2 +- requirements/edx/development.txt | 2 +- requirements/edx/doc.txt | 2 +- requirements/edx/testing.txt | 2 +- 7 files changed, 69 insertions(+), 68 deletions(-) diff --git a/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py b/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py index 5849f4e830..1389c2762e 100644 --- a/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py +++ b/openedx/core/djangoapps/content_tagging/rest_api/v1/tests/test_views.py @@ -270,18 +270,18 @@ class TestTaxonomyViewSet(TestTaxonomyObjectsMixin, APITestCase): assert response.status_code == status.HTTP_404_NOT_FOUND @ddt.data( - (None, "ot1", status.HTTP_403_FORBIDDEN), - (None, "ot2", status.HTTP_403_FORBIDDEN), - (None, "st1", status.HTTP_403_FORBIDDEN), - (None, "st2", status.HTTP_403_FORBIDDEN), - (None, "t1", status.HTTP_403_FORBIDDEN), - (None, "t2", status.HTTP_403_FORBIDDEN), - (None, "tA1", status.HTTP_403_FORBIDDEN), - (None, "tA2", status.HTTP_403_FORBIDDEN), - (None, "tB1", status.HTTP_403_FORBIDDEN), - (None, "tB2", status.HTTP_403_FORBIDDEN), - (None, "tC1", status.HTTP_403_FORBIDDEN), - (None, "tC2", status.HTTP_403_FORBIDDEN), + (None, "ot1", status.HTTP_401_UNAUTHORIZED), + (None, "ot2", status.HTTP_401_UNAUTHORIZED), + (None, "st1", status.HTTP_401_UNAUTHORIZED), + (None, "st2", status.HTTP_401_UNAUTHORIZED), + (None, "t1", status.HTTP_401_UNAUTHORIZED), + (None, "t2", status.HTTP_401_UNAUTHORIZED), + (None, "tA1", status.HTTP_401_UNAUTHORIZED), + (None, "tA2", status.HTTP_401_UNAUTHORIZED), + (None, "tB1", status.HTTP_401_UNAUTHORIZED), + (None, "tB2", status.HTTP_401_UNAUTHORIZED), + (None, "tC1", status.HTTP_401_UNAUTHORIZED), + (None, "tC2", status.HTTP_401_UNAUTHORIZED), ("user", "ot1", status.HTTP_200_OK), ("user", "ot2", status.HTTP_404_NOT_FOUND), ("user", "st1", status.HTTP_200_OK), @@ -336,7 +336,7 @@ class TestTaxonomyViewSet(TestTaxonomyObjectsMixin, APITestCase): check_taxonomy(response.data, taxonomy.pk, **(TaxonomySerializer(taxonomy.cast()).data)) @ddt.data( - (None, status.HTTP_403_FORBIDDEN), + (None, status.HTTP_401_UNAUTHORIZED), ("user", status.HTTP_403_FORBIDDEN), ("userA", status.HTTP_403_FORBIDDEN), ("userS", status.HTTP_201_CREATED), @@ -368,18 +368,18 @@ class TestTaxonomyViewSet(TestTaxonomyObjectsMixin, APITestCase): check_taxonomy(response.data, response.data["id"], **create_data) @ddt.data( - (None, "ot1", status.HTTP_403_FORBIDDEN), - (None, "ot2", status.HTTP_403_FORBIDDEN), - (None, "st1", status.HTTP_403_FORBIDDEN), - (None, "st2", status.HTTP_403_FORBIDDEN), - (None, "t1", status.HTTP_403_FORBIDDEN), - (None, "t2", status.HTTP_403_FORBIDDEN), - (None, "tA1", status.HTTP_403_FORBIDDEN), - (None, "tA2", status.HTTP_403_FORBIDDEN), - (None, "tB1", status.HTTP_403_FORBIDDEN), - (None, "tB2", status.HTTP_403_FORBIDDEN), - (None, "tC1", status.HTTP_403_FORBIDDEN), - (None, "tC2", status.HTTP_403_FORBIDDEN), + (None, "ot1", status.HTTP_401_UNAUTHORIZED), + (None, "ot2", status.HTTP_401_UNAUTHORIZED), + (None, "st1", status.HTTP_401_UNAUTHORIZED), + (None, "st2", status.HTTP_401_UNAUTHORIZED), + (None, "t1", status.HTTP_401_UNAUTHORIZED), + (None, "t2", status.HTTP_401_UNAUTHORIZED), + (None, "tA1", status.HTTP_401_UNAUTHORIZED), + (None, "tA2", status.HTTP_401_UNAUTHORIZED), + (None, "tB1", status.HTTP_401_UNAUTHORIZED), + (None, "tB2", status.HTTP_401_UNAUTHORIZED), + (None, "tC1", status.HTTP_401_UNAUTHORIZED), + (None, "tC2", status.HTTP_401_UNAUTHORIZED), ("user", "ot1", status.HTTP_403_FORBIDDEN), ("user", "ot2", status.HTTP_403_FORBIDDEN), ("user", "st1", status.HTTP_403_FORBIDDEN), @@ -465,18 +465,18 @@ class TestTaxonomyViewSet(TestTaxonomyObjectsMixin, APITestCase): assert response.data["system_defined"] is True @ddt.data( - (None, "ot1", status.HTTP_403_FORBIDDEN), - (None, "ot2", status.HTTP_403_FORBIDDEN), - (None, "st1", status.HTTP_403_FORBIDDEN), - (None, "st2", status.HTTP_403_FORBIDDEN), - (None, "t1", status.HTTP_403_FORBIDDEN), - (None, "t2", status.HTTP_403_FORBIDDEN), - (None, "tA1", status.HTTP_403_FORBIDDEN), - (None, "tA2", status.HTTP_403_FORBIDDEN), - (None, "tB1", status.HTTP_403_FORBIDDEN), - (None, "tB2", status.HTTP_403_FORBIDDEN), - (None, "tC1", status.HTTP_403_FORBIDDEN), - (None, "tC2", status.HTTP_403_FORBIDDEN), + (None, "ot1", status.HTTP_401_UNAUTHORIZED), + (None, "ot2", status.HTTP_401_UNAUTHORIZED), + (None, "st1", status.HTTP_401_UNAUTHORIZED), + (None, "st2", status.HTTP_401_UNAUTHORIZED), + (None, "t1", status.HTTP_401_UNAUTHORIZED), + (None, "t2", status.HTTP_401_UNAUTHORIZED), + (None, "tA1", status.HTTP_401_UNAUTHORIZED), + (None, "tA2", status.HTTP_401_UNAUTHORIZED), + (None, "tB1", status.HTTP_401_UNAUTHORIZED), + (None, "tB2", status.HTTP_401_UNAUTHORIZED), + (None, "tC1", status.HTTP_401_UNAUTHORIZED), + (None, "tC2", status.HTTP_401_UNAUTHORIZED), ("user", "ot1", status.HTTP_403_FORBIDDEN), ("user", "ot2", status.HTTP_403_FORBIDDEN), ("user", "st1", status.HTTP_403_FORBIDDEN), @@ -560,18 +560,18 @@ class TestTaxonomyViewSet(TestTaxonomyObjectsMixin, APITestCase): assert response.data["system_defined"] is True @ddt.data( - (None, "ot1", status.HTTP_403_FORBIDDEN), - (None, "ot2", status.HTTP_403_FORBIDDEN), - (None, "st1", status.HTTP_403_FORBIDDEN), - (None, "st2", status.HTTP_403_FORBIDDEN), - (None, "t1", status.HTTP_403_FORBIDDEN), - (None, "t2", status.HTTP_403_FORBIDDEN), - (None, "tA1", status.HTTP_403_FORBIDDEN), - (None, "tA2", status.HTTP_403_FORBIDDEN), - (None, "tB1", status.HTTP_403_FORBIDDEN), - (None, "tB2", status.HTTP_403_FORBIDDEN), - (None, "tC1", status.HTTP_403_FORBIDDEN), - (None, "tC2", status.HTTP_403_FORBIDDEN), + (None, "ot1", status.HTTP_401_UNAUTHORIZED), + (None, "ot2", status.HTTP_401_UNAUTHORIZED), + (None, "st1", status.HTTP_401_UNAUTHORIZED), + (None, "st2", status.HTTP_401_UNAUTHORIZED), + (None, "t1", status.HTTP_401_UNAUTHORIZED), + (None, "t2", status.HTTP_401_UNAUTHORIZED), + (None, "tA1", status.HTTP_401_UNAUTHORIZED), + (None, "tA2", status.HTTP_401_UNAUTHORIZED), + (None, "tB1", status.HTTP_401_UNAUTHORIZED), + (None, "tB2", status.HTTP_401_UNAUTHORIZED), + (None, "tC1", status.HTTP_401_UNAUTHORIZED), + (None, "tC2", status.HTTP_401_UNAUTHORIZED), ("user", "ot1", status.HTTP_403_FORBIDDEN), ("user", "ot2", status.HTTP_403_FORBIDDEN), ("user", "st1", status.HTTP_403_FORBIDDEN), @@ -695,24 +695,24 @@ class TestObjectTagViewSet(TestTaxonomyObjectsMixin, APITestCase): @ddt.data( # userA and userS are staff in courseA and can tag using enabled taxonomies - (None, "tA1", ["Tag 1"], status.HTTP_403_FORBIDDEN), + (None, "tA1", ["Tag 1"], status.HTTP_401_UNAUTHORIZED), ("user", "tA1", ["Tag 1"], status.HTTP_403_FORBIDDEN), ("userA", "tA1", ["Tag 1"], status.HTTP_200_OK), ("userS", "tA1", ["Tag 1"], status.HTTP_200_OK), - (None, "tA1", [], status.HTTP_403_FORBIDDEN), + (None, "tA1", [], status.HTTP_401_UNAUTHORIZED), ("user", "tA1", [], status.HTTP_403_FORBIDDEN), ("userA", "tA1", [], status.HTTP_200_OK), ("userS", "tA1", [], status.HTTP_200_OK), - (None, "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_403_FORBIDDEN), + (None, "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_401_UNAUTHORIZED), ("user", "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_403_FORBIDDEN), ("userA", "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_200_OK), ("userS", "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_200_OK), - (None, "open_taxonomy", ["tag1"], status.HTTP_403_FORBIDDEN), + (None, "open_taxonomy", ["tag1"], status.HTTP_401_UNAUTHORIZED), ("user", "open_taxonomy", ["tag1"], status.HTTP_403_FORBIDDEN), ("userA", "open_taxonomy", ["tag1"], status.HTTP_200_OK), ("userS", "open_taxonomy", ["tag1"], status.HTTP_200_OK), # Only userS is Tagging Admin and can tag objects using disabled taxonomies - (None, "tA2", ["Tag 1"], status.HTTP_403_FORBIDDEN), + (None, "tA2", ["Tag 1"], status.HTTP_401_UNAUTHORIZED), ("user", "tA2", ["Tag 1"], status.HTTP_403_FORBIDDEN), ("userA", "tA2", ["Tag 1"], status.HTTP_403_FORBIDDEN), ("userS", "tA2", ["Tag 1"], status.HTTP_200_OK), @@ -736,11 +736,11 @@ class TestObjectTagViewSet(TestTaxonomyObjectsMixin, APITestCase): @ddt.data( # Can't add invalid tags to a object using a closed taxonomy - (None, "tA1", ["invalid"], status.HTTP_403_FORBIDDEN), + (None, "tA1", ["invalid"], status.HTTP_401_UNAUTHORIZED), ("user", "tA1", ["invalid"], status.HTTP_403_FORBIDDEN), ("userA", "tA1", ["invalid"], status.HTTP_400_BAD_REQUEST), ("userS", "tA1", ["invalid"], status.HTTP_400_BAD_REQUEST), - (None, "multiple_taxonomy", ["invalid"], status.HTTP_403_FORBIDDEN), + (None, "multiple_taxonomy", ["invalid"], status.HTTP_401_UNAUTHORIZED), ("user", "multiple_taxonomy", ["invalid"], status.HTTP_403_FORBIDDEN), ("userA", "multiple_taxonomy", ["invalid"], status.HTTP_400_BAD_REQUEST), ("userS", "multiple_taxonomy", ["invalid"], status.HTTP_400_BAD_REQUEST), @@ -763,24 +763,24 @@ class TestObjectTagViewSet(TestTaxonomyObjectsMixin, APITestCase): @ddt.data( # userA and userS are staff in courseA (owner of xblockA) and can tag using enabled taxonomies - (None, "tA1", ["Tag 1"], status.HTTP_403_FORBIDDEN), + (None, "tA1", ["Tag 1"], status.HTTP_401_UNAUTHORIZED), ("user", "tA1", ["Tag 1"], status.HTTP_403_FORBIDDEN), ("userA", "tA1", ["Tag 1"], status.HTTP_200_OK), ("userS", "tA1", ["Tag 1"], status.HTTP_200_OK), - (None, "tA1", [], status.HTTP_403_FORBIDDEN), + (None, "tA1", [], status.HTTP_401_UNAUTHORIZED), ("user", "tA1", [], status.HTTP_403_FORBIDDEN), ("userA", "tA1", [], status.HTTP_200_OK), ("userS", "tA1", [], status.HTTP_200_OK), - (None, "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_403_FORBIDDEN), + (None, "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_401_UNAUTHORIZED), ("user", "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_403_FORBIDDEN), ("userA", "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_200_OK), ("userS", "multiple_taxonomy", ["Tag 1", "Tag 2"], status.HTTP_200_OK), - (None, "open_taxonomy", ["tag1"], status.HTTP_403_FORBIDDEN), + (None, "open_taxonomy", ["tag1"], status.HTTP_401_UNAUTHORIZED), ("user", "open_taxonomy", ["tag1"], status.HTTP_403_FORBIDDEN), ("userA", "open_taxonomy", ["tag1"], status.HTTP_200_OK), ("userS", "open_taxonomy", ["tag1"], status.HTTP_200_OK), # Only userS is Tagging Admin and can tag objects using disabled taxonomies - (None, "tA2", ["Tag 1"], status.HTTP_403_FORBIDDEN), + (None, "tA2", ["Tag 1"], status.HTTP_401_UNAUTHORIZED), ("user", "tA2", ["Tag 1"], status.HTTP_403_FORBIDDEN), ("userA", "tA2", ["Tag 1"], status.HTTP_403_FORBIDDEN), ("userS", "tA2", ["Tag 1"], status.HTTP_200_OK), @@ -804,11 +804,11 @@ class TestObjectTagViewSet(TestTaxonomyObjectsMixin, APITestCase): @ddt.data( # Can't add invalid tags to a object using a closed taxonomy - (None, "tA1", ["invalid"], status.HTTP_403_FORBIDDEN), + (None, "tA1", ["invalid"], status.HTTP_401_UNAUTHORIZED), ("user", "tA1", ["invalid"], status.HTTP_403_FORBIDDEN), ("userA", "tA1", ["invalid"], status.HTTP_400_BAD_REQUEST), ("userS", "tA1", ["invalid"], status.HTTP_400_BAD_REQUEST), - (None, "multiple_taxonomy", ["invalid"], status.HTTP_403_FORBIDDEN), + (None, "multiple_taxonomy", ["invalid"], status.HTTP_401_UNAUTHORIZED), ("user", "multiple_taxonomy", ["invalid"], status.HTTP_403_FORBIDDEN), ("userA", "multiple_taxonomy", ["invalid"], status.HTTP_400_BAD_REQUEST), ("userS", "multiple_taxonomy", ["invalid"], status.HTTP_400_BAD_REQUEST), diff --git a/openedx/core/djangoapps/content_tagging/rules.py b/openedx/core/djangoapps/content_tagging/rules.py index bad38019ce..b046fe5173 100644 --- a/openedx/core/djangoapps/content_tagging/rules.py +++ b/openedx/core/djangoapps/content_tagging/rules.py @@ -86,6 +86,7 @@ rules.set_perm("oel_tagging.add_taxonomy", oel_tagging.is_taxonomy_admin) rules.set_perm("oel_tagging.change_taxonomy", oel_tagging.can_change_taxonomy) rules.set_perm("oel_tagging.delete_taxonomy", oel_tagging.can_change_taxonomy) rules.set_perm("oel_tagging.view_taxonomy", oel_tagging.can_view_taxonomy) +rules.set_perm("oel_tagging.export_taxonomy", oel_tagging.can_view_taxonomy) # Tag rules.set_perm("oel_tagging.add_tag", can_change_taxonomy_tag) diff --git a/requirements/constraints.txt b/requirements/constraints.txt index 18168bb1ff..893b6e5253 100644 --- a/requirements/constraints.txt +++ b/requirements/constraints.txt @@ -121,7 +121,7 @@ libsass==0.10.0 click==8.1.6 # pinning this version to avoid updates while the library is being developed -openedx-learning==0.2.3 +openedx-learning==0.2.4 # lti-consumer-xblock 9.6.2 contains a breaking change that makes # existing custom parameter configurations unusable. diff --git a/requirements/edx/base.txt b/requirements/edx/base.txt index 00d27be34c..773972de74 100644 --- a/requirements/edx/base.txt +++ b/requirements/edx/base.txt @@ -785,7 +785,7 @@ openedx-filters==1.6.0 # via # -r requirements/edx/kernel.in # lti-consumer-xblock -openedx-learning==0.2.3 +openedx-learning==0.2.4 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/kernel.in diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index bc154d4c54..2dddbd8283 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -1318,7 +1318,7 @@ openedx-filters==1.6.0 # -r requirements/edx/doc.txt # -r requirements/edx/testing.txt # lti-consumer-xblock -openedx-learning==0.2.3 +openedx-learning==0.2.4 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/doc.txt diff --git a/requirements/edx/doc.txt b/requirements/edx/doc.txt index ff706089a4..01fd48a63e 100644 --- a/requirements/edx/doc.txt +++ b/requirements/edx/doc.txt @@ -925,7 +925,7 @@ openedx-filters==1.6.0 # via # -r requirements/edx/base.txt # lti-consumer-xblock -openedx-learning==0.2.3 +openedx-learning==0.2.4 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 44b91d3083..d57f523d7c 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -992,7 +992,7 @@ openedx-filters==1.6.0 # via # -r requirements/edx/base.txt # lti-consumer-xblock -openedx-learning==0.2.3 +openedx-learning==0.2.4 # via # -c requirements/edx/../constraints.txt # -r requirements/edx/base.txt