fix: notification tray icon was not visible to non-verified users (#33247)

This commit is contained in:
Muhammad Adeel Tajamul
2023-09-15 16:14:24 +05:00
committed by GitHub
parent 6ff8e42bba
commit 5fcad886cb
3 changed files with 42 additions and 17 deletions

View 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

View File

@@ -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):
"""

View File

@@ -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