Skip to content

Commit

Permalink
feat: deprecate get_verification_details_by_id (#35560)
Browse files Browse the repository at this point in the history
  • Loading branch information
alangsto authored Sep 30, 2024
1 parent 888d85c commit 5043260
Show file tree
Hide file tree
Showing 5 changed files with 0 additions and 153 deletions.
31 changes: 0 additions & 31 deletions lms/djangoapps/verify_student/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from urllib.parse import quote

from django.conf import settings
from django.core.exceptions import ObjectDoesNotExist
from django.utils.timezone import now
from django.utils.translation import gettext as _
from openedx_filters.learning.filters import IDVPageURLRequested
Expand Down Expand Up @@ -249,33 +248,3 @@ def get_verify_location(cls, course_id=None):
# .. filter_implemented_name: IDVPageURLRequested
# .. filter_type: org.openedx.learning.idv.page.url.requested.v1
return IDVPageURLRequested.run_filter(location)

@classmethod
def get_verification_details_by_id(cls, attempt_id):
"""
Returns a verification attempt object by attempt_id
If the verification object cannot be found, returns None
This method does not take into account verifications stored in the
VerificationAttempt model used for pluggable IDV implementations.
As part of the work to implement pluggable IDV, this method's use
will be deprecated: https://openedx.atlassian.net/browse/OSPR-1011
"""
verification = None

# This does not look at the VerificationAttempt model since the provided id would become
# ambiguous between tables. The verification models in this list all inherit from the same
# base class and share the same id space.
verification_models = [
SoftwareSecurePhotoVerification,
SSOVerification,
ManualVerification,
]
for ver_model in verification_models:
if not verification:
try:
verification = ver_model.objects.get(id=attempt_id)
except ObjectDoesNotExist:
pass
return verification
48 changes: 0 additions & 48 deletions lms/djangoapps/verify_student/tests/test_services.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
Tests for the service classes in verify_student.
"""

import itertools
from datetime import datetime, timedelta, timezone
from random import randint
from unittest.mock import patch

import ddt
Expand Down Expand Up @@ -231,52 +229,6 @@ def test_get_expiration_datetime_mixed_models(self):
expiration_datetime = IDVerificationService.get_expiration_datetime(user, ['approved'])
assert expiration_datetime == newest.expiration_datetime

@ddt.data(
{'status': 'denied', 'error_msg': '[{"generalReasons": ["Name mismatch"]}]'},
{'status': 'approved', 'error_msg': ''},
{'status': 'submitted', 'error_msg': ''},
)
def test_get_verification_details_by_id(self, kwargs):
user = UserFactory.create()
kwargs['user'] = user
sspv = SoftwareSecurePhotoVerification.objects.create(**kwargs)
attempt = IDVerificationService.get_verification_details_by_id(sspv.id)
assert attempt.id == sspv.id
assert attempt.user.id == user.id
assert attempt.status == kwargs['status']
assert attempt.error_msg == kwargs['error_msg']

@ddt.data(
*itertools.product(
[SSOVerification, ManualVerification],
[
{'status': 'denied'},
{'status': 'approved'},
{'status': 'submitted'},
]
)
)
@ddt.unpack
def test_get_verification_details_other_types(self, verification_model, kwargs):
user = UserFactory.create()
kwargs['user'] = user
model_object = verification_model.objects.create(**kwargs)

attempt = IDVerificationService.get_verification_details_by_id(model_object.id)
assert attempt.id == model_object.id
assert attempt.user.id == user.id
assert attempt.status == kwargs['status']

@ddt.data(
SoftwareSecurePhotoVerification, SSOVerification, ManualVerification
)
def test_get_verification_details_not_found(self, verification_model):
user = UserFactory.create()
model_object = verification_model.objects.create(user=user)
not_found_id = model_object.id + randint(100, 200)
attempt = IDVerificationService.get_verification_details_by_id(not_found_id)
assert attempt is None


@patch.dict(settings.VERIFY_STUDENT, FAKE_SETTINGS)
@ddt.ddt
Expand Down
6 changes: 0 additions & 6 deletions openedx/core/djangoapps/user_api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from .verification_api.views import (
IDVerificationStatusView,
IDVerificationStatusDetailsView,
IDVerificationSupportView,
)

ME = AccountViewSet.as_view({
Expand Down Expand Up @@ -147,11 +146,6 @@
IDVerificationStatusDetailsView.as_view(),
name='verification_details'
),
re_path(
r'^v1/accounts/verifications/(?P<attempt_id>[0-9]+)/$',
IDVerificationSupportView.as_view(),
name='verification_for_support'
),
re_path(
fr'^v1/accounts/{settings.USERNAME_PATTERN}/retirement_status/$',
RETIREMENT_RETRIEVE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import datetime
import json

import ddt
import freezegun
from django.conf import settings
from django.test import TestCase
Expand Down Expand Up @@ -258,51 +257,3 @@ def test_multiple_verification_instances(self):
},
]
assert json.loads(response.content.decode('utf-8')) == expected


@override_settings(VERIFY_STUDENT=VERIFY_STUDENT)
@ddt.ddt
class VerificationSupportViewTests(VerificationViewTestsMixinBase, TestCase):
"""
Tests for the verification_for_support view
"""
@property
def path(self):
return reverse('verification_for_support', kwargs={'attempt_id': self.photo_verification.id})

def get_expected_response(self, *args, **kwargs):
return {
'type': 'Software Secure',
'status': self.photo_verification.status,
'expiration_datetime': '{}Z'.format(kwargs.get('expected_expires').isoformat()),
'message': kwargs.get('error_msg'),
'updated_at': f'{self.CREATED_AT.isoformat()}Z',
'receipt_id': self.photo_verification.receipt_id,
}

@ddt.data(
('accepted', ''),
('denied', '[{"generalReasons": ["Name mismatch"]}]'),
('submitted', ''),
('must_retry', ''),
)
@ddt.unpack
def test_get_details(self, status, error_message):
self.photo_verification.status = status
self.photo_verification.error_msg = error_message
self.photo_verification.save()
self.client.login(username=self.staff.username, password=self.PASSWORD)
response = self.assert_verification_returned()
expected_expires = self.CREATED_AT + datetime.timedelta(settings.VERIFY_STUDENT['DAYS_GOOD_FOR'])
expected = self.get_expected_response(expected_expires=expected_expires, error_msg=error_message)
assert json.loads(response.content.decode('utf-8')) == expected

@ddt.data(
0,
234324,
'not_a_number',
)
def test_not_found(self, attempt_id):
not_found_path = self.path.replace(str(self.photo_verification.id), str(attempt_id))
response = self.client.get(not_found_path)
assert response.status_code == 404
19 changes: 0 additions & 19 deletions openedx/core/djangoapps/user_api/verification_api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django.contrib.auth import get_user_model
from django.http import Http404
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
from edx_rest_framework_extensions.permissions import IsStaff
from rest_framework.authentication import SessionAuthentication
from rest_framework.generics import ListAPIView
from rest_framework.response import Response
Expand Down Expand Up @@ -61,21 +60,3 @@ def get_queryset(self):
return sorted(verifications, key=lambda x: x.updated_at, reverse=True)
except User.DoesNotExist:
raise Http404 # lint-amnesty, pylint: disable=raise-missing-from


class IDVerificationSupportView(APIView):
""" IDVerification endpoint for support-tool"""
authentication_classes = (JwtAuthentication, BearerAuthentication, SessionAuthentication,)
permission_classes = (IsStaff,)

def get(self, request, **kwargs):
"""
Get IDV attempt details by attempt_id. Only accessible by global staff.
"""
attempt_id = kwargs.get('attempt_id')
verification_detail = IDVerificationService.get_verification_details_by_id(attempt_id)
if not verification_detail:
raise Http404
return Response(
IDVerificationDetailsSerializer(verification_detail).data
)

0 comments on commit 5043260

Please sign in to comment.