Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions djangocms_rest/permissions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from cms.models import Page, PageContent
from cms.utils.i18n import get_language_tuple
from cms.utils.i18n import get_language_tuple, get_languages
from cms.utils.page_permissions import user_can_view_page
from rest_framework.exceptions import NotFound
from rest_framework.permissions import BasePermission
Expand All @@ -10,7 +10,7 @@

class IsAllowedLanguage(BasePermission):
"""
Check whether the provided language is allowed.
Check whether the provided language is allowed for a given site.
"""

def has_permission(self, request: Request, view: BaseAPIView) -> bool:
Expand All @@ -22,6 +22,24 @@ def has_permission(self, request: Request, view: BaseAPIView) -> bool:
return True


class IsAllowedPublicLanguage(IsAllowedLanguage):
"""
Check whether the provided language is allowed and public for a given site.
"""
def has_permission(self, request: Request, view: BaseAPIView) -> bool:
super().has_permission(request, view)
language = view.kwargs.get("language")
languages = get_languages()
public_languages = [
lang["code"] for lang in languages if lang.get("public", True)
]
if language not in public_languages:
raise NotFound()
return True




class CanViewPage(IsAllowedLanguage):
"""
Check whether the provided language is allowed and the user can view the page.
Expand Down
9 changes: 5 additions & 4 deletions djangocms_rest/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
CanViewPage,
CanViewPageContent,
IsAllowedLanguage,
IsAllowedPublicLanguage,
)
from djangocms_rest.serializers.languages import LanguageSerializer
from djangocms_rest.serializers.pages import (
Expand Down Expand Up @@ -64,7 +65,7 @@ def get(self, request: Request | None) -> Response:


class PageListView(BaseListAPIView):
permission_classes = [IsAllowedLanguage]
permission_classes = [IsAllowedPublicLanguage]
serializer_class = PageListSerializer
pagination_class = LimitOffsetPagination

Expand All @@ -90,7 +91,7 @@ def get_queryset(self):
raise NotFound()

class PageTreeListView(BaseAPIView):
permission_classes = [IsAllowedLanguage]
permission_classes = [IsAllowedPublicLanguage]
serializer_class = PageMetaSerializer

def get(self, request, language):
Expand Down Expand Up @@ -119,7 +120,7 @@ def get(self, request, language):


class PageDetailView(BaseAPIView):
permission_classes = [CanViewPage]
permission_classes = [IsAllowedPublicLanguage, CanViewPage]
serializer_class = PageContentSerializer

def get(self, request: Request, language: str, path: str = "") -> Response:
Expand All @@ -140,8 +141,8 @@ def get(self, request: Request, language: str, path: str = "") -> Response:


class PlaceholderDetailView(BaseAPIView):
permission_classes = [IsAllowedPublicLanguage, CanViewPageContent]
serializer_class = PlaceholderSerializer
permission_classes = [CanViewPageContent]

@extend_placeholder_schema

Expand Down
169 changes: 167 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,15 @@ classifiers = [
]

[tool.poetry.dependencies]
python = ">=3.9"
python = ">=3.9,<4"
django-cms = ">=4.1.1"
djangorestframework = "*"
djangocms-link = "^5.0.0"
djangocms-text = "^0.8.0"
pytest-cov = "^6.0.0"
pytest-django = "^4.10.0"
djangocms-picture = "^4.1.1"
django-filer = "^3.3.1"

[tool.poetry.group.dev.dependencies]
pytest = "^7.3.1"
Expand Down
4 changes: 4 additions & 0 deletions tests/endpoints/test_page_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ def test_get_paginated_list(self):
response = self.client.get(reverse("page-list", kwargs={"language": "xx"}))
self.assertEqual(response.status_code, 404)

# Check Non-Public language
response = self.client.get(reverse("page-list", kwargs={"language": "fr"}))
self.assertEqual(response.status_code, 404)

# GET PREVIEW
response = self.client.get(reverse("preview-page-list", kwargs={"language": "en"}))
self.assertEqual(response.status_code, 403)
Expand Down
2 changes: 0 additions & 2 deletions tests/requirements/base.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# requirements from setup.py
djangorestframework
djangocms-picture>=2.1.0
djangocms-link>=2.2.1
djangocms-text
setuptools

Expand Down
26 changes: 11 additions & 15 deletions tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ def __getitem__(self, item):
'treebeard',
'sekizai',

'djangocms_link',
'djangocms_picture',
'djangocms_text',
'filer',
'easy_thumbnails',
'tests.test_app',
]

Expand Down Expand Up @@ -71,23 +67,23 @@ def __getitem__(self, item):
CMS_LANGUAGES = {
1: [
{
'code': 'en',
'name': gettext('English'),
'public': True,
"code": "en",
"name": gettext("English"),
"public": True,
},
{
'code': 'it',
'name': gettext('Italiano'),
'public': True,
"code": "it",
"name": gettext("Italiano"),
"public": True,
},
{
'code': 'fr',
'name': gettext('French'),
'public': True,
"code": "fr",
"name": gettext("French"),
"public": False,
},
],
'default': {
'hide_untranslated': False,
"default": {
"hide_untranslated": False,
},
}

Expand Down