From 5bf0e1e134c9248e3e3a01b4eb236baaf2463923 Mon Sep 17 00:00:00 2001 From: Andy Shultz Date: Mon, 19 Jul 2021 13:02:37 -0400 Subject: [PATCH] fix: remove deprecated ip fields These IP fields are PII which blocks us from using a standard history table which would copy them. They're not currently used and there is no data in the DB more recent than 2016. This removes them from code, the next release will drop them from the DB. MST-872 --- CHANGELOG.rst | 4 ++++ edx_proctoring/__init__.py | 2 +- edx_proctoring/admin.py | 2 -- edx_proctoring/api.py | 2 -- edx_proctoring/models.py | 18 ++++-------------- edx_proctoring/serializers.py | 5 ++--- .../spec/proctored_exam_attempt_spec.js | 10 ---------- edx_proctoring/tests/test_api.py | 7 ------- edx_proctoring/tests/test_views.py | 4 ---- edx_proctoring/views.py | 2 -- package.json | 2 +- 11 files changed, 12 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 71df2fbc0e2..da653c4023b 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -14,6 +14,10 @@ Change Log Unreleased ~~~~~~~~~~ +[3.20.1] - 2021-07-20 +~~~~~~~~~~~~~~~~~~~~~ +* Removed use of IP fields in proctored exam attempt. + [3.20.0] - 2021-07-19 ~~~~~~~~~~~~~~~~~~~~~ * Added Django 3.0, 3.1 & 3.2 Support diff --git a/edx_proctoring/__init__.py b/edx_proctoring/__init__.py index 9afe424ede7..8de2843fd7d 100644 --- a/edx_proctoring/__init__.py +++ b/edx_proctoring/__init__.py @@ -3,6 +3,6 @@ """ # Be sure to update the version number in edx_proctoring/package.json -__version__ = '3.20.0' +__version__ = '3.20.1' default_app_config = 'edx_proctoring.apps.EdxProctoringConfig' # pylint: disable=invalid-name diff --git a/edx_proctoring/admin.py b/edx_proctoring/admin.py index ddf9d8405f7..e366ed4d575 100644 --- a/edx_proctoring/admin.py +++ b/edx_proctoring/admin.py @@ -428,8 +428,6 @@ class ProctoredExamStudentAttemptAdmin(admin.ModelAdmin): 'proctored_exam', 'started_at', 'completed_at', - 'last_poll_timestamp', - 'last_poll_ipaddr', 'attempt_code', 'external_id', 'allowed_time_limit_mins', diff --git a/edx_proctoring/api.py b/edx_proctoring/api.py index 2693de0736c..25131aee4d2 100644 --- a/edx_proctoring/api.py +++ b/edx_proctoring/api.py @@ -850,8 +850,6 @@ def update_exam_attempt(attempt_id, **kwargs): # only allow a limit set of fields to update # namely because status transitions can trigger workflow if key not in [ - 'last_poll_timestamp', - 'last_poll_ipaddr', 'is_status_acknowledged', 'time_remaining_seconds', ]: diff --git a/edx_proctoring/models.py b/edx_proctoring/models.py index c12df8b43a3..3f83660ddc4 100644 --- a/edx_proctoring/models.py +++ b/edx_proctoring/models.py @@ -364,8 +364,8 @@ class ProctoredExamStudentAttempt(TimeStampedModel): Information about the Student Attempt on a Proctored Exam. - .. pii: new attempts log the student's name and IP - .. pii_types: name, ip + .. pii: new attempts log the student's name + .. pii_types: name .. pii_retirement: local_api """ objects = ProctoredExamStudentAttemptManager() @@ -380,11 +380,6 @@ class ProctoredExamStudentAttempt(TimeStampedModel): # completed_at means when the attempt was 'submitted' completed_at = models.DateTimeField(null=True) - # These two fields have been deprecated. - # They were used in client polling that no longer exists. - last_poll_timestamp = models.DateTimeField(null=True) - last_poll_ipaddr = models.CharField(max_length=32, null=True) - # this will be a unique string ID that the user # will have to use when starting the proctored exam attempt_code = models.CharField(max_length=255, null=True, db_index=True) @@ -466,8 +461,8 @@ class ProctoredExamStudentAttemptHistory(TimeStampedModel): This should be the same schema as ProctoredExamStudentAttempt but will record (for audit history) all entries that have been updated. - .. pii: new attempts log the student's name and IP - .. pii_types: name, ip + .. pii: new attempts log the student's name + .. pii_types: name .. pii_retirement: local_api """ @@ -511,11 +506,6 @@ class ProctoredExamStudentAttemptHistory(TimeStampedModel): # this ID might point to a record that is in the History table review_policy_id = models.IntegerField(null=True) - # These two fields have been deprecated. - # They were used in client polling that no longer exists. - last_poll_timestamp = models.DateTimeField(null=True) - last_poll_ipaddr = models.CharField(max_length=32, null=True) - # Marks whether the attempt at this current state is able to be resumed by user # Only those attempts which had an error state before, but # has not yet marked submitted is resumable. diff --git a/edx_proctoring/serializers.py b/edx_proctoring/serializers.py index 9e12217723f..322f33eaf73 100644 --- a/edx_proctoring/serializers.py +++ b/edx_proctoring/serializers.py @@ -84,7 +84,6 @@ class ProctoredExamStudentAttemptSerializer(serializers.ModelSerializer): # of returning raw `datetime` objects instead of unicode. started_at = DateTimeField(format=None) completed_at = DateTimeField(format=None) - last_poll_timestamp = DateTimeField(format=None) class Meta: """ @@ -95,8 +94,8 @@ class Meta: fields = ( "id", "created", "modified", "user", "started_at", "completed_at", "external_id", "status", "proctored_exam", "allowed_time_limit_mins", - "attempt_code", "is_sample_attempt", "taking_as_proctored", "last_poll_timestamp", - "last_poll_ipaddr", "review_policy_id", "student_name", "is_status_acknowledged", + "attempt_code", "is_sample_attempt", "taking_as_proctored", + "review_policy_id", "student_name", "is_status_acknowledged", "time_remaining_seconds", "is_resumable" ) diff --git a/edx_proctoring/static/proctoring/spec/proctored_exam_attempt_spec.js b/edx_proctoring/static/proctoring/spec/proctored_exam_attempt_spec.js index 9d360eefc2f..3d3ddf93e19 100644 --- a/edx_proctoring/static/proctoring/spec/proctored_exam_attempt_spec.js +++ b/edx_proctoring/static/proctoring/spec/proctored_exam_attempt_spec.js @@ -33,8 +33,6 @@ describe('ProctoredExamAttemptView', function() { external_id: '40eceb15-bcc3-4791-b43f-4e843afb7ae8', id: 43, is_sample_attempt: false, - last_poll_ipaddr: null, - last_poll_timestamp: null, modified: '2015-08-10T09:15:45Z', started_at: '2015-08-10T09:15:45Z', status: status, @@ -64,8 +62,6 @@ describe('ProctoredExamAttemptView', function() { external_id: '40eceb15-bcc3-4791-b43f-4e843afb7ae8', id: 43, is_sample_attempt: false, - last_poll_ipaddr: null, - last_poll_timestamp: null, modified: '2015-08-10T09:15:45Z', started_at: '2015-08-10T09:15:45Z', status: status, @@ -114,8 +110,6 @@ describe('ProctoredExamAttemptView', function() { external_id: '40eceb15-bcc3-4791-b43f-4e843afb7ae8', id: 43, is_sample_attempt: false, - last_poll_ipaddr: null, - last_poll_timestamp: null, modified: '2015-08-10T09:15:45Z', started_at: '2015-08-10T09:15:45Z', status: status, @@ -146,8 +140,6 @@ describe('ProctoredExamAttemptView', function() { external_id: '40eceb15-bcc3-4791-b43f-4e843afb7ae8', id: 43, is_sample_attempt: false, - last_poll_ipaddr: null, - last_poll_timestamp: null, modified: '2015-08-10T09:15:45Z', started_at: '2015-08-10T09:15:45Z', status: status, @@ -178,8 +170,6 @@ describe('ProctoredExamAttemptView', function() { external_id: '40eceb15-bcc3-4791-b43f-4e843afb7ae9', id: 44, is_sample_attempt: false, - last_poll_ipaddr: null, - last_poll_timestamp: null, modified: '2015-08-10T09:15:45Z', started_at: '2015-08-10T09:15:45Z', status: 'resumed', diff --git a/edx_proctoring/tests/test_api.py b/edx_proctoring/tests/test_api.py index f4604f05c3e..9fc84620051 100644 --- a/edx_proctoring/tests/test_api.py +++ b/edx_proctoring/tests/test_api.py @@ -2353,24 +2353,17 @@ def test_update_exam_attempt(self): with self.assertRaises(ProctoredExamPermissionDenied): update_exam_attempt( exam_attempt.id, - last_poll_timestamp=datetime.utcnow(), - last_poll_ipaddr='1.1.1.1', time_remaining_seconds=600, status='foo' ) - now = datetime.now(pytz.UTC) update_exam_attempt( exam_attempt.id, - last_poll_timestamp=now, - last_poll_ipaddr='1.1.1.1', time_remaining_seconds=600, ) attempt = get_exam_attempt_by_id(exam_attempt.id) - self.assertEqual(attempt['last_poll_timestamp'], now) - self.assertEqual(attempt['last_poll_ipaddr'], '1.1.1.1') self.assertEqual(attempt['time_remaining_seconds'], 600) @ddt.data( diff --git a/edx_proctoring/tests/test_views.py b/edx_proctoring/tests/test_views.py index 457c7567af5..2f39ce5c6ba 100644 --- a/edx_proctoring/tests/test_views.py +++ b/edx_proctoring/tests/test_views.py @@ -5776,7 +5776,6 @@ def test_retire_user_exam_attempt(self): proctored_exam=proctored_exam, user=self.user_to_retire, student_name='me', - last_poll_ipaddr='127.0.0.1' ) # Run the retirement command @@ -5786,7 +5785,6 @@ def test_retire_user_exam_attempt(self): retired_attempt = ProctoredExamStudentAttempt.objects.filter(user_id=self.user_to_retire.id).first() assert retired_attempt.student_name == '' - assert retired_attempt.last_poll_ipaddr is None def test_retire_user_exam_attempt_history(self): """ Retiring a user should obfuscate PII for exam attempt history and return a 204 status """ @@ -5796,7 +5794,6 @@ def test_retire_user_exam_attempt_history(self): proctored_exam=proctored_exam, user=self.user_to_retire, student_name='me', - last_poll_ipaddr='127.0.0.1' ) # Run the retirement command @@ -5806,7 +5803,6 @@ def test_retire_user_exam_attempt_history(self): retired_attempt_history = ProctoredExamStudentAttemptHistory \ .objects.filter(user_id=self.user_to_retire.id).first() assert retired_attempt_history.student_name == '' - assert retired_attempt_history.last_poll_ipaddr is None def test_retire_user_allowances(self): """ Retiring a user should delete their allowances and return a 204 """ diff --git a/edx_proctoring/views.py b/edx_proctoring/views.py index bd1086deafb..28d4db7cc3b 100644 --- a/edx_proctoring/views.py +++ b/edx_proctoring/views.py @@ -2031,14 +2031,12 @@ def _retire_exam_attempts_user_info(self, user_id): if attempts: for attempt in attempts: attempt.student_name = '' - attempt.last_poll_ipaddr = None attempt.save() attempts_history = ProctoredExamStudentAttemptHistory.objects.filter(user_id=user_id) if attempts_history: for attempt_history in attempts_history: attempt_history.student_name = '' - attempt_history.last_poll_ipaddr = None attempt_history.save() def _retire_user_allowances(self, user_id): diff --git a/package.json b/package.json index 751cb656892..2b389456cb0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@edx/edx-proctoring", "//": "Note that the version format is slightly different than that of the Python version when using prereleases.", - "version": "3.20.0", + "version": "3.20.1", "main": "edx_proctoring/static/index.js", "scripts": { "test": "gulp test"