Skip to content

Commit dac0309

Browse files
authored
fix: add should_display_status_to_user method and status_changed field to VerificationAttempt model (#35514)
* fix: add placeholder should_display_status_to_user * fix: have VerificationAttempt inherit StatusModel - should_display_status_to_user now returns False * chore: makemigrations * feat: status_changed field added * temp: idea to add should_display_status_to_user * feat: add should_display_status_to_user * fix: correct call in helpers+services * chore: lint+test fix * fix: default hide_status_user as False * chore: rename field call to STATUS * chore: remove extra status field - comment cleanup * temp: lint + comment out created status for now * fix: revamp status_changed for back-compat * fix: override save for status_changed * fix: replace created/updated instead of status - also made migrations * fix: squash commits - also remove extra updated_at property * chore: nits
1 parent 468c2bb commit dac0309

File tree

4 files changed

+77
-12
lines changed

4 files changed

+77
-12
lines changed

lms/djangoapps/verify_student/api.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ def send_approval_email(attempt):
5454
send_verification_approved_email(context=email_context)
5555

5656

57-
def create_verification_attempt(user: User, name: str, status: str, expiration_datetime: Optional[datetime] = None):
57+
def create_verification_attempt(
58+
user: User,
59+
name: str,
60+
status: str,
61+
expiration_datetime: Optional[datetime] = None,
62+
hide_status_from_user: Optional[bool] = False,
63+
):
5864
"""
5965
Create a verification attempt.
6066
@@ -74,6 +80,7 @@ def create_verification_attempt(user: User, name: str, status: str, expiration_d
7480
name=name,
7581
status=status,
7682
expiration_datetime=expiration_datetime,
83+
hide_status_from_user=hide_status_from_user,
7784
)
7885

7986
emit_idv_attempt_created_event(
@@ -129,7 +136,7 @@ def update_verification_attempt(
129136
'Status must be one of: %(status_list)s',
130137
{
131138
'status': status,
132-
'status_list': VerificationAttempt.STATUS_CHOICES,
139+
'status_list': VerificationAttempt.STATUS,
133140
},
134141
)
135142
raise VerificationAttemptInvalidStatus
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Generated by Django 4.2.15 on 2024-09-26 20:08
2+
3+
from django.db import migrations, models
4+
import django.utils.timezone
5+
import lms.djangoapps.verify_student.statuses
6+
import model_utils.fields
7+
8+
9+
class Migration(migrations.Migration):
10+
11+
dependencies = [
12+
('verify_student', '0015_verificationattempt'),
13+
]
14+
15+
operations = [
16+
migrations.RemoveField(
17+
model_name='verificationattempt',
18+
name='created',
19+
),
20+
migrations.RemoveField(
21+
model_name='verificationattempt',
22+
name='modified',
23+
),
24+
migrations.AddField(
25+
model_name='verificationattempt',
26+
name='created_at',
27+
field=models.DateTimeField(auto_now_add=True, db_index=True, default=django.utils.timezone.now),
28+
preserve_default=False,
29+
),
30+
migrations.AddField(
31+
model_name='verificationattempt',
32+
name='hide_status_from_user',
33+
field=models.BooleanField(default=False, null=True),
34+
),
35+
migrations.AddField(
36+
model_name='verificationattempt',
37+
name='status_changed',
38+
field=model_utils.fields.MonitorField(default=django.utils.timezone.now, monitor='status', verbose_name='status changed'),
39+
),
40+
migrations.AddField(
41+
model_name='verificationattempt',
42+
name='updated_at',
43+
field=models.DateTimeField(auto_now=True, db_index=True),
44+
),
45+
migrations.AlterField(
46+
model_name='verificationattempt',
47+
name='status',
48+
field=model_utils.fields.StatusField(choices=[(lms.djangoapps.verify_student.statuses.VerificationAttemptStatus['CREATED'], lms.djangoapps.verify_student.statuses.VerificationAttemptStatus['CREATED']), (lms.djangoapps.verify_student.statuses.VerificationAttemptStatus['PENDING'], lms.djangoapps.verify_student.statuses.VerificationAttemptStatus['PENDING']), (lms.djangoapps.verify_student.statuses.VerificationAttemptStatus['APPROVED'], lms.djangoapps.verify_student.statuses.VerificationAttemptStatus['APPROVED']), (lms.djangoapps.verify_student.statuses.VerificationAttemptStatus['DENIED'], lms.djangoapps.verify_student.statuses.VerificationAttemptStatus['DENIED'])], default=lms.djangoapps.verify_student.statuses.VerificationAttemptStatus['CREATED'], max_length=100, no_check_for_status=True, verbose_name='status'),
49+
),
50+
]

lms/djangoapps/verify_student/models.py

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
import logging
1616
import os.path
1717
import uuid
18+
1819
from datetime import timedelta
1920
from email.utils import formatdate
2021

22+
2123
import requests
2224
from config_models.models import ConfigurationModel
2325
from django.conf import settings
@@ -1214,7 +1216,7 @@ def __str__(self):
12141216
return str(self.arguments)
12151217

12161218

1217-
class VerificationAttempt(TimeStampedModel):
1219+
class VerificationAttempt(StatusModel):
12181220
"""
12191221
The model represents impelementation-agnostic information about identity verification (IDV) attempts.
12201222
@@ -1224,23 +1226,29 @@ class VerificationAttempt(TimeStampedModel):
12241226
user = models.ForeignKey(User, db_index=True, on_delete=models.CASCADE)
12251227
name = models.CharField(blank=True, max_length=255)
12261228

1227-
STATUS_CHOICES = [
1229+
STATUS = Choices(
12281230
VerificationAttemptStatus.CREATED,
12291231
VerificationAttemptStatus.PENDING,
12301232
VerificationAttemptStatus.APPROVED,
12311233
VerificationAttemptStatus.DENIED,
1232-
]
1233-
status = models.CharField(max_length=64, choices=[(status, status) for status in STATUS_CHOICES])
1234+
)
12341235

12351236
expiration_datetime = models.DateTimeField(
12361237
null=True,
12371238
blank=True,
12381239
)
12391240

1240-
@property
1241-
def updated_at(self):
1242-
"""Backwards compatibility with existing IDVerification models"""
1243-
return self.modified
1241+
hide_status_from_user = models.BooleanField(
1242+
default=False,
1243+
null=True,
1244+
)
1245+
1246+
created_at = models.DateTimeField(auto_now_add=True, db_index=True)
1247+
updated_at = models.DateTimeField(auto_now=True, db_index=True)
1248+
1249+
def should_display_status_to_user(self):
1250+
"""When called, returns true or false based on the type of VerificationAttempt"""
1251+
return not self.hide_status_from_user
12441252

12451253
@classmethod
12461254
def retire_user(cls, user_id):

lms/djangoapps/verify_student/services.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def verifications_for_user(cls, user):
7676
Return a list of all verifications associated with the given user.
7777
"""
7878
verifications = []
79-
for verification in chain(VerificationAttempt.objects.filter(user=user).order_by('-created'),
79+
for verification in chain(VerificationAttempt.objects.filter(user=user).order_by('-created_at'),
8080
SoftwareSecurePhotoVerification.objects.filter(user=user).order_by('-created_at'),
8181
SSOVerification.objects.filter(user=user).order_by('-created_at'),
8282
ManualVerification.objects.filter(user=user).order_by('-created_at')):
@@ -97,7 +97,7 @@ def get_verified_user_ids(cls, users):
9797
VerificationAttempt.objects.filter(**{
9898
'user__in': users,
9999
'status': 'approved',
100-
'created__gt': now() - timedelta(days=settings.VERIFY_STUDENT["DAYS_GOOD_FOR"])
100+
'created_at__gt': now() - timedelta(days=settings.VERIFY_STUDENT["DAYS_GOOD_FOR"])
101101
}).values_list('user_id', flat=True),
102102
SoftwareSecurePhotoVerification.objects.filter(**filter_kwargs).values_list('user_id', flat=True),
103103
SSOVerification.objects.filter(**filter_kwargs).values_list('user_id', flat=True),

0 commit comments

Comments
 (0)