Skip to content

Commit

Permalink
chore: Adding permissions and docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisChV committed Sep 8, 2023
1 parent 380257e commit 315e1db
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 8 deletions.
14 changes: 14 additions & 0 deletions openedx_tagging/core/tagging/rest_api/v1/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"""

from rest_framework.permissions import DjangoObjectPermissions
from openedx_tagging.core.tagging.models import Tag, Taxonomy
import rules


class TaxonomyObjectPermissions(DjangoObjectPermissions):
Expand All @@ -27,3 +29,15 @@ class ObjectTagObjectPermissions(DjangoObjectPermissions):
"PATCH": ["%(app_label)s.change_%(model_name)s"],
"DELETE": ["%(app_label)s.delete_%(model_name)s"],
}


class TagListPermissions(DjangoObjectPermissions):
def has_permission(self, request, view):
if not request.user or (
not request.user.is_authenticated and self.authenticated_users_only
):
return False
return True

def has_object_permission(self, request, view, obj):
return rules.has_perm("oel_tagging.list_tag", request.user, obj)
49 changes: 42 additions & 7 deletions openedx_tagging/core/tagging/rest_api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@
get_root_tags,
get_children_tags,
)
from .permissions import TaxonomyObjectPermissions, ObjectTagObjectPermissions
from .permissions import (
TaxonomyObjectPermissions,
TagListPermissions,
ObjectTagObjectPermissions,
)
from .serializers import (
ObjectTagListQueryParamsSerializer,
ObjectTagSerializer,
Expand All @@ -36,6 +40,7 @@
TagsPagination,
DisabledTagsPagination,
)
from openedx_tagging.core.tagging.models.base import Tag


class TaxonomyView(ModelViewSet):
Expand Down Expand Up @@ -321,8 +326,27 @@ def update(self, request, object_id, partial=False):


class TaxonomyTagsView(ListAPIView):
""" """
"""
View to list tags of a taxonomy.
**List Query Parameters**
* pk (required) - The pk of the taxonomy to retrieve tags.
* parent_tag_id (optional) - Id of the tag to retrieve children tags.
* page (optional) - Page number (default: 1)
* page_size (optional) - Number of items per page (default: 10)
**List Example Requests**
GET api/tagging/v1/taxonomy/:pk/tags - Get tags of taxonomy
GET api/tagging/v1/taxonomy/:pk/tags?parent_tag_id=30 - Get children tags of tag
**List Query Returns**
* 200 - Success
* 400 - Invalid query parameter
* 403 - Permission denied
* 404 - Taxonomy not found
"""

permission_classes = [TagListPermissions]
pagination_enabled = True

def get_pagination_class(self):
Expand Down Expand Up @@ -353,28 +377,39 @@ def get_taxonomy(self, pk: str):
taxonomy = get_taxonomy(pk)
if not taxonomy:
raise Http404("Taxonomy not found")

self.check_object_permissions(self.request, taxonomy)
return taxonomy

def get_matching_tags(self, pk: str, parent_tag_id: str = None):
def get_matching_tags(self, taxonomy_id: int, parent_tag_id: str = None):
"""
Returns a list of tags for the given taxonomy. Also returns a boolean
to identify if the pagination is enabled.
The pagination can be enabled or disabled depending of the taxonomy size.
You can read the desicion '0014_*' to more info about this logic.
Use `parent_tag_id` to get the children of the given tag.
TODO: Search tags
"""
taxonomy = self.get_taxonomy(pk)
taxonomy = self.get_taxonomy(taxonomy_id)
if parent_tag_id:
return get_children_tags(taxonomy, parent_tag_id), True
else:
pagination_enabled = taxonomy.tag_set.count() > TAGS_THRESHOLD
return get_root_tags(taxonomy), pagination_enabled

def get_queryset(self):
pk = self.kwargs.get("pk")
"""
Builds and returns the queryset to be paginated
"""
pk = str(self.kwargs.get("pk"))
parent_tag_id = self.request.query_params.get("parent_tag_id", None)
result, self.pagination_enabled = self.get_matching_tags(
pk, parent_tag_id=parent_tag_id
)

# This function is not called automatically
self.pagination_class = self.get_pagination_class()
# TODO sort, después de armar el arbol, por el break
# TODO sort
return result
1 change: 1 addition & 0 deletions openedx_tagging/core/tagging/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def can_change_object_tag(user: UserType, perm_obj: ChangeObjectTagPermissionIte
rules.add_perm("oel_tagging.change_tag", can_change_tag)
rules.add_perm("oel_tagging.delete_tag", is_taxonomy_admin)
rules.add_perm("oel_tagging.view_tag", rules.always_allow)
rules.add_perm("oel_tagging.list_tag", can_view_taxonomy)

# ObjectTag
rules.add_perm("oel_tagging.add_objecttag", can_change_object_tag)
Expand Down
13 changes: 12 additions & 1 deletion tests/openedx_tagging/core/tagging/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,6 @@ def _build_large_taxonomy(self):
for _ in range(self.root_tags_count):
self._create_tag(0)


def test_invalid_taxonomy(self):
url = TAXONOMY_TAGS_URL.format(pk=212121)

Expand All @@ -845,6 +844,18 @@ def test_invalid_taxonomy(self):

assert response.status_code == status.HTTP_404_NOT_FOUND

def test_not_authorized_user(self):
# Not authenticated user
response = self.client.get(self.small_taxonomy_url)
assert response.status_code == status.HTTP_403_FORBIDDEN

self.small_taxonomy.enabled = False
self.small_taxonomy.save()
self.client.force_authenticate(user=self.user)
response = self.client.get(self.small_taxonomy_url)

assert response.status_code == status.HTTP_403_FORBIDDEN

def test_small_taxonomy(self):
self.client.force_authenticate(user=self.staff)
response = self.client.get(self.small_taxonomy_url)
Expand Down

0 comments on commit 315e1db

Please sign in to comment.