fix: notification tray icon was not visible to non-verified users (#33247)
This commit is contained in:
committed by
GitHub
parent
6ff8e42bba
commit
5fcad886cb
27
openedx/core/djangoapps/notifications/permissions.py
Normal file
27
openedx/core/djangoapps/notifications/permissions.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""
|
||||
Permissions for notifications
|
||||
"""
|
||||
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
|
||||
from edx_rest_framework_extensions.auth.session.authentication import SessionAuthenticationAllowInactiveUser
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
|
||||
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser
|
||||
|
||||
|
||||
def allow_any_authenticated_user():
|
||||
"""
|
||||
Function and class decorator that abstracts the authentication and permission checks for api views.
|
||||
Allows both verified and non-verified users
|
||||
"""
|
||||
def _decorator(func_or_class):
|
||||
"""
|
||||
Requires either OAuth2 or Session-based authentication.
|
||||
"""
|
||||
func_or_class.authentication_classes = (
|
||||
JwtAuthentication,
|
||||
BearerAuthenticationAllowInactiveUser,
|
||||
SessionAuthenticationAllowInactiveUser
|
||||
)
|
||||
func_or_class.permission_classes = (IsAuthenticated,)
|
||||
return func_or_class
|
||||
return _decorator
|
||||
@@ -91,11 +91,11 @@ class CourseEnrollmentListViewTest(ModuleStoreTestCase):
|
||||
def test_course_enrollment_api_permission(self):
|
||||
"""
|
||||
Calls api without login.
|
||||
Check is 403 is returned
|
||||
Check is 401 is returned
|
||||
"""
|
||||
url = reverse('enrollment-list')
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
|
||||
@override_waffle_flag(ENABLE_NOTIFICATIONS, active=True)
|
||||
@@ -241,7 +241,7 @@ class UserNotificationPreferenceAPITest(ModuleStoreTestCase):
|
||||
Test get user notification preference without login.
|
||||
"""
|
||||
response = self.client.get(self.path)
|
||||
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
@mock.patch("eventtracking.tracker.emit")
|
||||
def test_get_user_notification_preference(self, mock_emit):
|
||||
@@ -411,13 +411,13 @@ class NotificationListAPIViewTest(APITestCase):
|
||||
|
||||
def test_list_notifications_without_authentication(self):
|
||||
"""
|
||||
Test that the view returns 403 if the user is not authenticated.
|
||||
Test that the view returns 401 if the user is not authenticated.
|
||||
"""
|
||||
# Make a request to the view without authenticating.
|
||||
response = self.client.get(self.url)
|
||||
|
||||
# Assert that the response is unauthorized.
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def test_list_notifications_with_expiry_date(self):
|
||||
"""
|
||||
@@ -533,10 +533,10 @@ class NotificationCountViewSetTestCase(ModuleStoreTestCase):
|
||||
|
||||
def test_get_unseen_notifications_count_for_unauthenticated_user(self):
|
||||
"""
|
||||
Test that the endpoint returns 403 for an unauthenticated user.
|
||||
Test that the endpoint returns 401 for an unauthenticated user.
|
||||
"""
|
||||
response = self.client.get(self.url)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
def test_get_unseen_notifications_count_for_user_with_no_notifications(self):
|
||||
"""
|
||||
|
||||
@@ -9,7 +9,7 @@ from django.shortcuts import get_object_or_404
|
||||
from django.utils.translation import gettext as _
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from pytz import UTC
|
||||
from rest_framework import generics, permissions, status
|
||||
from rest_framework import generics, status
|
||||
from rest_framework.generics import UpdateAPIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
@@ -19,6 +19,7 @@ from openedx.core.djangoapps.notifications.models import (
|
||||
CourseNotificationPreference,
|
||||
get_course_notification_preference_config_version
|
||||
)
|
||||
from openedx.core.djangoapps.notifications.permissions import allow_any_authenticated_user
|
||||
|
||||
from .base_notification import COURSE_NOTIFICATION_APPS
|
||||
from .config.waffle import ENABLE_NOTIFICATIONS
|
||||
@@ -38,6 +39,7 @@ from .serializers import (
|
||||
from .utils import get_show_notifications_tray
|
||||
|
||||
|
||||
@allow_any_authenticated_user()
|
||||
class CourseEnrollmentListView(generics.ListAPIView):
|
||||
"""
|
||||
API endpoint to get active CourseEnrollments for requester.
|
||||
@@ -67,7 +69,6 @@ class CourseEnrollmentListView(generics.ListAPIView):
|
||||
- 403: The requester cannot access resource.
|
||||
"""
|
||||
serializer_class = NotificationCourseEnrollmentSerializer
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
def get_paginated_response(self, data):
|
||||
"""
|
||||
@@ -105,6 +106,7 @@ class CourseEnrollmentListView(generics.ListAPIView):
|
||||
})
|
||||
|
||||
|
||||
@allow_any_authenticated_user()
|
||||
class UserNotificationPreferenceView(APIView):
|
||||
"""
|
||||
Supports retrieving and patching the UserNotificationPreference
|
||||
@@ -141,7 +143,6 @@ class UserNotificationPreferenceView(APIView):
|
||||
}
|
||||
}
|
||||
"""
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get(self, request, course_key_string):
|
||||
"""
|
||||
@@ -220,6 +221,7 @@ class UserNotificationPreferenceView(APIView):
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
@allow_any_authenticated_user()
|
||||
class NotificationListAPIView(generics.ListAPIView):
|
||||
"""
|
||||
API view for listing notifications for a user.
|
||||
@@ -253,7 +255,6 @@ class NotificationListAPIView(generics.ListAPIView):
|
||||
"""
|
||||
|
||||
serializer_class = NotificationSerializer
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get_queryset(self):
|
||||
"""
|
||||
@@ -279,13 +280,12 @@ class NotificationListAPIView(generics.ListAPIView):
|
||||
).order_by('-id')
|
||||
|
||||
|
||||
@allow_any_authenticated_user()
|
||||
class NotificationCountView(APIView):
|
||||
"""
|
||||
API view for getting the unseen notifications count and show_notification_tray flag for a user.
|
||||
"""
|
||||
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def get(self, request):
|
||||
"""
|
||||
Get the unseen notifications count and show_notification_tray flag for a user.
|
||||
@@ -334,13 +334,12 @@ class NotificationCountView(APIView):
|
||||
})
|
||||
|
||||
|
||||
@allow_any_authenticated_user()
|
||||
class MarkNotificationsSeenAPIView(UpdateAPIView):
|
||||
"""
|
||||
API view for marking user's all notifications seen for a provided app_name.
|
||||
"""
|
||||
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def update(self, request, *args, **kwargs):
|
||||
"""
|
||||
Marks all notifications for the given app name seen for the authenticated user.
|
||||
@@ -368,13 +367,12 @@ class MarkNotificationsSeenAPIView(UpdateAPIView):
|
||||
return Response({'message': _('Notifications marked as seen.')}, status=200)
|
||||
|
||||
|
||||
@allow_any_authenticated_user()
|
||||
class NotificationReadAPIView(APIView):
|
||||
"""
|
||||
API view for marking user notifications as read, either all notifications or a single notification
|
||||
"""
|
||||
|
||||
permission_classes = (permissions.IsAuthenticated,)
|
||||
|
||||
def patch(self, request, *args, **kwargs):
|
||||
"""
|
||||
Marks all notifications or single notification read for the given
|
||||
|
||||
Reference in New Issue
Block a user