Merge pull request #24107 from edx/restrict-api-to-staff-and-self-user

Restrict cert api to staff and self user
This commit is contained in:
Uzair Rasheed
2020-06-03 19:13:47 +05:00
committed by GitHub
3 changed files with 70 additions and 2 deletions

View File

@@ -0,0 +1,26 @@
"""
This module provides a custom DRF Permission class for supporting the course certificates
to Admin users and users whom they belongs to.
"""
from django.contrib.auth.models import User
from rest_framework.permissions import BasePermission
from openedx.core.djangoapps.user_api.models import UserPreference
class IsOwnerOrPublicCertificates(BasePermission):
"""
Method that will ensure whether the requesting user is staff or
the user whom the certificate belongs to
"""
def has_permission(self, request, view):
requested_profile_username = view.kwargs.get('username')
# check whether requesting user is the owner of certs or not
if request.user.username == requested_profile_username:
return True
user = User.objects.get(username=requested_profile_username)
cert_privacy = UserPreference.get_value(user, 'visibility.course_certificates')
return cert_privacy == 'all_users'

View File

@@ -229,6 +229,46 @@ class CertificatesListRestApiTest(AuthAndScopesTestMixin, SharedModuleStoreTestC
self.assertEqual(resp.status_code, status.HTTP_200_OK)
self.assertEqual(len(resp.data), 1)
def test_owner_can_access_its_certs(self):
"""
Tests the owner of the certs can access the certificate list api
"""
self.student.profile.year_of_birth = 1977
self.student.profile.save()
UserPreferenceFactory.build(
user=self.student,
key='visibility.course_certificates',
value='private',
).save()
resp = self.get_response(AuthType.session, requesting_user=self.student)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
# verifies that other than owner cert list api is not accessible
resp = self.get_response(AuthType.session, requesting_user=self.other_student)
self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN)
def test_public_profile_certs_is_accessible(self):
"""
Tests the public profile certs can be accessed by all users
"""
self.student.profile.year_of_birth = 1977
self.student.profile.save()
UserPreferenceFactory.build(
user=self.student,
key='visibility.course_certificates',
value='all_users',
).save()
resp = self.get_response(AuthType.session, requesting_user=self.student)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
resp = self.get_response(AuthType.session, requesting_user=self.other_student)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
resp = self.get_response(AuthType.session, requesting_user=self.global_staff)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
@ddt.data(*list(AuthType))
def test_another_user_with_certs_shared_custom(self, auth_type):
"""

View File

@@ -12,7 +12,7 @@ from edx_rest_framework_extensions.auth.session.authentication import SessionAut
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from rest_condition import C
from rest_framework.permissions import IsAuthenticated, IsAdminUser
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
@@ -23,6 +23,8 @@ from openedx.core.djangoapps.content.course_overviews.models import CourseOvervi
from openedx.core.djangoapps.user_api.accounts.api import visible_fields
from openedx.core.lib.api.authentication import BearerAuthenticationAllowInactiveUser
from .permissions import IsOwnerOrPublicCertificates
log = logging.getLogger(__name__)
User = get_user_model()
@@ -158,7 +160,7 @@ class CertificatesListView(APIView):
permissions.JwtHasUserFilterForRequestedUser
)
),
IsAdminUser,
(C(permissions.IsStaff) | IsOwnerOrPublicCertificates),
)
required_scopes = ['certificates:read']