MST-400 Update the support verification_api to provide the correct status under the same API used by learner (#25917)
This commit is contained in:
@@ -8,10 +8,8 @@ from django.utils.timezone import now
|
||||
from rest_framework import serializers
|
||||
|
||||
from lms.djangoapps.verify_student.models import (
|
||||
IDVerificationAttempt,
|
||||
ManualVerification,
|
||||
SoftwareSecurePhotoVerification,
|
||||
SSOVerification
|
||||
SoftwareSecurePhotoVerification
|
||||
)
|
||||
|
||||
from .models import UserPreference
|
||||
@@ -103,40 +101,6 @@ class CountryTimeZoneSerializer(serializers.Serializer): # pylint: disable=abst
|
||||
description = serializers.CharField()
|
||||
|
||||
|
||||
class IDVerificationSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
Serializer that generates a representation of a user's ID verification status.
|
||||
"""
|
||||
is_verified = serializers.SerializerMethodField()
|
||||
|
||||
def get_is_verified(self, obj):
|
||||
"""
|
||||
Return a boolean indicating if a the user is verified.
|
||||
"""
|
||||
return obj.status == 'approved' and obj.expiration_datetime > now()
|
||||
|
||||
|
||||
class SoftwareSecurePhotoVerificationSerializer(IDVerificationSerializer):
|
||||
|
||||
class Meta(object):
|
||||
fields = ('status', 'expiration_datetime', 'is_verified')
|
||||
model = SoftwareSecurePhotoVerification
|
||||
|
||||
|
||||
class SSOVerificationSerializer(IDVerificationSerializer):
|
||||
|
||||
class Meta(object):
|
||||
fields = ('status', 'expiration_datetime', 'is_verified')
|
||||
model = SSOVerification
|
||||
|
||||
|
||||
class ManualVerificationSerializer(IDVerificationSerializer):
|
||||
|
||||
class Meta(object):
|
||||
fields = ('status', 'expiration_datetime', 'is_verified')
|
||||
model = ManualVerification
|
||||
|
||||
|
||||
class IDVerificationDetailsSerializer(serializers.Serializer):
|
||||
type = serializers.SerializerMethodField()
|
||||
status = serializers.CharField()
|
||||
|
||||
@@ -15,7 +15,7 @@ from lms.djangoapps.verify_student.tests.factories import SSOVerificationFactory
|
||||
from common.djangoapps.student.tests.factories import UserFactory
|
||||
|
||||
FROZEN_TIME = '2015-01-01'
|
||||
VERIFY_STUDENT = {'DAYS_GOOD_FOR': 365}
|
||||
VERIFY_STUDENT = {'DAYS_GOOD_FOR': 365, 'EXPIRING_SOON_WINDOW': 20}
|
||||
|
||||
|
||||
class VerificationStatusViewTestsMixin:
|
||||
@@ -95,9 +95,12 @@ class PhotoVerificationStatusViewTests(VerificationStatusViewTestsMixin, TestCas
|
||||
VIEW_NAME = 'verification_status'
|
||||
|
||||
def get_expected_response(self, *args, **kwargs):
|
||||
verification_status = self.photo_verification.status
|
||||
if self.photo_verification.status == 'submitted':
|
||||
verification_status = 'pending'
|
||||
return {
|
||||
'status': self.photo_verification.status,
|
||||
'expiration_datetime': '{}Z'.format(kwargs.get('expected_expires').isoformat()),
|
||||
'status': verification_status,
|
||||
'expiration_datetime': '',
|
||||
'is_verified': kwargs.get('verified')
|
||||
}
|
||||
|
||||
@@ -109,6 +112,14 @@ class PhotoVerificationStatusViewTests(VerificationStatusViewTestsMixin, TestCas
|
||||
self.client.login(username=self.user.username, password=self.PASSWORD)
|
||||
self.assert_verification_returned(verified=True)
|
||||
|
||||
def test_multiple_verifications(self):
|
||||
self.photo_verification.status = 'approved'
|
||||
self.photo_verification.save()
|
||||
SoftwareSecurePhotoVerification.objects.create(user=self.user, status='denied')
|
||||
self.client.logout()
|
||||
self.client.login(username=self.user.username, password=self.PASSWORD)
|
||||
self.assert_verification_returned(verified=True)
|
||||
|
||||
|
||||
@override_settings(VERIFY_STUDENT=VERIFY_STUDENT)
|
||||
class VerificationsDetailsViewTests(VerificationStatusViewTestsMixin, TestCase):
|
||||
|
||||
@@ -4,57 +4,38 @@ from django.contrib.auth import get_user_model
|
||||
from django.http import Http404
|
||||
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
|
||||
from rest_framework.authentication import SessionAuthentication
|
||||
from rest_framework.generics import ListAPIView, RetrieveAPIView
|
||||
from rest_framework.generics import ListAPIView
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
|
||||
from lms.djangoapps.verify_student.models import ManualVerification, SoftwareSecurePhotoVerification, SSOVerification
|
||||
from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
from lms.djangoapps.verify_student.utils import most_recent_verification
|
||||
from openedx.core.djangoapps.user_api.serializers import (
|
||||
IDVerificationDetailsSerializer,
|
||||
ManualVerificationSerializer,
|
||||
SoftwareSecurePhotoVerificationSerializer,
|
||||
SSOVerificationSerializer
|
||||
)
|
||||
from openedx.core.djangoapps.user_api.serializers import IDVerificationDetailsSerializer
|
||||
from openedx.core.lib.api.authentication import BearerAuthentication
|
||||
from openedx.core.lib.api.permissions import IsStaffOrOwner
|
||||
|
||||
|
||||
class IDVerificationStatusView(RetrieveAPIView):
|
||||
""" IDVerificationStatus detail endpoint. """
|
||||
class IDVerificationStatusView(APIView):
|
||||
""" IDVerification Status endpoint """
|
||||
authentication_classes = (JwtAuthentication, BearerAuthentication, SessionAuthentication,)
|
||||
permission_classes = (IsStaffOrOwner,)
|
||||
|
||||
def get_serializer(self, *args, **kwargs):
|
||||
"""
|
||||
Overrides default get_serializer in order to choose the correct serializer for the instance.
|
||||
"""
|
||||
instance = args[0]
|
||||
kwargs['context'] = self.get_serializer_context()
|
||||
if isinstance(instance, SoftwareSecurePhotoVerification):
|
||||
return SoftwareSecurePhotoVerificationSerializer(*args, **kwargs)
|
||||
elif isinstance(instance, SSOVerification):
|
||||
return SSOVerificationSerializer(*args, **kwargs)
|
||||
else:
|
||||
return ManualVerificationSerializer(*args, **kwargs)
|
||||
def get(self, request, **kwargs):
|
||||
username = kwargs.get('username')
|
||||
User = get_user_model()
|
||||
try:
|
||||
user = User.objects.get(username=username)
|
||||
user_status = IDVerificationService.user_status(user)
|
||||
if user_status.get('status') == 'none':
|
||||
raise Http404
|
||||
|
||||
def get_object(self):
|
||||
username = self.kwargs['username']
|
||||
photo_verifications = SoftwareSecurePhotoVerification.objects.filter(
|
||||
user__username=username).order_by('-updated_at')
|
||||
sso_verifications = SSOVerification.objects.filter(user__username=username).order_by('-updated_at')
|
||||
manual_verifications = ManualVerification.objects.filter(user__username=username).order_by('-updated_at')
|
||||
return Response({
|
||||
"is_verified": user_status.get('status') == 'approved',
|
||||
"status": user_status.get('status'),
|
||||
"expiration_datetime": user_status.get('verification_expiry', '')
|
||||
})
|
||||
|
||||
if photo_verifications or sso_verifications or manual_verifications:
|
||||
verification = most_recent_verification(
|
||||
photo_verifications,
|
||||
sso_verifications,
|
||||
manual_verifications,
|
||||
'updated_at'
|
||||
)
|
||||
self.check_object_permissions(self.request, verification)
|
||||
return verification
|
||||
|
||||
raise Http404
|
||||
except User.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
|
||||
class IDVerificationStatusDetailsView(ListAPIView):
|
||||
|
||||
Reference in New Issue
Block a user